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

Commita916b47

Browse files
committed
Clean up usage of bison precedence for non-operator keywords.
Assigning a precedence to a keyword that isn't a kind of expressionoperator is rather dangerous, because it might mask grammarambiguities that we'd rather know about. It's much safer to attachexplicit precedences to individual rules, which will affect thebehavior of only that one rule. Moreover, when we do have to givea precedence to a non-operator keyword, we should try to give it thesame precedence as IDENT, thereby reducing the risk of surprisingside-effects.Apply this hard-won knowledge to SET (which I misassigned ages agoin commit2647ad6) and some SQL/JSON-related productions(from commits6ee3020,71bfd15).Patch HEAD only, since there's no evidence of actual bugs here.Discussion:https://postgr.es/m/CADT4RqBPdbsZW7HS1jJP319TMRHs1hzUiP=iRJYR6UqgHCrgNQ@mail.gmail.com
1 parentc82207a commita916b47

File tree

1 file changed

+44
-17
lines changed

1 file changed

+44
-17
lines changed

‎src/backend/parser/gram.y

Lines changed: 44 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -810,7 +810,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
810810

811811

812812
/* Precedence: lowest to highest*/
813-
%nonassocSET/* see relation_expr_opt_alias*/
814813
%leftUNIONEXCEPT
815814
%leftINTERSECT
816815
%leftOR
@@ -821,18 +820,23 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
821820
%nonassocBETWEENIN_PLIKEILIKESIMILARNOT_LA
822821
%nonassocESCAPE/* ESCAPE must be just above LIKE/ILIKE/SIMILAR*/
823822

824-
/* SQL/JSON related keywords*/
825-
%nonassocUNIQUEJSON
826-
%nonassocKEYSOBJECT_PSCALARVALUE_P
827-
%nonassocWITHWITHOUT
828-
829823
/*
830-
* To support target_el without AS, it used to be necessary to assign IDENT an
831-
* explicit precedence just less than Op. While that's not really necessary
832-
* since we removed postfix operators, it's still helpful to do so because
833-
* there are some other unreserved keywords that need precedence assignments.
834-
* If those keywords have the same precedence as IDENT then they clearly act
835-
* the same as non-keywords, reducing the risk of unwanted precedence effects.
824+
* Sometimes it is necessary to assign precedence to keywords that are not
825+
* really part of the operator hierarchy, in order to resolve grammar
826+
* ambiguities. It's best to avoid doing so whenever possible, because such
827+
* assignments have global effect and may hide ambiguities besides the one
828+
* you intended to solve. (Attaching a precedence to a single rule with
829+
* %prec is far safer and should be preferred.) If you must give precedence
830+
* to a new keyword, try very hard to give it the same precedence as IDENT.
831+
* If the keyword has IDENT's precedence then it clearly acts the same as
832+
* non-keywords and other similar keywords, thus reducing the risk of
833+
* unexpected precedence effects.
834+
*
835+
* We used to need to assign IDENT an explicit precedence just less than Op,
836+
* to support target_el without AS. While that's not really necessary since
837+
* we removed postfix operators, we continue to do so because it provides a
838+
* reference point for a precedence level that we can assign to other
839+
* keywords that lack a natural precedence level.
836840
*
837841
* We need to do this for PARTITION, RANGE, ROWS, and GROUPS to support
838842
* opt_existing_window_name (see comment there).
@@ -850,9 +854,18 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
850854
* an explicit priority lower than '(', so that a rule with CUBE '(' will shift
851855
* rather than reducing a conflicting rule that takes CUBE as a function name.
852856
* Using the same precedence as IDENT seems right for the reasons given above.
857+
*
858+
* SET is likewise assigned the same precedence as IDENT, to support the
859+
* relation_expr_opt_alias production (see comment there).
860+
*
861+
* KEYS, OBJECT_P, SCALAR, VALUE_P, WITH, and WITHOUT are similarly assigned
862+
* the same precedence as IDENT. This allows resolving conflicts in the
863+
* json_predicate_type_constraint and json_key_uniqueness_constraint_opt
864+
* productions (see comments there).
853865
*/
854866
%nonassocUNBOUNDED/* ideally would have same precedence as IDENT*/
855867
%nonassocIDENTPARTITIONRANGEROWSGROUPSPRECEDINGFOLLOWINGCUBEROLLUP
868+
SETKEYSOBJECT_PSCALARVALUE_PWITHWITHOUT
856869
%leftOpOPERATOR/* multi-character ops and user-defined operators*/
857870
%left'+''-'
858871
%left'*''/''%'
@@ -16519,21 +16532,35 @@ json_returning_clause_opt:
1651916532
|/* EMPTY*/{ $$ =NULL; }
1652016533
;
1652116534

16535+
/*
16536+
* We must assign the only-JSON production a precedence less than IDENT in
16537+
* order to favor shifting over reduction when JSON is followed by VALUE_P,
16538+
* OBJECT_P, or SCALAR. (ARRAY doesn't need that treatment, because it's a
16539+
* fully reserved word.) Because json_predicate_type_constraint is always
16540+
* followed by json_key_uniqueness_constraint_opt, we also need the only-JSON
16541+
* production to have precedence less than WITH and WITHOUT. UNBOUNDED isn't
16542+
* really related to this syntax, but it's a convenient choice because it
16543+
* already has a precedence less than IDENT for other reasons.
16544+
*/
1652216545
json_predicate_type_constraint:
16523-
JSON{ $$ = JS_TYPE_ANY; }
16546+
JSON%prec UNBOUNDED{ $$ = JS_TYPE_ANY; }
1652416547
| JSON VALUE_P{ $$ = JS_TYPE_ANY; }
1652516548
| JSON ARRAY{ $$ = JS_TYPE_ARRAY; }
1652616549
| JSON OBJECT_P{ $$ = JS_TYPE_OBJECT; }
1652716550
| JSON SCALAR{ $$ = JS_TYPE_SCALAR; }
1652816551
;
1652916552

16530-
/* KEYS is a noise word here*/
16553+
/*
16554+
* KEYS is a noise word here. To avoid shift/reduce conflicts, assign the
16555+
* KEYS-less productions a precedence less than IDENT (i.e., less than KEYS).
16556+
* This prevents reducing them when the next token is KEYS.
16557+
*/
1653116558
json_key_uniqueness_constraint_opt:
1653216559
WITH UNIQUE KEYS{ $$ =true; }
16533-
| WITH UNIQUE{ $$ =true; }
16560+
| WITH UNIQUE%prec UNBOUNDED{ $$ =true; }
1653416561
| WITHOUT UNIQUE KEYS{ $$ =false; }
16535-
| WITHOUT UNIQUE{ $$ =false; }
16536-
|/* EMPTY*/ %precKEYS{ $$ =false; }
16562+
| WITHOUT UNIQUE%prec UNBOUNDED{ $$ =false; }
16563+
|/* EMPTY*/ %precUNBOUNDED{ $$ =false; }
1653716564
;
1653816565

1653916566
json_name_and_value_list:

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp