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: