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

Commit66a9003

Browse files
committed
Don't include CaseTestExpr in JsonValueExpr.formatted_expr
A CaseTestExpr is currently being put intoJsonValueExpr.formatted_expr as placeholder for the result ofevaluating JsonValueExpr.raw_expr, which in turn is evaluatedseparately. Though, there's no need for this indirection ifraw_expr itself can be embedded into formatted_expr and evaluatedas part of evaluating the latter, especially as there is nospecial reason to evaluate it separately. So this commit makes itso. As a result, JsonValueExpr.raw_expr no longer needs to beevaluated in ExecInterpExpr(), eval_const_exprs_mutator() etc. andis now only used for displaying the original "unformatted"expression in ruleutils.c. Comments about and the code manipulatingformatted_expr is updated to mention that it is now always set andis the expression that gives a JsonValueExpr its runtime value.While at it, this also removes the function makeCaseTestExpr(),because the code in makeJsonConstructorExpr() looks more readablewithout it IMO and isn't used by anyone else either.Finally, a note is added in the comment above CaseTestExpr'sdefinition that JsonConstructorExpr is also using it.Backpatched to 16 from the development branch to keep the code insync across branches.Reviewed-by: Álvaro Herrera <alvherre@alvh.no-ip.org>Discussion:https://postgr.es/m/CA+HiwqE4XTdfb1nW=Ojoy_tQSRhYt-q_kb6i5d4xcKyrLC1Nbg@mail.gmail.com
1 parentc0f5313 commit66a9003

File tree

8 files changed

+56
-67
lines changed

8 files changed

+56
-67
lines changed

