Skip to content

Commit 49ced4f

Browse files
author
Nikita Glukhov
committed
Remove COERCE_INTERNAL_CAST in JsonValueExpr
1 parent edcf87d commit 49ced4f

File tree

12 files changed

+123
-34
lines changed

12 files changed

+123
-34
lines changed

contrib/pg_stat_statements/pg_stat_statements.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3090,7 +3090,8 @@ JumbleExpr(pgssJumbleState *jstate, Node *node)
30903090
{
30913091
JsonValueExpr *expr = (JsonValueExpr *) node;
30923092

3093-
JumbleExpr(jstate, (Node *) expr->expr);
3093+
JumbleExpr(jstate, (Node *) expr->raw_expr);
3094+
JumbleExpr(jstate, (Node *) expr->formatted_expr);
30943095
APP_JUMB(expr->format.type);
30953096
APP_JUMB(expr->format.encoding);
30963097
}

src/backend/executor/execExpr.c

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2109,9 +2109,26 @@ ExecInitExprRec(Expr *node, ExprState *state,
21092109
}
21102110

21112111
case T_JsonValueExpr:
2112-
ExecInitExprRec(((JsonValueExpr *) node)->expr, state, resv,
2113-
resnull);
2114-
break;
2112+
{
2113+
JsonValueExpr *jve = (JsonValueExpr *) node;
2114+
2115+
ExecInitExprRec(jve->raw_expr, state, resv, resnull);
2116+
2117+
if (jve->formatted_expr)
2118+
{
2119+
Datum *innermost_caseval = state->innermost_caseval;
2120+
bool *innermost_isnull = state->innermost_casenull;
2121+
2122+
state->innermost_caseval = resv;
2123+
state->innermost_casenull = resnull;
2124+
2125+
ExecInitExprRec(jve->formatted_expr, state, resv, resnull);
2126+
2127+
state->innermost_caseval = innermost_caseval;
2128+
state->innermost_casenull = innermost_isnull;
2129+
}
2130+
break;
2131+
}
21152132

