99 *
1010 *
1111 * IDENTIFICATION
12- * $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.123 2009/04/19 21:50:09 tgl Exp $
12+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.124 2009/05/01 23:57:34 tgl Exp $
1313 *
1414 *-------------------------------------------------------------------------
1515 */
@@ -144,7 +144,7 @@ static List *read_raise_options(void);
144144%type <forvariable> for_variable
145145%type <stmt> for_control
146146
147- %type <str> opt_lblname opt_block_label opt_label
147+ %type <str> any_identifier any_name opt_block_label opt_label
148148%type <str> execsql_start
149149
150150%type <list> proc_sect proc_stmts stmt_else
@@ -331,7 +331,7 @@ decl_stmts : decl_stmts decl_stmt
331331 { $$ = $1 ; }
332332 ;
333333
334- decl_stmt : ' <' ' <' opt_lblname ' >' ' >'
334+ decl_stmt : ' <' ' <' any_name ' >' ' >'
335335 { $$ = $3 ; }
336336 | K_DECLARE
337337 { $$ = NULL ; }
@@ -512,12 +512,12 @@ decl_cursor_arg : decl_varname decl_datatype
512512decl_is_for : K_IS | /* Oracle */
513513 K_FOR ; /* ANSI */
514514
515- decl_aliasitem : T_WORD
515+ decl_aliasitem : any_identifier
516516 {
517517 char *name;
518518 PLpgSQL_nsitem *nsi;
519519
520- plpgsql_convert_ident (yytext , &name, 1 );
520+ plpgsql_convert_ident ($ 1 , &name, 1 );
521521 if (name[0 ] != ' $' )
522522 yyerror (" only positional parameters can be aliased" );
523523
@@ -549,8 +549,27 @@ decl_varname : T_WORD
549549 $$ .name = name;
550550 $$ .lineno = plpgsql_scanner_lineno();
551551 }
552+ | T_SCALAR
553+ {
554+ /*
555+ * Since the scanner is only searching the topmost
556+ * namestack entry, getting T_SCALAR etc can only
557+ * happen if the name is already declared in this
558+ * block.
559+ */
560+ yyerror (" duplicate declaration" );
561+ }
562+ | T_ROW
563+ {
564+ yyerror (" duplicate declaration" );
565+ }
566+ | T_RECORD
567+ {
568+ yyerror (" duplicate declaration" );
569+ }
552570 ;
553571
572+ /* XXX this is broken because it doesn't allow for T_SCALAR,T_ROW,T_RECORD */
554573decl_renname : T_WORD
555574 {
556575 char *name;
@@ -1752,45 +1771,39 @@ proc_conditions : proc_conditions K_OR proc_condition
17521771 }
17531772 ;
17541773
1755- proc_condition : opt_lblname
1774+ proc_condition : any_name
17561775 {
1757- $$ = plpgsql_parse_err_condition($1 );
1758- }
1759- | T_SCALAR
1760- {
1761- /*
1762- * Because we know the special sqlstate variable
1763- * is at the top of the namestack (see the
1764- * exception_sect production), the SQLSTATE
1765- * keyword will always lex as T_SCALAR. This
1766- * might not be true in other parsing contexts!
1767- */
1768- PLpgSQL_condition *new ;
1769- char *sqlstatestr;
1770-
1771- if (pg_strcasecmp(yytext, " sqlstate" ) != 0 )
1772- yyerror (" syntax error" );
1776+ if (strcmp($1 , " sqlstate" ) != 0 )
1777+ {
1778+ $$ = plpgsql_parse_err_condition($1 );
1779+ }
1780+ else
1781+ {
1782+ PLpgSQL_condition *new ;
1783+ char *sqlstatestr;
17731784
1774- /* next token should be a string literal */
1775- if (yylex () != T_STRING)
1776- yyerror (" syntax error" );
1777- sqlstatestr = parse_string_token(yytext);
1778-
1779- if (strlen(sqlstatestr) != 5 )
1780- yyerror (" invalid SQLSTATE code" );
1781- if (strspn(sqlstatestr, " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" ) != 5 )
1782- yyerror (" invalid SQLSTATE code" );
1783-
1784- new = palloc(sizeof (PLpgSQL_condition));
1785- new ->sqlerrstate = MAKE_SQLSTATE(sqlstatestr[0 ],
1786- sqlstatestr[1 ],
1787- sqlstatestr[2 ],
1788- sqlstatestr[3 ],
1789- sqlstatestr[4 ]);
1790- new ->condname = sqlstatestr;
1791- new ->next = NULL ;
1792-
1793- $$ = new ;
1785+ /* next token should be a string literal */
1786+ if (yylex () != T_STRING)
1787+ yyerror (" syntax error" );
1788+ sqlstatestr = parse_string_token(yytext);
1789+
1790+ if (strlen(sqlstatestr) != 5 )
1791+ yyerror (" invalid SQLSTATE code" );
1792+ if (strspn(sqlstatestr, " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" ) != 5 )
1793+ yyerror (" invalid SQLSTATE code" );
1794+
1795+ new = palloc(sizeof (PLpgSQL_condition));
1796+ new ->sqlerrstate =
1797+ MAKE_SQLSTATE (sqlstatestr[0 ],
1798+ sqlstatestr[1 ],
1799+ sqlstatestr[2 ],
1800+ sqlstatestr[3 ],
1801+ sqlstatestr[4 ]);
1802+ new ->condname = sqlstatestr;
1803+ new ->next = NULL ;
1804+
1805+ $$ = new ;
1806+ }
17941807 }
17951808 ;
17961809
@@ -1815,49 +1828,55 @@ opt_block_label :
18151828 plpgsql_ns_push (NULL );
18161829 $$ = NULL ;
18171830 }
1818- | ' <' ' <' opt_lblname ' >' ' >'
1831+ | ' <' ' <' any_name ' >' ' >'
18191832 {
18201833 plpgsql_ns_push ($3 );
18211834 $$ = $3 ;
18221835 }
18231836 ;
18241837
1825- /*
1826- * need all the options because scanner will have tried to resolve as variable
1827- */
18281838opt_label :
18291839 {
18301840 $$ = NULL ;
18311841 }
1832- | T_WORD
1842+ | any_identifier
18331843 {
1834- $$ = check_label(yytext);
1844+ $$ = check_label($1 );
1845+ }
1846+ ;
1847+
1848+ opt_exitcond : ' ;'
1849+ { $$ = NULL ; }
1850+ | K_WHEN expr_until_semi
1851+ { $$ = $2 ; }
1852+ ;
1853+
1854+ /*
1855+ * need all the options because scanner will have tried to resolve as variable
1856+ */
1857+ any_identifier : T_WORD
1858+ {
1859+ $$ = yytext;
18351860 }
18361861 | T_SCALAR
18371862 {
1838- $$ = check_label( yytext) ;
1863+ $$ = yytext;
18391864 }
18401865 | T_RECORD
18411866 {
1842- $$ = check_label( yytext) ;
1867+ $$ = yytext;
18431868 }
18441869 | T_ROW
18451870 {
1846- $$ = check_label( yytext) ;
1871+ $$ = yytext;
18471872 }
18481873 ;
18491874
1850- opt_exitcond : ' ;'
1851- { $$ = NULL ; }
1852- | K_WHEN expr_until_semi
1853- { $$ = $2 ; }
1854- ;
1855-
1856- opt_lblname : T_WORD
1875+ any_name : any_identifier
18571876 {
18581877 char *name;
18591878
1860- plpgsql_convert_ident (yytext , &name, 1 );
1879+ plpgsql_convert_ident ($ 1 , &name, 1 );
18611880 $$ = name;
18621881 }
18631882 ;
0 commit comments