Skip to content

Commit da82c98

Browse files
author
Nikita Glukhov
committed
Remove ExecExprPassingCaseValue()
1 parent ff2645a commit da82c98

File tree

4 files changed

+90
-100
lines changed

4 files changed

+90
-100
lines changed

src/backend/executor/execExpr.c

Lines changed: 72 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,40 @@ static void ExecBuildAggTransCall(ExprState *state, AggState *aggstate,
8181
int transno, int setno, int setoff, bool ishash);
8282

8383

84+
static ExprState *
85+
ExecInitExprInternal(Expr *node, PlanState *parent, ParamListInfo ext_params,
86+
Datum *caseval, bool *casenull)
87+
{
88+
ExprState *state;
89+
ExprEvalStep scratch = {0};
90+
91+
/* Special case: NULL expression produces a NULL ExprState pointer */
92+
if (node == NULL)
93+
return NULL;
94+
95+
/* Initialize ExprState with empty step list */
96+
state = makeNode(ExprState);
97+
state->expr = node;
98+
state->parent = parent;
99+
state->ext_params = ext_params;
100+
state->innermost_caseval = caseval;
101+
state->innermost_casenull = casenull;
102+
103+
/* Insert EEOP_*_FETCHSOME steps as needed */
104+
ExecInitExprSlots(state, (Node *) node);
105+
106+
/* Compile the expression proper */
107+
ExecInitExprRec(node, state, &state->resvalue, &state->resnull);
108+
109+
/* Finally, append a DONE step */
110+
scratch.opcode = EEOP_DONE;
111+
ExprEvalPushStep(state, &scratch);
112+
113+
ExecReadyExpr(state);
114+
115+
return state;
116+
}
117+
84118
/*
85119
* ExecInitExpr: prepare an expression tree for execution
86120
*
@@ -119,32 +153,7 @@ static void ExecBuildAggTransCall(ExprState *state, AggState *aggstate,
119153
ExprState *
120154
ExecInitExpr(Expr *node, PlanState *parent)
121155
{
122-
ExprState *state;
123-
ExprEvalStep scratch = {0};
124-
125-
/* Special case: NULL expression produces a NULL ExprState pointer */
126-
if (node == NULL)
127-
return NULL;
128-
129-
/* Initialize ExprState with empty step list */
130-
state = makeNode(ExprState);
131-
state->expr = node;
132-
state->parent = parent;
133-
state->ext_params = NULL;
134-
135-
/* Insert EEOP_*_FETCHSOME steps as needed */
136-
ExecInitExprSlots(state, (Node *) node);
137-
138-
/* Compile the expression proper */
139-
ExecInitExprRec(node, state, &state->resvalue, &state->resnull);
140-
141-
/* Finally, append a DONE step */
142-
scratch.opcode = EEOP_DONE;
143-
ExprEvalPushStep(state, &scratch);
144-
145-
ExecReadyExpr(state);
146-
147-
return state;
156+
return ExecInitExprInternal(node, parent, NULL, NULL, NULL);
148157
}
149158

150159
/*
@@ -156,32 +165,20 @@ ExecInitExpr(Expr *node, PlanState *parent)
156165
ExprState *
157166
ExecInitExprWithParams(Expr *node, ParamListInfo ext_params)
158167
{
159-
ExprState *state;
160-
ExprEvalStep scratch = {0};
161-
162-
/* Special case: NULL expression produces a NULL ExprState pointer */
163-
if (node == NULL)
164-
return NULL;
165-
166-
/* Initialize ExprState with empty step list */
167-
state = makeNode(ExprState);
168-
state->expr = node;
169-
state->parent = NULL;
170-
state->ext_params = ext_params;
171-
172-
/* Insert EEOP_*_FETCHSOME steps as needed */
173-
ExecInitExprSlots(state, (Node *) node);
174-
175-
/* Compile the expression proper */
176-
ExecInitExprRec(node, state, &state->resvalue, &state->resnull);
177-
178-
/* Finally, append a DONE step */
179-
scratch.opcode = EEOP_DONE;
180-
ExprEvalPushStep(state, &scratch);
181-
182-
ExecReadyExpr(state);
168+
return ExecInitExprInternal(node, NULL, ext_params, NULL, NULL);
169+
}
183170

