Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit cb80df9

Browse files
author
Nikita Glukhov
committed
Add SQL/JSON constructors parsing
1 parent 80424b5 commit cb80df9

File tree

9 files changed

+393
-5
lines changed

9 files changed

+393
-5
lines changed

src/backend/nodes/makefuncs.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -868,3 +868,18 @@ makeJsonEncoding(char *name)
868868

869869
return JS_ENC_DEFAULT;
870870
}
871+
872+
/*
873+
* makeJsonKeyValue -
874+
* creates a JsonKeyValue node
875+
*/
876+
Node *
877+
makeJsonKeyValue(Node *key, Node *value)
878+
{
879+
JsonKeyValue *n = makeNode(JsonKeyValue);
880+
881+
n->key = (Expr *) key;
882+
n->value = castNode(JsonValueExpr, value);
883+
884+
return (Node *) n;
885+
}

src/backend/parser/gram.y

Lines changed: 241 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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

1283512859
opt_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
1371613758
func_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

1464814696
json_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
*/
1508015310
unreserved_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

Comments
 (0)