diff options
author | Amit Langote <amitlan@postgresql.org> | 2023-07-07 20:21:58 +0900 |
---|---|---|
committer | Amit Langote <amitlan@postgresql.org> | 2023-07-13 12:13:58 +0900 |
commit | b6e1157e7d339c4e20d68448125a4cef42b1ac9d (patch) | |
tree | 93dcf340a2404450ce7039ad495961f4a0d8f313 /src/backend/parser/parse_expr.c | |
parent | 785480c9533d9a905410c1a52f857a431daec37c (diff) | |
download | postgresql-b6e1157e7d339c4e20d68448125a4cef42b1ac9d.tar.gz postgresql-b6e1157e7d339c4e20d68448125a4cef42b1ac9d.zip |
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
Diffstat (limited to 'src/backend/parser/parse_expr.c')
-rw-r--r-- | src/backend/parser/parse_expr.c | 43 |
1 files changed, 22 insertions, 21 deletions
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index 5bf790cf0fe..26344743e40 100644 --- a/src/backend/parser/parse_expr.c +++ b/src/backend/parser/parse_expr.c @@ -3203,21 +3203,6 @@ makeJsonByteaToTextConversion(Node *expr, JsonFormat *format, int location) } /* - * Make a CaseTestExpr node. - */ -static Node * -makeCaseTestExpr(Node *expr) -{ - CaseTestExpr *placeholder = makeNode(CaseTestExpr); - - placeholder->typeId = exprType(expr); - placeholder->typeMod = exprTypmod(expr); - placeholder->collation = exprCollation(expr); - - return (Node *) placeholder; -} - -/* * Transform JSON value expression using specified input JSON format or * default format otherwise. */ @@ -3268,11 +3253,8 @@ transformJsonValueExpr(ParseState *pstate, char *constructName, if (format != JS_FORMAT_DEFAULT) { Oid targettype = format == JS_FORMAT_JSONB ? JSONBOID : JSONOID; - Node *orig = makeCaseTestExpr(expr); Node *coerced; - expr = orig; - if (exprtype != BYTEAOID && typcategory != TYPCATEGORY_STRING) ereport(ERROR, errcode(ERRCODE_DATATYPE_MISMATCH), @@ -3310,7 +3292,7 @@ transformJsonValueExpr(ParseState *pstate, char *constructName, coerced = (Node *) fexpr; } - if (coerced == orig) + if (coerced == expr) expr = rawexpr; else { @@ -3537,8 +3519,22 @@ makeJsonConstructorExpr(ParseState *pstate, JsonConstructorType type, jsctor->absent_on_null = absent_on_null; jsctor->location = location; + /* + * Coerce to the RETURNING type and format, if needed. We abuse + * CaseTestExpr here as placeholder to pass the result of either evaluating + * 'fexpr' or whatever is produced by ExecEvalJsonConstructor() that is of + * type JSON or JSONB to the coercion function. + */ if (fexpr) - placeholder = makeCaseTestExpr((Node *) fexpr); + { + CaseTestExpr *cte = makeNode(CaseTestExpr); + + cte->typeId = exprType((Node *) fexpr); + cte->typeMod = exprTypmod((Node *) fexpr); + cte->collation = exprCollation((Node *) fexpr); + + placeholder = (Node *) cte; + } else { CaseTestExpr *cte = makeNode(CaseTestExpr); @@ -3636,6 +3632,11 @@ transformJsonArrayQueryConstructor(ParseState *pstate, colref->location = ctor->location; agg->arg = makeJsonValueExpr((Expr *) colref, ctor->format); + /* + * No formatting necessary, so set formatted_expr to be the same as + * raw_expr. + */ + agg->arg->formatted_expr = agg->arg->raw_expr; agg->absent_on_null = ctor->absent_on_null; agg->constructor = makeNode(JsonAggConstructor); agg->constructor->agg_order = NIL; @@ -3900,7 +3901,7 @@ transformJsonParseArg(ParseState *pstate, Node *jsexpr, JsonFormat *format, { JsonValueExpr *jve; - expr = makeCaseTestExpr(raw_expr); + expr = raw_expr; expr = makeJsonByteaToTextConversion(expr, format, exprLocation(expr)); *exprtype = TEXTOID; |