184-
return state;
171+
/*
172+
* ExecInitExprWithCaseValue: prepare an expression tree for execution
173+
*
174+
* This is the same as ExecInitExpr, except that a pointer to the value for
175+
* CasTestExpr is passed here.
176+
*/
177+
ExprState *
178+
ExecInitExprWithCaseValue(Expr *node, PlanState *parent,
179+
Datum *caseval, bool *casenull)
180+
{
181+
return ExecInitExprInternal(node, parent, NULL, caseval, casenull);
185182
}
186183

187184
/*
@@ -2129,7 +2126,7 @@ ExecInitExprRec(Expr *node, ExprState *state,
21292126
scratch.d.jsonexpr.jsexpr = jexpr;
21302127

21312128
scratch.d.jsonexpr.raw_expr =
2132-
palloc(sizeof(*scratch.d.jsonexpr.raw_expr));
2129+
palloc(sizeof(*scratch.d.jsonexpr.raw_expr));
21332130

21342131
ExecInitExprRec((Expr *) jexpr->raw_expr, state,
21352132
&scratch.d.jsonexpr.raw_expr->value,
@@ -2143,12 +2140,20 @@ ExecInitExprRec(Expr *node, ExprState *state,
21432140
&scratch.d.jsonexpr.pathspec->isnull);
21442141

21452142
scratch.d.jsonexpr.formatted_expr =
2146-
ExecInitExpr((Expr *) jexpr->formatted_expr,
2147-
state->parent);
2143+
ExecInitExprWithCaseValue((Expr *) jexpr->formatted_expr,
2144+
state->parent,
2145+
&scratch.d.jsonexpr.raw_expr->value,
2146+
&scratch.d.jsonexpr.raw_expr->isnull);
2147+
2148+
scratch.d.jsonexpr.res_expr =
2149+
palloc(sizeof(*scratch.d.jsonexpr.res_expr));
2150+
21482151

21492152
scratch.d.jsonexpr.result_expr = jexpr->result_coercion
2150-
? ExecInitExpr((Expr *) jexpr->result_coercion->expr,
2151-
state->parent)
2153+
? ExecInitExprWithCaseValue((Expr *) jexpr->result_coercion->expr,
2154+
state->parent,
2155+
&scratch.d.jsonexpr.res_expr->value,
2156+
&scratch.d.jsonexpr.res_expr->isnull)
21522157
: NULL;
21532158

21542159
scratch.d.jsonexpr.default_on_empty =
@@ -2200,6 +2205,14 @@ ExecInitExprRec(Expr *node, ExprState *state,
22002205
{
22012206
JsonCoercion **coercion;
22022207
struct JsonCoercionState *cstate;
2208+
Datum *caseval;
2209+
bool *casenull;
2210+
2211+
scratch.d.jsonexpr.coercion_expr =
2212+
palloc(sizeof(*scratch.d.jsonexpr.coercion_expr));
2213+
2214+
caseval = &scratch.d.jsonexpr.coercion_expr->value;
2215+
casenull = &scratch.d.jsonexpr.coercion_expr->isnull;
22032216

22042217
for (cstate = &scratch.d.jsonexpr.coercions.null,
22052218
coercion = &jexpr->coercions->null;
@@ -2208,8 +2221,9 @@ ExecInitExprRec(Expr *node, ExprState *state,
22082221
{
22092222
cstate->coercion = *coercion;
22102223
cstate->estate = *coercion ?
2211-
ExecInitExpr((Expr *)(*coercion)->expr,
2212-
state->parent) : NULL;
2224+
ExecInitExprWithCaseValue((Expr *)(*coercion)->expr,
2225+
state->parent,
2226+
caseval, casenull) : NULL;
22132227
}
22142228
}
22152229

src/backend/executor/execExprInterp.c

Lines changed: 14 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -4141,40 +4141,6 @@ ExecEvalAggOrderedTransTuple(ExprState *state, ExprEvalStep *op,
41414141
tuplesort_puttupleslot(pertrans->sortstates[setno], pertrans->sortslot);
41424142
}
41434143

4144-
/*
4145-
* Evaluate a expression substituting specified value in its CaseTestExpr nodes.
4146-
*/
4147-
static Datum
4148-
ExecEvalExprPassingCaseValue(ExprState *estate, ExprContext *econtext,
4149-
bool *isnull,
4150-
Datum caseval_datum, bool caseval_isnull)
4151-
{
4152-
Datum res;
4153-
Datum save_datum = econtext->caseValue_datum;
4154-
bool save_isNull = econtext->caseValue_isNull;
4155-
4156-
econtext->caseValue_datum = caseval_datum;
4157-
econtext->caseValue_isNull = caseval_isnull;
4158-
4159-
PG_TRY();
4160-
{
4161-
res = ExecEvalExpr(estate, econtext, isnull);
4162-
}
4163-
PG_CATCH();
4164-
{
4165-
econtext->caseValue_datum = save_datum;
4166-
econtext->caseValue_isNull = save_isNull;
4167-
4168-
PG_RE_THROW();
4169-
}
4170-
PG_END_TRY();
4171-
4172-
econtext->caseValue_datum = save_datum;
4173-
econtext->caseValue_isNull = save_isNull;
4174-
4175-
return res;
4176-
}
4177-
41784144
/*
41794145
* Evaluate a JSON error/empty behavior result.
41804146
*/
@@ -4234,8 +4200,12 @@ ExecEvalJsonExprCoercion(ExprEvalStep *op, ExprContext *econtext,
42344200
jexpr->returning.typmod);
42354201
}
42364202
else if (op->d.jsonexpr.result_expr)
4237-
res = ExecEvalExprPassingCaseValue(op->d.jsonexpr.result_expr, econtext,
4238-
isNull, res, *isNull);
4203+
{
4204+
op->d.jsonexpr.res_expr->value = res;
4205+
op->d.jsonexpr.res_expr->isnull = *isNull;
4206+
4207+
res = ExecEvalExpr(op->d.jsonexpr.result_expr, econtext, isNull);
4208+
}
42394209
else if (coercion && coercion->via_populate)
42404210
res = json_populate_type(res, JSONBOID,
42414211
jexpr->returning.typid,
@@ -4362,8 +4332,10 @@ ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op, ExprContext *econtext,
43624332
{
43634333
bool isnull;
43644334

4365-
item = ExecEvalExprPassingCaseValue(op->d.jsonexpr.formatted_expr,
4366-
econtext, &isnull, item, false);
4335+
op->d.jsonexpr.raw_expr->value = item;
4336+
op->d.jsonexpr.raw_expr->isnull = false;
4337+
4338+
item = ExecEvalExpr(op->d.jsonexpr.formatted_expr, econtext, &isnull);
43674339
if (isnull)
43684340
{
43694341
/* execute domain checks for NULLs */
@@ -4410,10 +4382,10 @@ ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op, ExprContext *econtext,
44104382
}
44114383
else if (jcstate->estate)
44124384
{
4413-
res = ExecEvalExprPassingCaseValue(jcstate->estate,
4414-
econtext,
4415-
resnull,
4416-
res, false);
4385+
op->d.jsonexpr.coercion_expr->value = res;
4386+
op->d.jsonexpr.coercion_expr->isnull = false;
4387+
4388+
res = ExecEvalExpr(jcstate->estate, econtext, resnull);
44174389
}
44184390
/* else no coercion */
44194391
}

src/include/executor/execExpr.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,8 @@ typedef struct ExprEvalStep
655655
Datum value;
656656
bool isnull;
657657
} *raw_expr, /* raw context item value */
658+
*res_expr, /* result item */
659+
*coercion_expr, /* input for JSON item coercion */
658660
*pathspec; /* path specification value */
659661

660662
ExprState *formatted_expr; /* formatted context item */

src/include/executor/executor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,8 @@ ExecProcNode(PlanState *node)
243243
*/
244244
extern ExprState *ExecInitExpr(Expr *node, PlanState *parent);
245245
extern ExprState *ExecInitExprWithParams(Expr *node, ParamListInfo ext_params);
246+
extern ExprState *ExecInitExprWithCaseValue(Expr *node, PlanState *parent,
247+
Datum *caseval, bool *casenull);
246248
extern ExprState *ExecInitQual(List *qual, PlanState *parent);
247249
extern ExprState *ExecInitCheck(List *qual, PlanState *parent);
248250
extern List *ExecInitExprList(List *nodes, PlanState *parent);

0 commit comments

Comments
 (0)