v4-0002-Don-t-include-CaseTestExpr-in-JsonValueExpr.forma.patch
application/octet-stream
Filename: v4-0002-Don-t-include-CaseTestExpr-in-JsonValueExpr.forma.patch
Type: application/octet-stream
Part: 5
Message:
Re: remaining sql/json patches
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v4-0002
Subject: Don't include CaseTestExpr in JsonValueExpr.formatted_expr
| File | + | − |
|---|---|---|
| src/backend/executor/execExpr.c | 2 | 15 |
| src/backend/nodes/makefuncs.c | 4 | 0 |
| src/backend/optimizer/util/clauses.c | 5 | 18 |
| src/backend/parser/parse_expr.c | 7 | 5 |
| src/include/nodes/primnodes.h | 4 | 1 |
From e2e69da761ba69557c8ed0f3908c370755d56292 Mon Sep 17 00:00:00 2001
From: Amit Langote <amitlan@postgresql.org>
Date: Fri, 7 Jul 2023 20:21:58 +0900
Subject: [PATCH v4 2/7] Don't include CaseTestExpr in
JsonValueExpr.formatted_expr
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
CaseTestExpr is normally (ab)used as a placeholder expression to
represent the source value for computing an expression when the
expression that provides the source value is computed independently.
A CaseTestExpr is currently 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, so
this commit makes it so.
JsonValueExpr.raw_expr is no longer evaluated by ExecInterpExpr(),
eval_const_exprs_mutator(), etc. and only used for displaying the
original "unformatted" expression.
Reviewed-by: Álvaro Herrera <alvherre@alvh.no-ip.org>
Discussion: https://postgr.es/m/CA+HiwqE4XTdfb1nW=Ojoy_tQSRhYt-q_kb6i5d4xcKyrLC1Nbg@mail.gmail.com
---
src/backend/executor/execExpr.c | 17 ++---------------
src/backend/nodes/makefuncs.c | 4 ++++
src/backend/optimizer/util/clauses.c | 23 +++++------------------
src/backend/parser/parse_expr.c | 12 +++++++-----
src/include/nodes/primnodes.h | 5 ++++-
5 files changed, 22 insertions(+), 39 deletions(-)
diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c
index e6e616865c..bf3a08c5f0 100644
--- a/src/backend/executor/execExpr.c
+++ b/src/backend/executor/execExpr.c
@@ -2294,21 +2294,8 @@ ExecInitExprRec(Expr *node, ExprState *state,
{
JsonValueExpr *jve = (JsonValueExpr *) node;
- ExecInitExprRec(jve->raw_expr, state, resv, resnull);
-
- if (jve->formatted_expr)
- {
- Datum *innermost_caseval = state->innermost_caseval;
- bool *innermost_isnull = state->innermost_casenull;
-
- state->innermost_caseval = resv;
- state->innermost_casenull = resnull;
-
- ExecInitExprRec(jve->formatted_expr, state, resv, resnull);
-
- state->innermost_caseval = innermost_caseval;
- state->innermost_casenull = innermost_isnull;
- }
+ Assert(jve->formatted_expr != NULL);
+ ExecInitExprRec(jve->formatted_expr, state, resv, resnull);
break;
}
diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c
index 39e1884cf4..c6c310d253 100644
--- a/src/backend/nodes/makefuncs.c
+++ b/src/backend/nodes/makefuncs.c
@@ -853,6 +853,10 @@ makeJsonValueExpr(Expr *expr, JsonFormat *format)
JsonValueExpr *jve = makeNode(JsonValueExpr);
jve->raw_expr = expr;
+
+ /*
+ * Set after checking the format, if needed, in transformJsonValueExpr().
+ */
jve->formatted_expr = NULL;
jve->format = format;
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 7f453b04f8..da258968b8 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -2827,25 +2827,12 @@ eval_const_expressions_mutator(Node *node,
case T_JsonValueExpr:
{
JsonValueExpr *jve = (JsonValueExpr *) node;
- Node *raw;
+ Node *formatted;
- raw = eval_const_expressions_mutator((Node *) jve->raw_expr,
- context);
- if (raw && IsA(raw, Const))
- {
- Node *formatted;
- Node *save_case_val = context->case_val;
-
- context->case_val = raw;
-
- formatted = eval_const_expressions_mutator((Node *) jve->formatted_expr,
- context);
-
- context->case_val = save_case_val;
-
- if (formatted && IsA(formatted, Const))
- return formatted;
- }
+ formatted = eval_const_expressions_mutator((Node *) jve->formatted_expr,
+ context);
+ if (formatted && IsA(formatted, Const))
+ return formatted;
break;
}
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 5bf790cf0f..20cbb0a8e7 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -3268,11 +3268,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 +3307,7 @@ transformJsonValueExpr(ParseState *pstate, char *constructName,
coerced = (Node *) fexpr;
}
- if (coerced == orig)
+ if (coerced == expr)
expr = rawexpr;
else
{
@@ -3636,6 +3633,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 +3902,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;
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index 792a743f72..442d675600 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -1593,12 +1593,15 @@ typedef struct JsonReturning
/*
* JsonValueExpr -
* representation of JSON value expression (expr [FORMAT JsonFormat])
+ *
+ * Note that raw_expr is only there for displaying and is not evaluated by
+ * ExecInterpExpr() and eval_const_exprs_mutator().
*/
typedef struct JsonValueExpr
{
NodeTag type;
Expr *raw_expr; /* raw expression */
- Expr *formatted_expr; /* formatted expression or NULL */
+ Expr *formatted_expr; /* formatted expression */
JsonFormat *format; /* FORMAT clause, if specified */
} JsonValueExpr;
--
2.35.3