@@ -602,11 +602,31 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
602602%type <node> json_format_clause_opt
603603 json_representation
604604 json_value_expr
605+ json_func_expr
605606 json_output_clause_opt
607+ json_value_constructor
608+ json_object_constructor
609+ json_object_constructor_args_opt
610+ json_object_args
611+ json_object_ctor_args_opt
612+ json_object_func_args
613+ json_array_constructor
614+ json_name_and_value
615+ json_aggregate_func
616+ json_object_aggregate_constructor
617+ json_array_aggregate_constructor
618+
619+ %type <list> json_name_and_value_list
620+ json_value_expr_list
621+ json_array_aggregate_order_by_clause_opt
606622
607623%type <ival> json_encoding
608624 json_encoding_clause_opt
609625
626+ %type <boolean> json_key_uniqueness_constraint_opt
627+ json_object_constructor_null_clause_opt
628+ json_array_constructor_null_clause_opt
629+
610630/*
611631 * Non-keyword token types. These are hard-wired into the "flex" lexer.
612632 * They must be listed first so that their numeric codes do not depend on
@@ -632,7 +652,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
632652 */
633653
634654/* ordinary key words in alphabetical order */
635- %token <keyword> ABORT_P ABSOLUTE_P ACCESS ACTION ADD_P ADMIN AFTER
655+ %token <keyword> ABORT_P ABSENT ABSOLUTE_P ACCESS ACTION ADD_P ADMIN AFTER
636656 AGGREGATE ALL ALSO ALTER ALWAYS ANALYSE ANALYZE AND ANY ARRAY AS ASC
637657 ASSERTION ASSIGNMENT ASYMMETRIC AT ATTACH ATTRIBUTE AUTHORIZATION
638658
@@ -669,9 +689,9 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
669689 INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P INTEGER
670690 INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION
671691
672- JOIN JSON
692+ JOIN JSON JSON_ARRAY JSON_ARRAYAGG JSON_OBJECT JSON_OBJECTAGG
673693
674- KEY
694+ KEY KEYS
675695
676696 LABEL LANGUAGE LARGE_P LAST_P LATERAL_P
677697 LEADING LEAKPROOF LEAST LEFT LEVEL LIKE LIMIT LISTEN LOAD LOCAL
@@ -735,7 +755,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
735755 * as NOT, at least with respect to their left-hand subexpression.
736756 * NULLS_LA and WITH_LA are needed to make the grammar LALR(1).
737757 */
738- %token NOT_LA NULLS_LA WITH_LA
758+ %token NOT_LA NULLS_LA WITH_LA WITH_LA_UNIQUE WITHOUT_LA
739759
740760/* Precedence: lowest to highest */
741761%nonassoc SET /* see relation_expr_opt_alias */
@@ -778,6 +798,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
778798 * blame any funny behavior of UNBOUNDED on the SQL standard, though.
779799 */
780800%nonassoc UNBOUNDED /* ideally should have same precedence as IDENT */
801+ %nonassoc ABSENT
781802%nonassoc IDENT GENERATED NULL_P PARTITION RANGE ROWS GROUPS PRECEDING FOLLOWING CUBE ROLLUP
782803%left Op OPERATOR /* multi-character ops and user-defined operators */
783804%left ' +' ' -'
@@ -802,6 +823,9 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
802823/* kluge to keep xml_whitespace_option from causing shift/reduce conflicts */
803824%right PRESERVE STRIP_P
804825
826+ %nonassoc empty_json_unique
827+ %left WITHOUT WITH_LA_UNIQUE
828+
805829%%
806830
807831/*
@@ -12834,7 +12858,7 @@ ConstInterval:
1283412858
1283512859opt_timezone :
1283612860 WITH_LA TIME ZONE { $$ = true ; }
12837- | WITHOUT TIME ZONE { $$ = false ; }
12861+ | WITHOUT_LA TIME ZONE { $$ = false ; }
1283812862 | /* EMPTY*/ { $$ = false ; }
1283912863 ;
1284012864
@@ -13443,6 +13467,17 @@ b_expr: c_expr
1344313467 }
1344413468 ;
1344513469
13470+ json_key_uniqueness_constraint_opt :
13471+ WITH_LA_UNIQUE UNIQUE opt_keys { $$ = true ; }
13472+ | WITHOUT UNIQUE opt_keys { $$ = false ; }
13473+ | /* EMPTY */ %prec empty_json_unique { $$ = false ; }
13474+ ;
13475+
13476+ opt_keys :
13477+ KEYS { }
13478+ | /* EMPTY */ { }
13479+ ;
13480+
1344613481/*
1344713482 * Productions that can be used in both a_expr and b_expr.
1344813483 *
@@ -13703,6 +13738,13 @@ func_expr: func_application within_group_clause filter_clause over_clause
1370313738 n->over = $4 ;
1370413739 $$ = (Node *) n;
1370513740 }
13741+ | json_aggregate_func filter_clause over_clause
13742+ {
13743+ JsonAggCtor *n = (JsonAggCtor *) $1 ;
13744+ n->agg_filter = $2 ;
13745+ n->over = $3 ;
13746+ $$ = (Node *) $1 ;
13747+ }
1370613748 | func_expr_common_subexpr
1370713749 { $$ = $1 ; }
1370813750 ;
@@ -13716,6 +13758,7 @@ func_expr: func_application within_group_clause filter_clause over_clause
1371613758func_expr_windowless :
1371713759 func_application { $$ = $1 ; }
1371813760 | func_expr_common_subexpr { $$ = $1 ; }
13761+ | json_aggregate_func { $$ = $1 ; }
1371913762 ;
1372013763
1372113764/*
@@ -13940,6 +13983,8 @@ func_expr_common_subexpr:
1394013983 n->location = @1 ;
1394113984 $$ = (Node *)n;
1394213985 }
13986+ | json_func_expr
13987+ { $$ = $1 ; }
1394313988 ;
1394413989
1394513990/*
@@ -14644,6 +14689,9 @@ opt_asymmetric: ASYMMETRIC
1464414689 ;
1464514690
1464614691/* SQL/JSON support */
14692+ json_func_expr:
14693+ json_value_constructor
14694+ ;
1464714695
1464814696json_value_expr:
1464914697 a_expr json_format_clause_opt
@@ -14690,6 +14738,188 @@ json_output_clause_opt:
1469014738 $$ = (Node *) n;
1469114739 }
1469214740 | /* EMPTY */ { $$ = NULL ; }
14741+ ;
14742+
14743+ json_value_constructor:
14744+ json_object_constructor
14745+ | json_array_constructor
14746+ ;
14747+
14748+ json_object_constructor:
14749+ JSON_OBJECT ' (' json_object_args ' )'
14750+ {
14751+ $$ = $3 ;
14752+ }
14753+ ;
14754+
14755+ json_object_args:
14756+ json_object_ctor_args_opt
14757+ | json_object_func_args
14758+ ;
14759+
14760+ json_object_func_args:
14761+ func_arg_list
14762+ {
14763+ List *func = list_make1 (makeString (" json_object" ));
14764+ $$ = (Node *) makeFuncCall (func, $1 , @1 );
14765+ }
14766+ ;
14767+
14768+ json_object_ctor_args_opt:
14769+ json_object_constructor_args_opt json_output_clause_opt
14770+ {
14771+ JsonObjectCtor *n = (JsonObjectCtor *) $1 ;
14772+ n->output = (JsonOutput *) $2 ;
14773+ n->location = @1 ;
14774+ $$ = (Node *) n;
14775+ }
14776+ ;
14777+
14778+ json_object_constructor_args_opt:
14779+ json_name_and_value_list
14780+ json_object_constructor_null_clause_opt
14781+ json_key_uniqueness_constraint_opt
14782+ {
14783+ JsonObjectCtor *n = makeNode (JsonObjectCtor);
14784+ n->exprs = $1 ;
14785+ n->absent_on_null = $2 ;
14786+ n->unique = $3 ;
14787+ $$ = (Node *) n;
14788+ }
14789+ | /* EMPTY */
14790+ {
14791+ JsonObjectCtor *n = makeNode (JsonObjectCtor);
14792+ n->exprs = NULL ;
14793+ n->absent_on_null = false ;
14794+ n->unique = false ;
14795+ $$ = (Node *) n;
14796+ }
14797+ ;
14798+
14799+ json_name_and_value_list:
14800+ json_name_and_value
14801+ { $$ = list_make1 ($1 ); }
14802+ | json_name_and_value_list ' ,' json_name_and_value
14803+ { $$ = lappend ($1 , $3 ); }
14804+ ;
14805+
14806+ json_name_and_value:
14807+ /* TODO This is not supported due to conflicts
14808+ KEY c_expr VALUE_P json_value_expr %prec POSTFIXOP
14809+ { $$ = makeJsonKeyValue($2, $4); }
14810+ |
14811+ */
14812+ c_expr VALUE_P json_value_expr
14813+ { $$ = makeJsonKeyValue ($1 , $3 ); }
14814+ |
14815+ a_expr ' :' json_value_expr
14816+ { $$ = makeJsonKeyValue ($1 , $3 ); }
14817+ ;
14818+
14819+ json_object_constructor_null_clause_opt:
14820+ NULL_P ON NULL_P { $$ = false ; }
14821+ | ABSENT ON NULL_P { $$ = true ; }
14822+ | /* EMPTY */ { $$ = false ; }
14823+ ;
14824+
14825+ json_array_constructor:
14826+ JSON_ARRAY ' ('
14827+ json_value_expr_list
14828+ json_array_constructor_null_clause_opt
14829+ json_output_clause_opt
14830+ ' )'
14831+ {
14832+ JsonArrayCtor *n = makeNode (JsonArrayCtor);
14833+ n->exprs = $3 ;
14834+ n->absent_on_null = $4 ;
14835+ n->output = (JsonOutput *) $5 ;
14836+ n->location = @1 ;
14837+ $$ = (Node *) n;
14838+ }
14839+ | JSON_ARRAY ' ('
14840+ select_no_parens
14841+ /* json_format_clause_opt */
14842+ /* json_array_constructor_null_clause_opt */
14843+ json_output_clause_opt
14844+ ' )'
14845+ {
14846+ JsonArrayQueryCtor *n = makeNode (JsonArrayQueryCtor);
14847+ n->query = $3 ;
14848+ /* n->format = $4; */
14849+ n->absent_on_null = true /* $5 */ ;
14850+ n->output = (JsonOutput *) $4 ;
14851+ n->location = @1 ;
14852+ $$ = (Node *) n;
14853+ }
14854+ | JSON_ARRAY ' ('
14855+ json_output_clause_opt
14856+ ' )'
14857+ {
14858+ JsonArrayCtor *n = makeNode (JsonArrayCtor);
14859+ n->exprs = NIL;
14860+ n->absent_on_null = true ;
14861+ n->output = (JsonOutput *) $3 ;
14862+ n->location = @1 ;
14863+ $$ = (Node *) n;
14864+ }
14865+ ;
14866+
14867+ json_value_expr_list:
14868+ json_value_expr { $$ = list_make1 ($1 ); }
14869+ | json_value_expr_list ' ,' json_value_expr { $$ = lappend ($1 , $3 );}
14870+ ;
14871+
14872+ json_array_constructor_null_clause_opt:
14873+ NULL_P ON NULL_P { $$ = false ; }
14874+ | ABSENT ON NULL_P { $$ = true ; }
14875+ | /* EMPTY */ { $$ = true ; }
14876+ ;
14877+
14878+ json_aggregate_func:
14879+ json_object_aggregate_constructor
14880+ | json_array_aggregate_constructor
14881+ ;
14882+
14883+ json_object_aggregate_constructor:
14884+ JSON_OBJECTAGG ' ('
14885+ json_name_and_value
14886+ json_object_constructor_null_clause_opt
14887+ json_key_uniqueness_constraint_opt
14888+ json_output_clause_opt
14889+ ' )'
14890+ {
14891+ JsonObjectAgg *n = makeNode (JsonObjectAgg);
14892+ n->arg = (JsonKeyValue *) $3 ;
14893+ n->absent_on_null = $4 ;
14894+ n->unique = $5 ;
14895+ n->ctor .output = (JsonOutput *) $6 ;
14896+ n->ctor .agg_order = NULL ;
14897+ n->ctor .location = @1 ;
14898+ $$ = (Node *) n;
14899+ }
14900+ ;
14901+
14902+ json_array_aggregate_constructor:
14903+ JSON_ARRAYAGG ' ('
14904+ json_value_expr
14905+ json_array_aggregate_order_by_clause_opt
14906+ json_array_constructor_null_clause_opt
14907+ json_output_clause_opt
14908+ ' )'
14909+ {
14910+ JsonArrayAgg *n = makeNode (JsonArrayAgg);
14911+ n->arg = (JsonValueExpr *) $3 ;
14912+ n->ctor .agg_order = $4 ;
14913+ n->absent_on_null = $5 ;
14914+ n->ctor .output = (JsonOutput *) $6 ;
14915+ n->ctor .location = @1 ;
14916+ $$ = (Node *) n;
14917+ }
14918+ ;
14919+
14920+ json_array_aggregate_order_by_clause_opt:
14921+ ORDER BY sortby_list { $$ = $3 ; }
14922+ | /* EMPTY */ { $$ = NIL; }
1469314923 ;
1469414924
1469514925/* ****************************************************************************
@@ -15079,6 +15309,7 @@ ColLabel: IDENT { $$ = $1; }
1507915309 */
1508015310unreserved_keyword:
1508115311 ABORT_P
15312+ | ABSENT
1508215313 | ABSOLUTE_P
1508315314 | ACCESS
1508415315 | ACTION
@@ -15203,6 +15434,7 @@ unreserved_keyword:
1520315434 | ISOLATION
1520415435 | JSON
1520515436 | KEY
15437+ | KEYS
1520615438 | LABEL
1520715439 | LANGUAGE
1520815440 | LARGE_P
@@ -15410,6 +15642,10 @@ col_name_keyword:
1541015642 | INT_P
1541115643 | INTEGER
1541215644 | INTERVAL
15645+ | JSON_ARRAY
15646+ | JSON_ARRAYAGG
15647+ | JSON_OBJECT
15648+ | JSON_OBJECTAGG
1541315649 | LEAST
1541415650 | NATIONAL
1541515651 | NCHAR
0 commit comments