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

Commit 779f6bd

Browse files
author
Nikita Glukhov
committed
Remove ExecExprPassingCaseValue()
1 parent c863327 commit 779f6bd

File tree

4 files changed

+88
-98
lines changed

4 files changed

+88
-98
lines changed

src/backend/executor/execExpr.c

Lines changed: 70 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,40 @@ static void ExecBuildAggTransCall(ExprState *state, AggState *aggstate,
8585
bool nullcheck);
8686

8787

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

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

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

191188
/*
@@ -2231,11 +2228,19 @@ ExecInitExprRec(Expr *node, ExprState *state,
22312228
&scratch.d.jsonexpr.pathspec->isnull);
22322229

22332230
scratch.d.jsonexpr.formatted_expr =
2234-
ExecInitExpr((Expr *) jexpr->formatted_expr, state->parent);
2231+
ExecInitExprWithCaseValue((Expr *) jexpr->formatted_expr,
2232+
state->parent,
2233+
&scratch.d.jsonexpr.raw_expr->value,
2234+
&scratch.d.jsonexpr.raw_expr->isnull);
2235+
2236+
scratch.d.jsonexpr.res_expr =
2237+
palloc(sizeof(*scratch.d.jsonexpr.res_expr));
22352238

22362239
scratch.d.jsonexpr.result_expr = jexpr->result_coercion
2237-
? ExecInitExpr((Expr *) jexpr->result_coercion->expr,
2238-
state->parent)
2240+
? ExecInitExprWithCaseValue((Expr *) jexpr->result_coercion->expr,
2241+
state->parent,
2242+
&scratch.d.jsonexpr.res_expr->value,
2243+
&scratch.d.jsonexpr.res_expr->isnull)
22392244
: NULL;
22402245

22412246
scratch.d.jsonexpr.default_on_empty = !jexpr->on_empty ? NULL :
@@ -2285,6 +2290,14 @@ ExecInitExprRec(Expr *node, ExprState *state,
22852290
{
22862291
JsonCoercion **coercion;
22872292
struct JsonCoercionState *cstate;
2293+
Datum *caseval;
2294+
bool *casenull;
2295+
2296+
scratch.d.jsonexpr.coercion_expr =
2297+
palloc(sizeof(*scratch.d.jsonexpr.coercion_expr));
2298+
2299+
caseval = &scratch.d.jsonexpr.coercion_expr->value;
2300+
casenull = &scratch.d.jsonexpr.coercion_expr->isnull;
22882301

22892302
for (cstate = &scratch.d.jsonexpr.coercions.null,
22902303
coercion = &jexpr->coercions->null;
@@ -2293,8 +2306,9 @@ ExecInitExprRec(Expr *node, ExprState *state,
22932306
{
22942307
cstate->coercion = *coercion;
22952308
cstate->estate = *coercion ?
2296-
ExecInitExpr((Expr *)(*coercion)->expr,
2297-
state->parent) : NULL;
2309+
ExecInitExprWithCaseValue((Expr *)(*coercion)->expr,
2310+
state->parent,
2311+
caseval, casenull) : NULL;
22982312
}
22992313
}
23002314

src/backend/executor/execExprInterp.c

Lines changed: 14 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -4471,40 +4471,6 @@ ExecAggPlainTransByRef(AggState *aggstate, AggStatePerTrans pertrans,
44714471
MemoryContextSwitchTo(oldContext);
44724472
}
44734473

4474-
/*
4475-
* Evaluate a expression substituting specified value in its CaseTestExpr nodes.
4476-
*/
4477-
static Datum
4478-
ExecEvalExprPassingCaseValue(ExprState *estate, ExprContext *econtext,
4479-
bool *isnull,
4480-
Datum caseval_datum, bool caseval_isnull)
4481-
{
4482-
Datum res;
4483-
Datum save_datum = econtext->caseValue_datum;
4484-
bool save_isNull = econtext->caseValue_isNull;
4485-
4486-
econtext->caseValue_datum = caseval_datum;
4487-
econtext->caseValue_isNull = caseval_isnull;
4488-
4489-
PG_TRY();
4490-
{
4491-
res = ExecEvalExpr(estate, econtext, isnull);
4492-
}
4493-
PG_CATCH();
4494-
{
4495-
econtext->caseValue_datum = save_datum;
4496-
econtext->caseValue_isNull = save_isNull;
4497-
4498-
PG_RE_THROW();
4499-
}
4500-
PG_END_TRY();
4501-
4502-
econtext->caseValue_datum = save_datum;
4503-
econtext->caseValue_isNull = save_isNull;
4504-
4505-
return res;
4506-
}
4507-
45084474
/*
45094475
* Evaluate a JSON error/empty behavior result.
45104476
*/
@@ -4564,8 +4530,12 @@ ExecEvalJsonExprCoercion(ExprEvalStep *op, ExprContext *econtext,
45644530
jexpr->returning->typmod);
45654531
}
45664532
else if (op->d.jsonexpr.result_expr)
4567-
res = ExecEvalExprPassingCaseValue(op->d.jsonexpr.result_expr, econtext,
4568-
isNull, res, *isNull);
4533+
{
4534+
op->d.jsonexpr.res_expr->value = res;
4535+
op->d.jsonexpr.res_expr->isnull = *isNull;
4536+
4537+
res = ExecEvalExpr(op->d.jsonexpr.result_expr, econtext, isNull);
4538+
}
45694539
else if (coercion && coercion->via_populate)
45704540
res = json_populate_type(res, JSONBOID,
45714541
jexpr->returning->typid,
@@ -4728,8 +4698,10 @@ ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op, ExprContext *econtext,
47284698
{
47294699
bool isnull;
47304700

4731-
item = ExecEvalExprPassingCaseValue(op->d.jsonexpr.formatted_expr,
4732-
econtext, &isnull, item, false);
4701+
op->d.jsonexpr.raw_expr->value = item;
4702+
op->d.jsonexpr.raw_expr->isnull = false;
4703+
4704+
item = ExecEvalExpr(op->d.jsonexpr.formatted_expr, econtext, &isnull);
47334705
if (isnull)
47344706
{
47354707
/* execute domain checks for NULLs */
@@ -4776,10 +4748,10 @@ ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op, ExprContext *econtext,
47764748
}
47774749
else if (jcstate->estate)
47784750
{
4779-
res = ExecEvalExprPassingCaseValue(jcstate->estate,
4780-
econtext,
4781-
resnull,
4782-
res, false);
4751+
op->d.jsonexpr.coercion_expr->value = res;
4752+
op->d.jsonexpr.coercion_expr->isnull = false;
4753+
4754+
res = ExecEvalExpr(jcstate->estate, econtext, resnull);
47834755
}
47844756
/* else no coercion */
47854757
}

src/include/executor/execExpr.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,8 @@ typedef struct ExprEvalStep
677677
Datum value;
678678
bool isnull;
679679
} *raw_expr, /* raw context item value */
680+
*res_expr, /* result item */
681+
*coercion_expr, /* input for JSON item coercion */
680682
*pathspec; /* path specification value */
681683

682684
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
@@ -251,6 +251,8 @@ ExecProcNode(PlanState *node)
251251
*/
252252
extern ExprState *ExecInitExpr(Expr *node, PlanState *parent);
253253
extern ExprState *ExecInitExprWithParams(Expr *node, ParamListInfo ext_params);
254+
extern ExprState *ExecInitExprWithCaseValue(Expr *node, PlanState *parent,
255+
Datum *caseval, bool *casenull);
254256
extern ExprState *ExecInitQual(List *qual, PlanState *parent);
255257
extern ExprState *ExecInitCheck(List *qual, PlanState *parent);
256258
extern List *ExecInitExprList(List *nodes, PlanState *parent);

0 commit comments

Comments
 (0)