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

Commit b6e1157

Browse files
committed
Don't include CaseTestExpr in JsonValueExpr.formatted_expr
A CaseTestExpr is currently being put into JsonValueExpr.formatted_expr as placeholder for the result of evaluating JsonValueExpr.raw_expr, which in turn is evaluated separately. Though, there's no need for this indirection if raw_expr itself can be embedded into formatted_expr and evaluated as part of evaluating the latter, especially as there is no special reason to evaluate it separately. So this commit makes it so. As a result, JsonValueExpr.raw_expr no longer needs to be evaluated in ExecInterpExpr(), eval_const_exprs_mutator() etc. and is now only used for displaying the original "unformatted" expression in ruleutils.c. While at it, this also removes the function makeCaseTestExpr(), because the code in makeJsonConstructorExpr() looks more readable without it IMO and isn't used by anyone else either. Finally, a note is added in the comment above CaseTestExpr's definition that JsonConstructorExpr is also using it. Reviewed-by: Álvaro Herrera <alvherre@alvh.no-ip.org> Discussion: https://postgr.es/m/CA+HiwqE4XTdfb1nW=Ojoy_tQSRhYt-q_kb6i5d4xcKyrLC1Nbg@mail.gmail.com
1 parent 785480c commit b6e1157

File tree

5 files changed

+39
-55
lines changed

5 files changed

+39
-55
lines changed

src/backend/executor/execExpr.c

+2-15
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

+4
Original file line numberDiff line numberDiff line change
@@ -853,6 +853,10 @@ makeJsonValueExpr(Expr *expr, JsonFormat *format)
853853
JsonValueExpr *jve = makeNode(JsonValueExpr);
854854

855855
jve->raw_expr = expr;
856+
857+
/*
858+
* Set after checking the format, if needed, in transformJsonValueExpr().
859+
*/
856860
jve->formatted_expr = NULL;
857861
jve->format = format;
858862

src/backend/optimizer/util/clauses.c

+5-18
Original file line numberDiff line numberDiff line change
@@ -2827,25 +2827,12 @@ eval_const_expressions_mutator(Node *node,
28272827
case T_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-
return formatted;
2848-
}
2832+
formatted = eval_const_expressions_mutator((Node *) jve->formatted_expr,
2833+
context);
2834+
if (formatted && IsA(formatted, Const))
2835+
return formatted;
28492836
break;
28502837
}
28512838

src/backend/parser/parse_expr.c

+22-21
Original file line numberDiff line numberDiff line change
@@ -3202,21 +3202,6 @@ makeJsonByteaToTextConversion(Node *expr, JsonFormat *format, int location)
32023202
return (Node *) fexpr;
32033203
}
32043204

3205-
/*
3206-
* Make a CaseTestExpr node.
3207-
*/
3208-
static Node *
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.
@@ -3268,11 +3253,8 @@ transformJsonValueExpr(ParseState *pstate, char *constructName,
32683253
if (format != JS_FORMAT_DEFAULT)
32693254
{
32703255
Oid targettype = format == JS_FORMAT_JSONB ? JSONBOID : JSONOID;
3271-
Node *orig = makeCaseTestExpr(expr);
32723256
Node *coerced;
32733257

3274-
expr = orig;
3275-
32763258
if (exprtype != BYTEAOID && typcategory != TYPCATEGORY_STRING)
32773259
ereport(ERROR,
32783260
errcode(ERRCODE_DATATYPE_MISMATCH),
@@ -3310,7 +3292,7 @@ transformJsonValueExpr(ParseState *pstate, char *constructName,
33103292
coerced = (Node *) fexpr;
33113293
}
33123294

3313-
if (coerced == orig)
3295+
if (coerced == expr)
33143296
expr = rawexpr;
33153297
else
33163298
{
@@ -3537,8 +3519,22 @@ makeJsonConstructorExpr(ParseState *pstate, JsonConstructorType type,
35373519
jsctor->absent_on_null = absent_on_null;
35383520
jsctor->location = location;
35393521

3522+
/*
3523+
* Coerce to the RETURNING type and format, if needed. We abuse
3524+
* CaseTestExpr here as placeholder to pass the result of either evaluating
3525+
* 'fexpr' or whatever is produced by ExecEvalJsonConstructor() that is of
3526+
* type JSON or JSONB to the coercion function.
3527+
*/
35403528
if (fexpr)
3541-
placeholder = makeCaseTestExpr((Node *) fexpr);
3529+
{
3530+
CaseTestExpr *cte = makeNode(CaseTestExpr);
3531+
3532+
cte->typeId = exprType((Node *) fexpr);
3533+
cte->typeMod = exprTypmod((Node *) fexpr);
3534+
cte->collation = exprCollation((Node *) fexpr);
3535+
3536+
placeholder = (Node *) cte;
3537+
}
35423538
else
35433539
{
35443540
CaseTestExpr *cte = makeNode(CaseTestExpr);
@@ -3636,6 +3632,11 @@ transformJsonArrayQueryConstructor(ParseState *pstate,
36363632
colref->location = ctor->location;
36373633

36383634
agg->arg = makeJsonValueExpr((Expr *) colref, ctor->format);
3635+
/*
3636+
* No formatting necessary, so set formatted_expr to be the same as
3637+
* raw_expr.
3638+
*/
3639+
agg->arg->formatted_expr = agg->arg->raw_expr;
36393640
agg->absent_on_null = ctor->absent_on_null;
36403641
agg->constructor = makeNode(JsonAggConstructor);
36413642
agg->constructor->agg_order = NIL;
@@ -3900,7 +3901,7 @@ transformJsonParseArg(ParseState *pstate, Node *jsexpr, JsonFormat *format,
39003901
{
39013902
JsonValueExpr *jve;
39023903

3903-
expr = makeCaseTestExpr(raw_expr);
3904+
expr = raw_expr;
39043905
expr = makeJsonByteaToTextConversion(expr, format, exprLocation(expr));
39053906
*exprtype = TEXTOID;
39063907

src/include/nodes/primnodes.h

+6-1
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,15 @@ typedef struct JsonReturning
15931595
/*
15941596
* JsonValueExpr -
15951597
* representation of JSON value expression (expr [FORMAT JsonFormat])
1598+
*
1599+
* Note that raw_expr is only there for displaying and is not evaluated by
1600+
* ExecInterpExpr() and eval_const_exprs_mutator().
15961601
*/
15971602
typedef struct JsonValueExpr
15981603
{
15991604
NodeTag type;
16001605
Expr *raw_expr; /* raw expression */
1601-
Expr *formatted_expr; /* formatted expression or NULL */
1606+
Expr *formatted_expr; /* formatted expression */
16021607
JsonFormat *format; /* FORMAT clause, if specified */
16031608
} JsonValueExpr;
16041609

0 commit comments

Comments
 (0)