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

Commit7247297

Browse files
author
Nikita Glukhov
committed
Allow variable jsonpath specifications
1 parent5070aad commit7247297

File tree

13 files changed

+94
-18
lines changed

13 files changed

+94
-18
lines changed

‎contrib/pg_stat_statements/pg_stat_statements.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3140,7 +3140,7 @@ JumbleExpr(pgssJumbleState *jstate, Node *node)
31403140

31413141
APP_JUMB(jexpr->op);
31423142
JumbleExpr(jstate,jexpr->raw_expr);
3143-
JumbleExpr(jstate,(Node*)jexpr->path_spec);
3143+
JumbleExpr(jstate,jexpr->path_spec);
31443144
foreach(temp,jexpr->passing_names)
31453145
{
31463146
APP_JUMB_STRING(castNode(Value,temp)->val.str);

‎src/backend/executor/execExpr.c‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2223,6 +2223,13 @@ ExecInitExprRec(Expr *node, ExprState *state,
22232223
&scratch.d.jsonexpr.raw_expr->value,
22242224
&scratch.d.jsonexpr.raw_expr->isnull);
22252225

2226+
scratch.d.jsonexpr.pathspec=
2227+
palloc(sizeof(*scratch.d.jsonexpr.pathspec));
2228+
2229+
ExecInitExprRec((Expr*)jexpr->path_spec,state,
2230+
&scratch.d.jsonexpr.pathspec->value,
2231+
&scratch.d.jsonexpr.pathspec->isnull);
2232+
22262233
scratch.d.jsonexpr.formatted_expr=
22272234
ExecInitExpr((Expr*)jexpr->formatted_expr,state->parent);
22282235

‎src/backend/executor/execExprInterp.c‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4832,7 +4832,7 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
48324832
*op->resnull= true;/* until we get a result */
48334833
*op->resvalue= (Datum)0;
48344834

4835-
if (op->d.jsonexpr.raw_expr->isnull)
4835+
if (op->d.jsonexpr.raw_expr->isnull||op->d.jsonexpr.pathspec->isnull)
48364836
{
48374837
/* execute domain checks for NULLs */
48384838
(void)ExecEvalJsonExprCoercion(op,econtext,res,op->resnull);
@@ -4844,8 +4844,7 @@ ExecEvalJson(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
48444844
}
48454845

48464846
item=op->d.jsonexpr.raw_expr->value;
4847-
4848-
path=DatumGetJsonPathP(jexpr->path_spec->constvalue);
4847+
path=DatumGetJsonPathP(op->d.jsonexpr.pathspec->value);
48494848

48504849
/* reset JSON path variable contexts */
48514850
foreach(lc,op->d.jsonexpr.args)

‎src/backend/nodes/copyfuncs.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2565,7 +2565,7 @@ _copyJsonCommon(const JsonCommon *from)
25652565
JsonCommon*newnode=makeNode(JsonCommon);
25662566

25672567
COPY_NODE_FIELD(expr);
2568-
COPY_STRING_FIELD(pathspec);
2568+
COPY_NODE_FIELD(pathspec);
25692569
COPY_STRING_FIELD(pathname);
25702570
COPY_NODE_FIELD(passing);
25712571
COPY_LOCATION_FIELD(location);

‎src/backend/nodes/nodeFuncs.c‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3405,6 +3405,7 @@ expression_tree_mutator(Node *node,
34053405
JsonExpr*newnode;
34063406

34073407
FLATCOPY(newnode,jexpr,JsonExpr);
3408+
MUTATE(newnode->path_spec,jexpr->path_spec,Node*);
34083409
MUTATE(newnode->raw_expr,jexpr->raw_expr,Node*);
34093410
MUTATE(newnode->formatted_expr,jexpr->formatted_expr,Node*);
34103411
MUTATE(newnode->result_coercion,jexpr->result_coercion,JsonCoercion*);
@@ -4264,6 +4265,8 @@ raw_expression_tree_walker(Node *node,
42644265

42654266
if (walker(jc->expr,context))
42664267
return true;
4268+
if (walker(jc->pathspec,context))
4269+
return true;
42674270
if (walker(jc->passing,context))
42684271
return true;
42694272
}

‎src/backend/parser/gram.y‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -629,15 +629,15 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
629629
json_aggregate_func
630630
json_object_aggregate_constructor
631631
json_array_aggregate_constructor
632+
json_path_specification
632633

633634
%type<list>json_name_and_value_list
634635
json_value_expr_list
635636
json_array_aggregate_order_by_clause_opt
636637
json_arguments
637638
json_passing_clause_opt
638639

639-
%type<str>json_path_specification
640-
json_table_path_name
640+
%type<str>json_table_path_name
641641
json_as_path_name_clause_opt
642642

643643
%type<ival>json_encoding
@@ -843,6 +843,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
843843
*/
844844
%nonassocUNBOUNDED/* ideally should have same precedence as IDENT*/
845845
%nonassocERROR_PEMPTY_PDEFAULTABSENT/* JSON error/empty behavior*/
846+
%nonassocFALSE_PKEEPOMITPASSINGTRUE_PUNKNOWN
846847
%nonassocIDENTGENERATEDNULL_PPARTITIONRANGEROWSGROUPSPRECEDINGFOLLOWINGCUBEROLLUP
847848
%leftOpOPERATOR/* multi-character ops and user-defined operators*/
848849
%left'+''-'
@@ -14831,7 +14832,7 @@ json_context_item:
1483114832
;
1483214833

1483314834
json_path_specification:
14834-
Sconst{ $$ = $1; }
14835+
a_expr{ $$ = $1; }
1483514836
;
1483614837

1483714838
json_as_path_name_clause_opt:

‎src/backend/parser/parse_expr.c‎

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4535,7 +4535,7 @@ static JsonExpr *
45354535
transformJsonExprCommon(ParseState*pstate,JsonFuncExpr*func)
45364536
{
45374537
JsonExpr*jsexpr=makeNode(JsonExpr);
4538-
Datumjsonpath;
4538+
Node*pathspec;
45394539
JsonFormatTypeformat;
45404540

45414541
if (func->common->pathname)
@@ -4566,12 +4566,19 @@ transformJsonExprCommon(ParseState *pstate, JsonFuncExpr *func)
45664566

45674567
jsexpr->format=func->common->expr->format;
45684568

4569-
/* parse JSON path string */
4570-
jsonpath=DirectFunctionCall1(jsonpath_in,
4571-
CStringGetDatum(func->common->pathspec));
4569+
pathspec=transformExprRecurse(pstate,func->common->pathspec);
45724570

4573-
jsexpr->path_spec=makeConst(JSONPATHOID,-1,InvalidOid,-1,
4574-
jsonpath, false, false);
4571+
jsexpr->path_spec=
4572+
coerce_to_target_type(pstate,pathspec,exprType(pathspec),
4573+
JSONPATHOID,-1,
4574+
COERCION_EXPLICIT,COERCE_IMPLICIT_CAST,
4575+
exprLocation(pathspec));
4576+
if (!jsexpr->path_spec)
4577+
ereport(ERROR,
4578+
(errcode(ERRCODE_DATATYPE_MISMATCH),
4579+
errmsg("JSON path expression must be type %s, not type %s",
4580+
"jsonpath",format_type_be(exprType(pathspec))),
4581+
parser_errposition(pstate,exprLocation(pathspec))));
45754582

45764583
/* transform and coerce to json[b] passing arguments */
45774584
transformJsonPassingArgs(pstate,format,func->common->passing,

‎src/backend/utils/adt/ruleutils.c‎

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,8 @@ static char *generate_qualified_type_name(Oid typid);
487487
statictext*string_to_text(char*str);
488488
staticchar*flatten_reloptions(Oidrelid);
489489
staticvoidget_reloptions(StringInfobuf,Datumreloptions);
490+
staticvoidget_json_path_spec(Node*path_spec,deparse_context*context,
491+
boolshowimplicit);
490492

491493
#defineonly_marker(rte) ((rte)->inh ? "" : "ONLY ")
492494

@@ -7909,6 +7911,19 @@ get_rule_expr_paren(Node *node, deparse_context *context,
79097911
appendStringInfoChar(context->buf,')');
79107912
}
79117913

7914+
7915+
/*
7916+
* get_json_path_spec- Parse back a JSON path specification
7917+
*/
7918+
staticvoid
7919+
get_json_path_spec(Node*path_spec,deparse_context*context,boolshowimplicit)
7920+
{
7921+
if (IsA(path_spec,Const))
7922+
get_const_expr((Const*)path_spec,context,-1);
7923+
else
7924+
get_rule_expr(path_spec,context,showimplicit);
7925+
}
7926+
79127927
/*
79137928
* get_json_format- Parse back a JsonFormat node
79147929
*/
@@ -9271,7 +9286,7 @@ get_rule_expr(Node *node, deparse_context *context,
92719286

92729287
appendStringInfoString(buf,", ");
92739288

9274-
get_const_expr(jexpr->path_spec,context,-1);
9289+
get_json_path_spec(jexpr->path_spec,context,showimplicit);
92759290

92769291
if (jexpr->passing_values)
92779292
{

‎src/include/executor/execExpr.h‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -676,7 +676,8 @@ typedef struct ExprEvalStep
676676
{
677677
Datumvalue;
678678
boolisnull;
679-
}*raw_expr;/* raw context item value */
679+
}*raw_expr,/* raw context item value */
680+
*pathspec;/* path specification value */
680681

681682
ExprState*formatted_expr;/* formatted context item */
682683
ExprState*result_expr;/* coerced to output type */

‎src/include/nodes/parsenodes.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1535,7 +1535,7 @@ typedef struct JsonCommon
15351535
{
15361536
NodeTagtype;
15371537
JsonValueExpr*expr;/* context item expression */
1538-
JsonPathSpecpathspec;/* JSON path specification */
1538+
Node*pathspec;/* JSON path specification expression */
15391539
char*pathname;/* path name, if any */
15401540
List*passing;/* list of PASSING clause arguments, if any */
15411541
intlocation;/* token location, or -1 if unknown */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp