Re: factorial function/phase out postfix operators? - Mailing list pgsql-hackers
From | Tom Lane |
---|---|
Subject | Re: factorial function/phase out postfix operators? |
Date | |
Msg-id | 28461.1589932031@sss.pgh.pa.us Whole thread Raw |
In response to | Re: factorial function/phase out postfix operators? (Tom Lane <tgl@sss.pgh.pa.us>) |
Responses |
Re: factorial function/phase out postfix operators?
Re: factorial function/phase out postfix operators? Re: factorial function/phase out postfix operators? |
List | pgsql-hackers |
I wrote: > However, we do have to have a benefit to show those people whose > queries we break. Hence my insistence on having a working AS fix > (or some other benefit) before not after. I experimented with this a bit more, and came up with the attached. It's not a working patch, just a set of grammar changes that Bison is happy with. (Getting to a working patch would require fixing the various build infrastructure that knows about the keyword classification, which seems straightforward but tedious.) As Robert theorized, it works to move a fairly-small number of unreserved keywords into a new slightly-reserved category. However, as the patch stands, only the remaining fully-unreserved keywords can be used as bare column labels. I'd hoped to be able to also use col_name keywords in that way (which'd make the set of legal bare column labels mostly the same as ColId). The col_name keywords that cause problems are, it appears, only PRECISION, CHARACTER, and CHAR_P. So in principle we could move those three into yet another keyword category and then let the remaining col_name keywords be included in BareColLabel. I kind of think that that's more complication than it's worth, though. regards, tom lane diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index a24b30f..0b034b6 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -542,13 +542,14 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type <str> Sconst comment_text notify_payload %type <str> RoleId opt_boolean_or_string %type <list> var_list -%type <str> ColId ColLabel var_name type_function_name param_name +%type <str> ColId ColLabel BareColLabel %type <str> NonReservedWord NonReservedWord_or_Sconst +%type <str> var_name type_function_name param_name %type <str> createdb_opt_name %type <node> var_value zone_value %type <rolespec> auth_ident RoleSpec opt_granted_by -%type <keyword> unreserved_keyword type_func_name_keyword +%type <keyword> unreserved_keyword non_label_keyword type_func_name_keyword %type <keyword> col_name_keyword reserved_keyword %type <node> TableConstraint TableLikeClause @@ -744,7 +745,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %nonassoc '<' '>' '=' LESS_EQUALS GREATER_EQUALS NOT_EQUALS %nonassoc BETWEEN IN_P LIKE ILIKE SIMILAR NOT_LA %nonassoc ESCAPE /* ESCAPE must be just above LIKE/ILIKE/SIMILAR */ -%left POSTFIXOP /* dummy for postfix Op rules */ /* * To support target_el without AS, we must give IDENT an explicit priority * between POSTFIXOP and Op. We can safely assign the same priority to @@ -3908,6 +3908,7 @@ PartitionSpec: PARTITION BY part_strategy '(' part_params ')' part_strategy: IDENT { $$ = $1; } | unreserved_keyword { $$ = pstrdup($1); } + | non_label_keyword { $$ = pstrdup($1); } ; part_params: part_elem { $$ = list_make1($1); } @@ -13230,8 +13231,6 @@ a_expr: c_expr { $$ = $1; } { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, $3, @2); } | qual_Op a_expr %prec Op { $$ = (Node *) makeA_Expr(AEXPR_OP, $1, NULL, $2, @1); } - | a_expr qual_Op %prec POSTFIXOP - { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, NULL, @2); } | a_expr AND a_expr { $$ = makeAndExpr($1, $3, @2); } @@ -13645,8 +13644,6 @@ b_expr: c_expr { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, $3, @2); } | qual_Op b_expr %prec Op { $$ = (Node *) makeA_Expr(AEXPR_OP, $1, NULL, $2, @1); } - | b_expr qual_Op %prec POSTFIXOP - { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, NULL, @2); } | b_expr IS DISTINCT FROM b_expr %prec IS { $$ = (Node *) makeSimpleA_Expr(AEXPR_DISTINCT, "=", $1, $5, @2); @@ -14910,7 +14907,7 @@ target_el: a_expr AS ColLabel * as an infix expression, which we accomplish by assigning * IDENT a precedence higher than POSTFIXOP. */ - | a_expr IDENT + | a_expr BareColLabel { $$ = makeNode(ResTarget); $$->name = $2; @@ -15228,6 +15225,7 @@ role_list: RoleSpec */ ColId: IDENT { $$ = $1; } | unreserved_keyword { $$ = pstrdup($1); } + | non_label_keyword { $$ = pstrdup($1); } | col_name_keyword { $$ = pstrdup($1); } ; @@ -15235,6 +15233,7 @@ ColId: IDENT { $$ = $1; } */ type_function_name: IDENT { $$ = $1; } | unreserved_keyword { $$ = pstrdup($1); } + | non_label_keyword { $$ = pstrdup($1); } | type_func_name_keyword { $$ = pstrdup($1); } ; @@ -15242,15 +15241,23 @@ type_function_name: IDENT { $$ = $1; } */ NonReservedWord: IDENT { $$ = $1; } | unreserved_keyword { $$ = pstrdup($1); } + | non_label_keyword { $$ = pstrdup($1); } | col_name_keyword { $$ = pstrdup($1); } | type_func_name_keyword { $$ = pstrdup($1); } ; +/* Bare column label --- names that can be column labels without writing "AS". + */ +BareColLabel: IDENT { $$ = $1; } + | unreserved_keyword { $$ = pstrdup($1); } + ; + /* Column label --- allowed labels in "AS" clauses. * This presently includes *all* Postgres keywords. */ ColLabel: IDENT { $$ = $1; } | unreserved_keyword { $$ = pstrdup($1); } + | non_label_keyword { $$ = pstrdup($1); } | col_name_keyword { $$ = pstrdup($1); } | type_func_name_keyword { $$ = pstrdup($1); } | reserved_keyword { $$ = pstrdup($1); } @@ -15326,7 +15333,6 @@ unreserved_keyword: | CYCLE | DATA_P | DATABASE - | DAY_P | DEALLOCATE | DECLARE | DEFAULTS @@ -15360,7 +15366,6 @@ unreserved_keyword: | EXTENSION | EXTERNAL | FAMILY - | FILTER | FIRST_P | FOLLOWING | FORCE @@ -15374,7 +15379,6 @@ unreserved_keyword: | HANDLER | HEADER_P | HOLD - | HOUR_P | IDENTITY_P | IF_P | IMMEDIATE @@ -15414,10 +15418,8 @@ unreserved_keyword: | MATERIALIZED | MAXVALUE | METHOD - | MINUTE_P | MINVALUE | MODE - | MONTH_P | MOVE | NAME_P | NAMES @@ -15443,7 +15445,6 @@ unreserved_keyword: | OPTIONS | ORDINALITY | OTHERS - | OVER | OVERRIDING | OWNED | OWNER @@ -15499,7 +15500,6 @@ unreserved_keyword: | SCHEMAS | SCROLL | SEARCH - | SECOND_P | SECURITY | SEQUENCE | SEQUENCES @@ -15557,23 +15557,36 @@ unreserved_keyword: | VALIDATE | VALIDATOR | VALUE_P - | VARYING | VERSION_P | VIEW | VIEWS | VOLATILE | WHITESPACE_P - | WITHIN - | WITHOUT | WORK | WRAPPER | WRITE | XML_P - | YEAR_P | YES_P | ZONE ; +/* "Non label" keywords --- cannot be a bare column label in a SELECT list + * (you have to write AS in front). Otherwise usable for anything. + */ +non_label_keyword: + DAY_P + | FILTER + | HOUR_P + | MINUTE_P + | MONTH_P + | OVER + | SECOND_P + | VARYING + | WITHIN + | WITHOUT + | YEAR_P + ; + /* Column identifier --- keywords that can be column, table, etc names. * * Many of these keywords will in fact be recognized as type or function
pgsql-hackers by date: