mirror of
https://github.com/postgres/postgres.git
synced 2025-05-01 01:04:50 +03:00
Make plpgsql's unreserved keywords more unreserved.
There were assorted places where unreserved keywords were not treated the same as T_WORD (that is, a random unrecognized identifier). Fix them. It might not always be possible to allow this, but it is in all these places, so I don't see any downside. Per gripe from Jim Wilson. Arguably this is a bug fix, but given the lack of other complaints and the ease of working around it (just quote the word), I won't risk back-patching.
This commit is contained in:
parent
fc68ac86b1
commit
bac95fd474
@ -642,6 +642,21 @@ decl_aliasitem : T_WORD
|
||||
parser_errposition(@1)));
|
||||
$$ = nsi;
|
||||
}
|
||||
| unreserved_keyword
|
||||
{
|
||||
PLpgSQL_nsitem *nsi;
|
||||
|
||||
nsi = plpgsql_ns_lookup(plpgsql_ns_top(), false,
|
||||
$1, NULL, NULL,
|
||||
NULL);
|
||||
if (nsi == NULL)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||
errmsg("variable \"%s\" does not exist",
|
||||
$1),
|
||||
parser_errposition(@1)));
|
||||
$$ = nsi;
|
||||
}
|
||||
| T_CWORD
|
||||
{
|
||||
PLpgSQL_nsitem *nsi;
|
||||
@ -722,6 +737,11 @@ decl_collate :
|
||||
$$ = get_collation_oid(list_make1(makeString($2.ident)),
|
||||
false);
|
||||
}
|
||||
| K_COLLATE unreserved_keyword
|
||||
{
|
||||
$$ = get_collation_oid(list_make1(makeString(pstrdup($2))),
|
||||
false);
|
||||
}
|
||||
| K_COLLATE T_CWORD
|
||||
{
|
||||
$$ = get_collation_oid($2.idents, false);
|
||||
@ -1720,9 +1740,12 @@ stmt_raise : K_RAISE
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tok != T_WORD)
|
||||
yyerror("syntax error");
|
||||
if (tok == T_WORD)
|
||||
new->condname = yylval.word.ident;
|
||||
else if (plpgsql_token_is_unreserved_keyword(tok))
|
||||
new->condname = pstrdup(yylval.keyword);
|
||||
else
|
||||
yyerror("syntax error");
|
||||
plpgsql_recognize_err_condition(new->condname,
|
||||
false);
|
||||
}
|
||||
@ -2185,12 +2208,16 @@ opt_exitcond : ';'
|
||||
;
|
||||
|
||||
/*
|
||||
* need both options because scanner will have tried to resolve as variable
|
||||
* need to allow DATUM because scanner will have tried to resolve as variable
|
||||
*/
|
||||
any_identifier : T_WORD
|
||||
{
|
||||
$$ = $1.ident;
|
||||
}
|
||||
| unreserved_keyword
|
||||
{
|
||||
$$ = pstrdup($1);
|
||||
}
|
||||
| T_DATUM
|
||||
{
|
||||
if ($1.ident == NULL) /* composite name not OK */
|
||||
@ -2513,6 +2540,30 @@ read_datatype(int tok)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (plpgsql_token_is_unreserved_keyword(tok))
|
||||
{
|
||||
char *dtname = pstrdup(yylval.keyword);
|
||||
|
||||
tok = yylex();
|
||||
if (tok == '%')
|
||||
{
|
||||
tok = yylex();
|
||||
if (tok_is_keyword(tok, &yylval,
|
||||
K_TYPE, "type"))
|
||||
{
|
||||
result = plpgsql_parse_wordtype(dtname);
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
else if (tok_is_keyword(tok, &yylval,
|
||||
K_ROWTYPE, "rowtype"))
|
||||
{
|
||||
result = plpgsql_parse_wordrowtype(dtname);
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (tok == T_CWORD)
|
||||
{
|
||||
List *dtnames = yylval.cword.idents;
|
||||
|
@ -410,6 +410,25 @@ plpgsql_push_back_token(int token)
|
||||
push_back_token(token, &auxdata);
|
||||
}
|
||||
|
||||
/*
|
||||
* Tell whether a token is an unreserved keyword.
|
||||
*
|
||||
* (If it is, its lowercased form was returned as the token value, so we
|
||||
* do not need to offer that data here.)
|
||||
*/
|
||||
bool
|
||||
plpgsql_token_is_unreserved_keyword(int token)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_unreserved_keywords; i++)
|
||||
{
|
||||
if (unreserved_keywords[i].value == token)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Append the function text starting at startlocation and extending to
|
||||
* (not including) endlocation onto the existing contents of "buf".
|
||||
|
@ -973,6 +973,7 @@ extern void plpgsql_dumptree(PLpgSQL_function *func);
|
||||
extern int plpgsql_base_yylex(void);
|
||||
extern int plpgsql_yylex(void);
|
||||
extern void plpgsql_push_back_token(int token);
|
||||
extern bool plpgsql_token_is_unreserved_keyword(int token);
|
||||
extern void plpgsql_append_source_text(StringInfo buf,
|
||||
int startlocation, int endlocation);
|
||||
extern void plpgsql_peek2(int *tok1_p, int *tok2_p, int *tok1_loc,
|
||||
|
Loading…
x
Reference in New Issue
Block a user