‎src/backend/executor/execExpr.c

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2294,21 +2294,8 @@ ExecInitExprRec(Expr *node, ExprState *state,
22942294
{
22952295
JsonValueExpr*jve= (JsonValueExpr*)node;
22962296

2297-
ExecInitExprRec(jve->raw_expr,state,resv,resnull);
2298-
2299-
if (jve->formatted_expr)
2300-
{
2301-
Datum*innermost_caseval=state->innermost_caseval;
2302-
bool*innermost_isnull=state->innermost_casenull;
2303-
2304-
state->innermost_caseval=resv;
2305-
state->innermost_casenull=resnull;
2306-
2307-
ExecInitExprRec(jve->formatted_expr,state,resv,resnull);
2308-
2309-
state->innermost_caseval=innermost_caseval;
2310-
state->innermost_casenull=innermost_isnull;
2311-
}
2297+
Assert(jve->formatted_expr!=NULL);
2298+
ExecInitExprRec(jve->formatted_expr,state,resv,resnull);
23122299
break;
23132300
}
23142301

‎src/backend/nodes/makefuncs.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -848,12 +848,13 @@ makeJsonFormat(JsonFormatType type, JsonEncoding encoding, int location)
848848
* creates a JsonValueExpr node
849849
*/
850850
JsonValueExpr*
851-
makeJsonValueExpr(Expr*expr,JsonFormat*format)
851+
makeJsonValueExpr(Expr*raw_expr,Expr*formatted_expr,
852+
JsonFormat*format)
852853
{
853854
JsonValueExpr*jve=makeNode(JsonValueExpr);
854855

855-
jve->raw_expr=expr;
856-
jve->formatted_expr=NULL;
856+
jve->raw_expr=raw_expr;
857+
jve->formatted_expr=formatted_expr;
857858
jve->format=format;
858859

859860
returnjve;

‎src/backend/nodes/nodeFuncs.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -225,9 +225,7 @@ exprType(const Node *expr)
225225
{
226226
constJsonValueExpr*jve= (constJsonValueExpr*)expr;
227227

228-
type=exprType((Node*)
229-
(jve->formatted_expr ?jve->formatted_expr :
230-
jve->raw_expr));
228+
type=exprType((Node*)jve->formatted_expr);
231229
}
232230
break;
233231
caseT_JsonConstructorExpr:

‎src/backend/optimizer/util/clauses.c

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2827,25 +2827,12 @@ eval_const_expressions_mutator(Node *node,
28272827
caseT_JsonValueExpr:
28282828
{
28292829
JsonValueExpr*jve= (JsonValueExpr*)node;
2830-
Node*raw;
2830+
Node*formatted;
28312831

2832-
raw=eval_const_expressions_mutator((Node*)jve->raw_expr,
2833-
context);
2834-
if (raw&&IsA(raw,Const))
2835-
{
2836-
Node*formatted;
2837-
Node*save_case_val=context->case_val;
2838-
2839-
context->case_val=raw;
2840-
2841-
formatted=eval_const_expressions_mutator((Node*)jve->formatted_expr,
2842-
context);
2843-
2844-
context->case_val=save_case_val;
2845-
2846-
if (formatted&&IsA(formatted,Const))
2847-
returnformatted;
2848-
}
2832+
formatted=eval_const_expressions_mutator((Node*)jve->formatted_expr,
2833+
context);
2834+
if (formatted&&IsA(formatted,Const))
2835+
returnformatted;
28492836
break;
28502837
}
28512838

‎src/backend/parser/gram.y

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16353,7 +16353,9 @@ opt_asymmetric: ASYMMETRIC
1635316353
json_value_expr:
1635416354
a_expr json_format_clause_opt
1635516355
{
16356-
$$ = (Node *)makeJsonValueExpr((Expr *) $1,castNode(JsonFormat, $2));
16356+
/* formatted_expr will be set during parse-analysis.*/
16357+
$$ = (Node *)makeJsonValueExpr((Expr *) $1,NULL,
16358+
castNode(JsonFormat, $2));
1635716359
}
1635816360
;
1635916361

‎src/backend/parser/parse_expr.c

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3202,24 +3202,13 @@ makeJsonByteaToTextConversion(Node *expr, JsonFormat *format, int location)
32023202
return (Node*)fexpr;
32033203
}
32043204

3205-
/*
3206-
* Make a CaseTestExpr node.
3207-
*/
3208-
staticNode*
3209-
makeCaseTestExpr(Node*expr)
3210-
{
3211-
CaseTestExpr*placeholder=makeNode(CaseTestExpr);
3212-
3213-
placeholder->typeId=exprType(expr);
3214-
placeholder->typeMod=exprTypmod(expr);
3215-
placeholder->collation=exprCollation(expr);
3216-
3217-
return (Node*)placeholder;
3218-
}
3219-
32203205
/*
32213206
* Transform JSON value expression using specified input JSON format or
32223207
* default format otherwise.
3208+
*
3209+
* Returned expression is either ve->raw_expr coerced to text (if needed) or
3210+
* a JsonValueExpr with formatted_expr set to the coerced copy of raw_expr
3211+
* if the specified format requires it.
32233212
*/
32243213
staticNode*
32253214
transformJsonValueExpr(ParseState*pstate,constchar*constructName,
@@ -3268,11 +3257,8 @@ transformJsonValueExpr(ParseState *pstate, const char *constructName,
32683257
if (format!=JS_FORMAT_DEFAULT)
32693258
{
32703259
Oidtargettype=format==JS_FORMAT_JSONB ?JSONBOID :JSONOID;
3271-
Node*orig=makeCaseTestExpr(expr);
32723260
Node*coerced;
32733261

3274-
expr=orig;
3275-
32763262
if (exprtype!=BYTEAOID&&typcategory!=TYPCATEGORY_STRING)
32773263
ereport(ERROR,
32783264
errcode(ERRCODE_DATATYPE_MISMATCH),
@@ -3310,7 +3296,7 @@ transformJsonValueExpr(ParseState *pstate, const char *constructName,
33103296
coerced= (Node*)fexpr;
33113297
}
33123298

3313-
if (coerced==orig)
3299+
if (coerced==expr)
33143300
expr=rawexpr;
33153301
else
33163302
{
@@ -3322,6 +3308,10 @@ transformJsonValueExpr(ParseState *pstate, const char *constructName,
33223308
}
33233309
}
33243310

3311+
/* If returning a JsonValueExpr, formatted_expr must have been set. */
3312+
Assert(!IsA(expr,JsonValueExpr)||
3313+
((JsonValueExpr*)expr)->formatted_expr!=NULL);
3314+
33253315
returnexpr;
33263316
}
33273317

@@ -3537,8 +3527,22 @@ makeJsonConstructorExpr(ParseState *pstate, JsonConstructorType type,
35373527
jsctor->absent_on_null=absent_on_null;
35383528
jsctor->location=location;
35393529

3530+
/*
3531+
* Coerce to the RETURNING type and format, if needed. We abuse
3532+
* CaseTestExpr here as placeholder to pass the result of either
3533+
* evaluating 'fexpr' or whatever is produced by ExecEvalJsonConstructor()
3534+
* that is of type JSON or JSONB to the coercion function.
3535+
*/
35403536
if (fexpr)
3541-
placeholder=makeCaseTestExpr((Node*)fexpr);
3537+
{
3538+
CaseTestExpr*cte=makeNode(CaseTestExpr);
3539+
3540+
cte->typeId=exprType((Node*)fexpr);
3541+
cte->typeMod=exprTypmod((Node*)fexpr);
3542+
cte->collation=exprCollation((Node*)fexpr);
3543+
3544+
placeholder= (Node*)cte;
3545+
}
35423546
else
35433547
{
35443548
CaseTestExpr*cte=makeNode(CaseTestExpr);
@@ -3635,7 +3639,12 @@ transformJsonArrayQueryConstructor(ParseState *pstate,
36353639
makeString(pstrdup("a")));
36363640
colref->location=ctor->location;
36373641

3638-
agg->arg=makeJsonValueExpr((Expr*)colref,ctor->format);
3642+
/*
3643+
* No formatting necessary, so set formatted_expr to be the same as
3644+
* raw_expr.
3645+
*/
3646+
agg->arg=makeJsonValueExpr((Expr*)colref, (Expr*)colref,
3647+
ctor->format);
36393648
agg->absent_on_null=ctor->absent_on_null;
36403649
agg->constructor=makeNode(JsonAggConstructor);
36413650
agg->constructor->agg_order=NIL;
@@ -3900,13 +3909,11 @@ transformJsonParseArg(ParseState *pstate, Node *jsexpr, JsonFormat *format,
39003909
{
39013910
JsonValueExpr*jve;
39023911

3903-
expr=makeCaseTestExpr(raw_expr);
3912+
expr=raw_expr;
39043913
expr=makeJsonByteaToTextConversion(expr,format,exprLocation(expr));
39053914
*exprtype=TEXTOID;
39063915

3907-
jve=makeJsonValueExpr((Expr*)raw_expr,format);
3908-
3909-
jve->formatted_expr= (Expr*)expr;
3916+
jve=makeJsonValueExpr((Expr*)raw_expr, (Expr*)expr,format);
39103917
expr= (Node*)jve;
39113918
}
39123919
else

‎src/include/nodes/makefuncs.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,8 @@ extern VacuumRelation *makeVacuumRelation(RangeVar *relation, Oid oid, List *va_
110110

111111
externJsonFormat*makeJsonFormat(JsonFormatTypetype,JsonEncodingencoding,
112112
intlocation);
113-
externJsonValueExpr*makeJsonValueExpr(Expr*expr,JsonFormat*format);
113+
externJsonValueExpr*makeJsonValueExpr(Expr*raw_expr,Expr*formatted_expr,
114+
JsonFormat*format);
114115
externNode*makeJsonKeyValue(Node*key,Node*value);
115116
externNode*makeJsonIsPredicate(Node*expr,JsonFormat*format,
116117
JsonValueTypeitem_type,boolunique_keys,

‎src/include/nodes/primnodes.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1264,6 +1264,8 @@ typedef struct CaseWhen
12641264
* see build_coercion_expression().
12651265
** Nested FieldStore/SubscriptingRef assignment expressions in INSERT/UPDATE;
12661266
* see transformAssignmentIndirection().
1267+
** Placeholder for intermediate results in some SQL/JSON expression nodes,
1268+
* such as JsonConstructorExpr.
12671269
*
12681270
* The uses in CaseExpr and ArrayCoerceExpr are safe only to the extent that
12691271
* there is not any other CaseExpr or ArrayCoerceExpr between the value source
@@ -1593,12 +1595,16 @@ typedef struct JsonReturning
15931595
/*
15941596
* JsonValueExpr -
15951597
*representation of JSON value expression (expr [FORMAT JsonFormat])
1598+
*
1599+
* The actual value is obtained by evaluating formatted_expr. raw_expr is
1600+
* only there for displaying the original user-written expression and is not
1601+
* evaluated by ExecInterpExpr() and eval_const_exprs_mutator().
15961602
*/
15971603
typedefstructJsonValueExpr
15981604
{
15991605
NodeTagtype;
16001606
Expr*raw_expr;/* raw expression */
1601-
Expr*formatted_expr;/* formatted expressionor NULL*/
1607+
Expr*formatted_expr;/* formatted expression */
16021608
JsonFormat*format;/* FORMAT clause, if specified */
16031609
}JsonValueExpr;
16041610

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp