@@ -810,7 +810,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
810
810
811
811
812
812
/* Precedence: lowest to highest */
813
- %nonassoc SET /* see relation_expr_opt_alias */
814
813
%left UNION EXCEPT
815
814
%left INTERSECT
816
815
%left OR
@@ -821,18 +820,23 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
821
820
%nonassoc BETWEEN IN_P LIKE ILIKE SIMILAR NOT_LA
822
821
%nonassoc ESCAPE /* ESCAPE must be just above LIKE/ILIKE/SIMILAR */
823
822
824
- /* SQL/JSON related keywords */
825
- %nonassoc UNIQUE JSON
826
- %nonassoc KEYS OBJECT_P SCALAR VALUE_P
827
- %nonassoc WITH WITHOUT
828
-
829
823
/*
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.
836
840
*
837
841
* We need to do this for PARTITION, RANGE, ROWS, and GROUPS to support
838
842
* opt_existing_window_name (see comment there).
@@ -850,9 +854,18 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
850
854
* an explicit priority lower than '(', so that a rule with CUBE '(' will shift
851
855
* rather than reducing a conflicting rule that takes CUBE as a function name.
852
856
* 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).
853
865
*/
854
866
%nonassoc UNBOUNDED /* ideally would have same precedence as IDENT */
855
867
%nonassoc IDENT PARTITION RANGE ROWS GROUPS PRECEDING FOLLOWING CUBE ROLLUP
868
+ SET KEYS OBJECT_P SCALAR VALUE_P WITH WITHOUT
856
869
%left Op OPERATOR /* multi-character ops and user-defined operators */
857
870
%left ' +' ' -'
858
871
%left ' *' ' /' ' %'
@@ -16519,21 +16532,35 @@ json_returning_clause_opt:
16519
16532
| /* EMPTY */ { $$ = NULL ; }
16520
16533
;
16521
16534
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
+ */
16522
16545
json_predicate_type_constraint:
16523
- JSON { $$ = JS_TYPE_ANY; }
16546
+ JSON %prec UNBOUNDED { $$ = JS_TYPE_ANY; }
16524
16547
| JSON VALUE_P { $$ = JS_TYPE_ANY; }
16525
16548
| JSON ARRAY { $$ = JS_TYPE_ARRAY; }
16526
16549
| JSON OBJECT_P { $$ = JS_TYPE_OBJECT; }
16527
16550
| JSON SCALAR { $$ = JS_TYPE_SCALAR; }
16528
16551
;
16529
16552
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
+ */
16531
16558
json_key_uniqueness_constraint_opt:
16532
16559
WITH UNIQUE KEYS { $$ = true ; }
16533
- | WITH UNIQUE { $$ = true ; }
16560
+ | WITH UNIQUE %prec UNBOUNDED { $$ = true ; }
16534
16561
| WITHOUT UNIQUE KEYS { $$ = false ; }
16535
- | WITHOUT UNIQUE { $$ = false ; }
16536
- | /* EMPTY */ %prec KEYS { $$ = false ; }
16562
+ | WITHOUT UNIQUE %prec UNBOUNDED { $$ = false ; }
16563
+ | /* EMPTY */ %prec UNBOUNDED { $$ = false ; }
16537
16564
;
16538
16565
16539
16566
json_name_and_value_list:
0 commit comments