Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit2d7f136

Browse files
committed
Improve plpgsql parsing to report "foo is not a known variable", rather than a
generic syntax error, when seeing "foo := something" and foo isn't recognized.This buys back most of the helpfulness discarded in my previous patch by notthrowing errors when a qualified name appears to match a row variable but thelast component doesn't match any field of the row. It covers other caseswhere our error messages left something to be desired, too.
1 parent01f7d29 commit2d7f136

File tree

1 file changed

+68
-33
lines changed

1 file changed

+68
-33
lines changed

‎src/pl/plpgsql/src/gram.y

Lines changed: 68 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.138 2010/01/10 17:15:18 tgl Exp $
11+
* $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.139 2010/01/10 17:56:50 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -56,7 +56,9 @@ union YYSTYPE;/* need forward reference for tok_is_keyword */
5656

5757
staticbooltok_is_keyword(int token,union YYSTYPE *lval,
5858
int kw_token,constchar *kw_str);
59-
staticvoidtoken_is_not_variable(int tok);
59+
staticvoidword_is_not_variable(PLword *word,int location);
60+
staticvoidcword_is_not_variable(PLcword *cword,int location);
61+
staticvoidcurrent_token_is_not_variable(int tok);
6062
staticPLpgSQL_expr*read_sql_construct(int until,
6163
int until2,
6264
int until3,
@@ -851,12 +853,12 @@ getdiag_target: T_DATUM
851853
| T_WORD
852854
{
853855
/* just to give a better message than "syntax error"*/
854-
token_is_not_variable(T_WORD);
856+
word_is_not_variable(&($1), @1);
855857
}
856858
| T_CWORD
857859
{
858860
/* just to give a better message than "syntax error"*/
859-
token_is_not_variable(T_CWORD);
861+
cword_is_not_variable(&($1), @1);
860862
}
861863
;
862864

@@ -1371,19 +1373,12 @@ for_variable: T_DATUM
13711373
tok =yylex();
13721374
plpgsql_push_back_token(tok);
13731375
if (tok ==',')
1374-
{
1375-
/* can't use token_is_not_variable here*/
1376-
ereport(ERROR,
1377-
(errcode(ERRCODE_SYNTAX_ERROR),
1378-
errmsg("\"%s\" is not a known variable",
1379-
$1.ident),
1380-
parser_errposition(@1)));
1381-
}
1376+
word_is_not_variable(&($1), @1);
13821377
}
13831378
| T_CWORD
13841379
{
13851380
/* just to give a better message than "syntax error"*/
1386-
token_is_not_variable(T_CWORD);
1381+
cword_is_not_variable(&($1), @1);
13871382
}
13881383
;
13891384

@@ -1587,15 +1582,38 @@ loop_body: proc_sect K_END K_LOOP opt_label ';'
15871582

15881583
/*
15891584
* T_WORD+T_CWORD match any initial identifier that is not a known plpgsql
1590-
* variable. The composite case is probably a syntax error, but we'll let
1591-
* the core parser decide that.
1585+
* variable. (The composite case is probably a syntax error, but we'll let
1586+
* the core parser decide that.) Normally, we should assume that such a
1587+
* word is a SQL statement keyword that isn't also a plpgsql keyword.
1588+
* However, if the next token is assignment or '[', it can't be a valid
1589+
* SQL statement, and what we're probably looking at is an intended variable
1590+
* assignment. Give an appropriate complaint for that, instead of letting
1591+
* the core parser throw an unhelpful "syntax error".
15921592
*/
15931593
stmt_execsql: K_INSERT
1594-
{ $$ =make_execsql_stmt(K_INSERT, @1); }
1594+
{
1595+
$$ =make_execsql_stmt(K_INSERT, @1);
1596+
}
15951597
| T_WORD
1596-
{ $$ =make_execsql_stmt(T_WORD, @1); }
1598+
{
1599+
inttok;
1600+
1601+
tok =yylex();
1602+
plpgsql_push_back_token(tok);
1603+
if (tok =='=' || tok == COLON_EQUALS || tok =='[')
1604+
word_is_not_variable(&($1), @1);
1605+
$$ =make_execsql_stmt(T_WORD, @1);
1606+
}
15971607
| T_CWORD
1598-
{ $$ =make_execsql_stmt(T_CWORD, @1); }
1608+
{
1609+
inttok;
1610+
1611+
tok =yylex();
1612+
plpgsql_push_back_token(tok);
1613+
if (tok =='=' || tok == COLON_EQUALS || tok =='[')
1614+
cword_is_not_variable(&($1), @1);
1615+
$$ =make_execsql_stmt(T_CWORD, @1);
1616+
}
15991617
;
16001618

16011619
stmt_dynexecute : K_EXECUTE
@@ -1793,12 +1811,12 @@ cursor_variable: T_DATUM
17931811
| T_WORD
17941812
{
17951813
/* just to give a better message than "syntax error"*/
1796-
token_is_not_variable(T_WORD);
1814+
word_is_not_variable(&($1), @1);
17971815
}
17981816
| T_CWORD
17991817
{
18001818
/* just to give a better message than "syntax error"*/
1801-
token_is_not_variable(T_CWORD);
1819+
cword_is_not_variable(&($1), @1);
18021820
}
18031821
;
18041822

@@ -2045,26 +2063,43 @@ tok_is_keyword(int token, union YYSTYPE *lval,
20452063
return false;/* not the keyword*/
20462064
}
20472065

2066+
/*
2067+
* Convenience routine to complain when we expected T_DATUM and got T_WORD,
2068+
* ie, unrecognized variable.
2069+
*/
2070+
static void
2071+
word_is_not_variable(PLword *word, int location)
2072+
{
2073+
ereport(ERROR,
2074+
(errcode(ERRCODE_SYNTAX_ERROR),
2075+
errmsg("\"%s\" is not a known variable",
2076+
word->ident),
2077+
parser_errposition(location)));
2078+
}
2079+
2080+
/* Same, for a CWORD*/
2081+
static void
2082+
cword_is_not_variable(PLcword *cword, int location)
2083+
{
2084+
ereport(ERROR,
2085+
(errcode(ERRCODE_SYNTAX_ERROR),
2086+
errmsg("\"%s\" is not a known variable",
2087+
NameListToString(cword->idents)),
2088+
parser_errposition(location)));
2089+
}
2090+
20482091
/*
20492092
* Convenience routine to complain when we expected T_DATUM and got
20502093
* something else. "tok" must be the current token, since we also
20512094
* look at yylval and yylloc.
20522095
*/
20532096
static void
2054-
token_is_not_variable(int tok)
2097+
current_token_is_not_variable(int tok)
20552098
{
20562099
if (tok == T_WORD)
2057-
ereport(ERROR,
2058-
(errcode(ERRCODE_SYNTAX_ERROR),
2059-
errmsg("\"%s\" is not a known variable",
2060-
yylval.word.ident),
2061-
parser_errposition(yylloc)));
2100+
word_is_not_variable(&(yylval.word), yylloc);
20622101
else if (tok == T_CWORD)
2063-
ereport(ERROR,
2064-
(errcode(ERRCODE_SYNTAX_ERROR),
2065-
errmsg("\"%s\" is not a known variable",
2066-
NameListToString(yylval.cword.idents)),
2067-
parser_errposition(yylloc)));
2102+
cword_is_not_variable(&(yylval.cword), yylloc);
20682103
else
20692104
yyerror("syntax error");
20702105
}
@@ -2848,7 +2883,7 @@ read_into_target(PLpgSQL_rec **rec, PLpgSQL_row **row, bool *strict)
28482883

28492884
default:
28502885
/* just to give a better message than "syntax error"*/
2851-
token_is_not_variable(tok);
2886+
current_token_is_not_variable(tok);
28522887
}
28532888
}
28542889

@@ -2901,7 +2936,7 @@ read_into_scalar_list(char *initial_name,
29012936

29022937
default:
29032938
/* just to give a better message than "syntax error"*/
2904-
token_is_not_variable(tok);
2939+
current_token_is_not_variable(tok);
29052940
}
29062941
}
29072942

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp