From 2c92edad48796119c83d7dbe6c33425d1924626d Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 2 Jun 2013 20:09:20 -0400 Subject: [PATCH] Allow type_func_name_keywords in some places where they weren't before. This change makes type_func_name_keywords less reserved than they were before, by allowing them for role names, language names, EXPLAIN and COPY options, and SET values for GUCs; which are all places where few if any actual keywords could appear instead, so no new ambiguities are introduced. The main driver for this change is to allow "COPY ... (FORMAT BINARY)" to work without quoting the word "binary". That is an inconsistency that has been complained of repeatedly over the years (at least by Pavel Golub, Kurt Lidl, and Simon Riggs); but we hadn't thought of any non-ugly solution until now. Back-patch to 9.0 where the COPY (FORMAT BINARY) syntax was introduced. --- src/backend/parser/gram.y | 53 ++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 73c446a907..7c8dc50088 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -450,9 +450,10 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type Iconst SignedIconst %type Sconst comment_text notify_payload -%type RoleId opt_granted_by opt_boolean_or_string ColId_or_Sconst +%type RoleId opt_granted_by opt_boolean_or_string %type var_list %type ColId ColLabel var_name type_function_name param_name +%type NonReservedWord NonReservedWord_or_Sconst %type var_value zone_value %type unreserved_keyword type_func_name_keyword @@ -1402,7 +1403,7 @@ set_rest_more: /* Generic SET syntaxes: */ n->kind = VAR_SET_DEFAULT; $$ = n; } - | ROLE ColId_or_Sconst + | ROLE NonReservedWord_or_Sconst { VariableSetStmt *n = makeNode(VariableSetStmt); n->kind = VAR_SET_VALUE; @@ -1410,7 +1411,7 @@ set_rest_more: /* Generic SET syntaxes: */ n->args = list_make1(makeStringConst($2, @2)); $$ = n; } - | SESSION AUTHORIZATION ColId_or_Sconst + | SESSION AUTHORIZATION NonReservedWord_or_Sconst { VariableSetStmt *n = makeNode(VariableSetStmt); n->kind = VAR_SET_VALUE; @@ -1473,11 +1474,11 @@ opt_boolean_or_string: | FALSE_P { $$ = "false"; } | ON { $$ = "on"; } /* - * OFF is also accepted as a boolean value, but is handled - * by the ColId rule below. The action for booleans and strings + * OFF is also accepted as a boolean value, but is handled by + * the NonReservedWord rule. The action for booleans and strings * is the same, so we don't need to distinguish them here. */ - | ColId_or_Sconst { $$ = $1; } + | NonReservedWord_or_Sconst { $$ = $1; } ; /* Timezone values can be: @@ -1546,8 +1547,8 @@ opt_encoding: | /*EMPTY*/ { $$ = NULL; } ; -ColId_or_Sconst: - ColId { $$ = $1; } +NonReservedWord_or_Sconst: + NonReservedWord { $$ = $1; } | Sconst { $$ = $1; } ; @@ -3418,7 +3419,7 @@ NumericOnly_list: NumericOnly { $$ = list_make1($1); } *****************************************************************************/ CreatePLangStmt: - CREATE opt_or_replace opt_trusted opt_procedural LANGUAGE ColId_or_Sconst + CREATE opt_or_replace opt_trusted opt_procedural LANGUAGE NonReservedWord_or_Sconst { CreatePLangStmt *n = makeNode(CreatePLangStmt); n->replace = $2; @@ -3430,7 +3431,7 @@ CreatePLangStmt: n->pltrusted = false; $$ = (Node *)n; } - | CREATE opt_or_replace opt_trusted opt_procedural LANGUAGE ColId_or_Sconst + | CREATE opt_or_replace opt_trusted opt_procedural LANGUAGE NonReservedWord_or_Sconst HANDLER handler_name opt_inline_handler opt_validator { CreatePLangStmt *n = makeNode(CreatePLangStmt); @@ -3474,7 +3475,7 @@ opt_validator: ; DropPLangStmt: - DROP opt_procedural LANGUAGE ColId_or_Sconst opt_drop_behavior + DROP opt_procedural LANGUAGE NonReservedWord_or_Sconst opt_drop_behavior { DropStmt *n = makeNode(DropStmt); n->removeType = OBJECT_LANGUAGE; @@ -3485,7 +3486,7 @@ DropPLangStmt: n->concurrent = false; $$ = (Node *)n; } - | DROP opt_procedural LANGUAGE IF_P EXISTS ColId_or_Sconst opt_drop_behavior + | DROP opt_procedural LANGUAGE IF_P EXISTS NonReservedWord_or_Sconst opt_drop_behavior { DropStmt *n = makeNode(DropStmt); n->removeType = OBJECT_LANGUAGE; @@ -3587,11 +3588,11 @@ create_extension_opt_item: { $$ = makeDefElem("schema", (Node *)makeString($2)); } - | VERSION_P ColId_or_Sconst + | VERSION_P NonReservedWord_or_Sconst { $$ = makeDefElem("new_version", (Node *)makeString($2)); } - | FROM ColId_or_Sconst + | FROM NonReservedWord_or_Sconst { $$ = makeDefElem("old_version", (Node *)makeString($2)); } @@ -3620,7 +3621,7 @@ alter_extension_opt_list: ; alter_extension_opt_item: - TO ColId_or_Sconst + TO NonReservedWord_or_Sconst { $$ = makeDefElem("new_version", (Node *)makeString($2)); } @@ -5428,8 +5429,8 @@ SecLabelStmt: } ; -opt_provider: FOR ColId_or_Sconst { $$ = $2; } - | /* empty */ { $$ = NULL; } +opt_provider: FOR NonReservedWord_or_Sconst { $$ = $2; } + | /* empty */ { $$ = NULL; } ; security_label_type: @@ -6455,7 +6456,7 @@ createfunc_opt_item: { $$ = makeDefElem("as", (Node *)$2); } - | LANGUAGE ColId_or_Sconst + | LANGUAGE NonReservedWord_or_Sconst { $$ = makeDefElem("language", (Node *)makeString($2)); } @@ -6670,7 +6671,7 @@ dostmt_opt_item: { $$ = makeDefElem("as", (Node *)makeString($1)); } - | LANGUAGE ColId_or_Sconst + | LANGUAGE NonReservedWord_or_Sconst { $$ = makeDefElem("language", (Node *)makeString($2)); } @@ -8667,9 +8668,7 @@ explain_option_elem: ; explain_option_name: - ColId { $$ = $1; } - | analyze_keyword { $$ = "analyze"; } - | VERBOSE { $$ = "verbose"; } + NonReservedWord { $$ = $1; } ; explain_option_arg: @@ -12580,7 +12579,7 @@ AexprConst: Iconst Iconst: ICONST { $$ = $1; }; Sconst: SCONST { $$ = $1; }; -RoleId: ColId { $$ = $1; }; +RoleId: NonReservedWord { $$ = $1; }; SignedIconst: Iconst { $$ = $1; } | '+' Iconst { $$ = + $2; } @@ -12612,6 +12611,14 @@ type_function_name: IDENT { $$ = $1; } | type_func_name_keyword { $$ = pstrdup($1); } ; +/* Any not-fully-reserved word --- these names can be, eg, role names. + */ +NonReservedWord: IDENT { $$ = $1; } + | unreserved_keyword { $$ = pstrdup($1); } + | col_name_keyword { $$ = pstrdup($1); } + | type_func_name_keyword { $$ = pstrdup($1); } + ; + /* Column label --- allowed labels in "AS" clauses. * This presently includes *all* Postgres keywords. */