21162133
default:
21172134
elog(ERROR, "unrecognized node type: %d",

src/backend/nodes/copyfuncs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2256,7 +2256,8 @@ _copyJsonValueExpr(const JsonValueExpr *from)
22562256
{
22572257
JsonValueExpr *newnode = makeNode(JsonValueExpr);
22582258

2259-
COPY_NODE_FIELD(expr);
2259+
COPY_NODE_FIELD(raw_expr);
2260+
COPY_NODE_FIELD(formatted_expr);
22602261
COPY_SCALAR_FIELD(format);
22612262

22622263
return newnode;

src/backend/nodes/equalfuncs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,8 @@ _equalOnConflictExpr(const OnConflictExpr *a, const OnConflictExpr *b)
821821
static bool
822822
_equalJsonValueExpr(const JsonValueExpr *a, const JsonValueExpr *b)
823823
{
824-
COMPARE_NODE_FIELD(expr);
824+
COMPARE_NODE_FIELD(raw_expr);
825+
COMPARE_NODE_FIELD(formatted_expr);
825826
COMPARE_SCALAR_FIELD(format.type);
826827
COMPARE_SCALAR_FIELD(format.encoding);
827828
COMPARE_LOCATION_FIELD(format.location);

src/backend/nodes/makefuncs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -841,7 +841,8 @@ makeJsonValueExpr(Expr *expr, JsonFormat *format)
841841
{
842842
JsonValueExpr *jve = makeNode(JsonValueExpr);
843843

844-
jve->expr = expr;
844+
jve->raw_expr = expr;
845+
jve->formatted_expr = NULL;
845846
jve->format = format;
846847

847848
return jve;

src/backend/nodes/nodeFuncs.c

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,11 @@ exprType(const Node *expr)
259259
type = exprType((Node *) ((const PlaceHolderVar *) expr)->phexpr);
260260
break;
261261
case T_JsonValueExpr:
262-
type = exprType((Node *) ((const JsonValueExpr *) expr)->expr);
262+
{
263+
const JsonValueExpr *jve = (const JsonValueExpr *) expr;
264+
265+
type = exprType((Node *) (jve->formatted_expr ? jve->formatted_expr : jve->raw_expr));
266+
}
263267
break;
264268
default:
265269
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
@@ -495,7 +499,7 @@ exprTypmod(const Node *expr)
495499
case T_PlaceHolderVar:
496500
return exprTypmod((Node *) ((const PlaceHolderVar *) expr)->phexpr);
497501
case T_JsonValueExpr:
498-
return exprTypmod((Node *) ((const JsonValueExpr *) expr)->expr);
502+
return exprTypmod((Node *) ((const JsonValueExpr *) expr)->formatted_expr);
499503
default:
500504
break;
501505
}
@@ -912,7 +916,7 @@ exprCollation(const Node *expr)
912916
coll = exprCollation((Node *) ((const PlaceHolderVar *) expr)->phexpr);
913917
break;
914918
case T_JsonValueExpr:
915-
coll = exprCollation((Node *) ((const JsonValueExpr *) expr)->expr);
919+
coll = exprCollation((Node *) ((const JsonValueExpr *) expr)->formatted_expr);
916920
break;
917921
default:
918922
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
@@ -1118,7 +1122,7 @@ exprSetCollation(Node *expr, Oid collation)
11181122
* type */
11191123
break;
11201124
case T_JsonValueExpr:
1121-
exprSetCollation((Node *) ((const JsonValueExpr *) expr)->expr,
1125+
exprSetCollation((Node *) ((JsonValueExpr *) expr)->formatted_expr,
11221126
collation);
11231127
break;
11241128
default:
@@ -1562,7 +1566,7 @@ exprLocation(const Node *expr)
15621566
loc = ((const PartitionRangeDatum *) expr)->location;
15631567
break;
15641568
case T_JsonValueExpr:
1565-
loc = exprLocation((Node *) ((const JsonValueExpr *) expr)->expr);
1569+
loc = exprLocation((Node *) ((const JsonValueExpr *) expr)->raw_expr);
15661570
break;
15671571
default:
15681572
/* for any other node type it's just unknown... */
@@ -2262,7 +2266,15 @@ expression_tree_walker(Node *node,
22622266
}
22632267
break;
22642268
case T_JsonValueExpr:
2265-
return walker(((JsonValueExpr *) node)->expr, context);
2269+
{
2270+
JsonValueExpr *jve = (JsonValueExpr *) node;
2271+
2272+
if (walker(jve->raw_expr, context))
2273+
return true;
2274+
if (walker(jve->formatted_expr, context))
2275+
return true;
2276+
}
2277+
break;
22662278
default:
22672279
elog(ERROR, "unrecognized node type: %d",
22682280
(int) nodeTag(node));
@@ -3192,7 +3204,8 @@ expression_tree_mutator(Node *node,
31923204
JsonValueExpr *newnode;
31933205

31943206
FLATCOPY(newnode, jve, JsonValueExpr);
3195-
MUTATE(newnode->expr, jve->expr, Expr *);
3207+
MUTATE(newnode->raw_expr, jve->raw_expr, Expr *);
3208+
MUTATE(newnode->formatted_expr, jve->formatted_expr, Expr *);
31963209

31973210
return (Node *) newnode;
31983211
}
@@ -3892,7 +3905,15 @@ raw_expression_tree_walker(Node *node,
38923905
case T_CommonTableExpr:
38933906
return walker(((CommonTableExpr *) node)->ctequery, context);
38943907
case T_JsonValueExpr:
3895-
return walker(((JsonValueExpr *) node)->expr, context);
3908+
{
3909+
JsonValueExpr *jve = (JsonValueExpr *) node;
3910+
3911+
if (walker(jve->raw_expr, context))
3912+
return true;
3913+
if (walker(jve->formatted_expr, context))
3914+
return true;
3915+
}
3916+
break;
38963917
default:
38973918
elog(ERROR, "unrecognized node type: %d",
38983919
(int) nodeTag(node));

src/backend/nodes/outfuncs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1714,7 +1714,8 @@ _outJsonValueExpr(StringInfo str, const JsonValueExpr *node)
17141714
{
17151715
WRITE_NODE_TYPE("JSONVALUEEXPR");
17161716

1717-
WRITE_NODE_FIELD(expr);
1717+
WRITE_NODE_FIELD(raw_expr);
1718+
WRITE_NODE_FIELD(formatted_expr);
17181719
WRITE_ENUM_FIELD(format.type, JsonFormatType);
17191720
WRITE_ENUM_FIELD(format.encoding, JsonEncoding);
17201721
WRITE_LOCATION_FIELD(format.location);

src/backend/nodes/readfuncs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1351,7 +1351,8 @@ _readJsonValueExpr(void)
13511351
{
13521352
READ_LOCALS(JsonValueExpr);
13531353

1354-
READ_NODE_FIELD(expr);
1354+
READ_NODE_FIELD(raw_expr);
1355+
READ_NODE_FIELD(formatted_expr);
13551356
READ_ENUM_FIELD(format.type, JsonFormatType);
13561357
READ_ENUM_FIELD(format.encoding, JsonEncoding);
13571358
READ_LOCATION_FIELD(format.location);

src/backend/optimizer/util/clauses.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3523,6 +3523,29 @@ eval_const_expressions_mutator(Node *node,
35233523
return ece_evaluate_expr((Node *) newcre);
35243524
return (Node *) newcre;
35253525
}
3526+
case T_JsonValueExpr:
3527+
{
3528+
JsonValueExpr *jve = (JsonValueExpr *) node;
3529+
Node *raw = eval_const_expressions_mutator((Node *) jve->raw_expr,
3530+
context);
3531+
3532+
if (raw && IsA(raw, Const))
3533+
{
3534+
Node *formatted;
3535+
Node *save_case_val = context->case_val;
3536+
3537+
context->case_val = raw;
3538+
3539+
formatted = eval_const_expressions_mutator((Node *) jve->formatted_expr,
3540+
context);
3541+
3542+
context->case_val = save_case_val;
3543+
3544+
if (formatted && IsA(formatted, Const))
3545+
return formatted;
3546+
}
3547+
break;
3548+
}
35263549
default:
35273550
break;
35283551
}

src/backend/parser/parse_expr.c

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3627,6 +3627,21 @@ makeJsonByteaToTextConversion(Node *expr, JsonFormat *format, int location)
36273627
return (Node *) fexpr;
36283628
}
36293629

3630+
/*
3631+
* Make CaseTestExpr node.
3632+
*/
3633+
static Node *
3634+
makeCaseTestExpr(Node *expr)
3635+
{
3636+
CaseTestExpr *placeholder = makeNode(CaseTestExpr);
3637+
3638+
placeholder->typeId = exprType(expr);
3639+
placeholder->typeMod = exprTypmod(expr);
3640+
placeholder->collation = exprCollation(expr);
3641+
3642+
return (Node *) placeholder;
3643+
}
3644+
36303645
/*
36313646
* Transform JSON value expression using specified input JSON format or
36323647
* default format otherwise.
@@ -3635,7 +3650,8 @@ static Node *
36353650
transformJsonValueExpr(ParseState *pstate, JsonValueExpr *ve,
36363651
JsonFormatType default_format)
36373652
{
3638-
Node *expr = transformExprRecurse(pstate, (Node *) ve->expr);
3653+
Node *expr = transformExprRecurse(pstate, (Node *) ve->raw_expr);
3654+
Node *rawexpr;
36393655
JsonFormatType format;
36403656
Oid exprtype;
36413657
int location;
@@ -3645,6 +3661,7 @@ transformJsonValueExpr(ParseState *pstate, JsonValueExpr *ve,
36453661
if (exprType(expr) == UNKNOWNOID)
36463662
expr = coerce_to_specific_type(pstate, expr, TEXTOID, "JSON_VALUE_EXPR");
36473663

3664+
rawexpr = expr;
36483665
exprtype = exprType(expr);
36493666
location = exprLocation(expr);
36503667

@@ -3676,8 +3693,10 @@ transformJsonValueExpr(ParseState *pstate, JsonValueExpr *ve,
36763693
if (format != JS_FORMAT_DEFAULT)
36773694
{
36783695
Oid targettype = format == JS_FORMAT_JSONB ? JSONBOID : JSONOID;
3696+
Node *orig = makeCaseTestExpr(expr);
36793697
Node *coerced;
3680-
FuncExpr *fexpr;
3698+
3699+
expr = orig;
36813700

36823701
if (exprtype != BYTEAOID && typcategory != TYPCATEGORY_STRING)
36833702
ereport(ERROR,
@@ -3699,28 +3718,32 @@ transformJsonValueExpr(ParseState *pstate, JsonValueExpr *ve,
36993718
coerced = coerce_to_target_type(pstate, expr, exprtype,
37003719
targettype, -1,
37013720
COERCION_EXPLICIT,
3702-
COERCE_INTERNAL_CAST,
3721+
COERCE_EXPLICIT_CAST,
37033722
location);
37043723

3705-
if (coerced)
3706-
expr = coerced;
3707-
else
3724+
if (!coerced)
37083725
{
37093726
/* If coercion failed, use to_json()/to_jsonb() functions. */
37103727
Oid fnoid = targettype == JSONOID ? F_TO_JSON : F_TO_JSONB;
3711-
3712-
fexpr = makeFuncExpr(fnoid, targettype, list_make1(expr),
3713-
InvalidOid, InvalidOid,
3714-
COERCE_INTERNAL_CAST);
3728+
FuncExpr *fexpr = makeFuncExpr(fnoid, targettype,
3729+
list_make1(expr),
3730+
InvalidOid, InvalidOid,
3731+
COERCE_EXPLICIT_CALL);
37153732
fexpr->location = location;
37163733

3717-
expr = (Node *) fexpr;
3734+
coerced = (Node *) fexpr;
37183735
}
37193736

3720-
ve = copyObject(ve);
3721-
ve->expr = (Expr *) expr;
3737+
if (coerced == orig)
3738+
expr = rawexpr;
3739+
else
3740+
{
3741+
ve = copyObject(ve);
3742+
ve->raw_expr = (Expr *) rawexpr;
3743+
ve->formatted_expr = (Expr *) coerced;
37223744

3723-
expr = (Node *) ve;
3745+
expr = (Node *) ve;
3746+
}
37243747
}
37253748

37263749
return expr;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy