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

Commit 76d01c6

Browse files
author
Nikita Glukhov
committed
Remove ExecExprPassingCaseValue()
1 parent d631ce1 commit 76d01c6

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
@@ -82,6 +82,40 @@ static void ExecBuildAggTransCall(ExprState *state, AggState *aggstate,
8282
int transno, int setno, int setoff, bool ishash);
8383

8484

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

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

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

188185
/*
@@ -2136,11 +2133,19 @@ ExecInitExprRec(Expr *node, ExprState *state,
21362133
&scratch.d.jsonexpr.pathspec->isnull);
21372134

21382135
scratch.d.jsonexpr.formatted_expr =
2139-
ExecInitExpr((Expr *) jexpr->formatted_expr, state->parent);
2136+
ExecInitExprWithCaseValue((Expr *) jexpr->formatted_expr,
2137+
state->parent,
2138+
&scratch.d.jsonexpr.raw_expr->value,
2139+
&scratch.d.jsonexpr.raw_expr->isnull);
2140+
2141+
scratch.d.jsonexpr.res_expr =
2142+
palloc(sizeof(*scratch.d.jsonexpr.res_expr));
21402143

21412144
scratch.d.jsonexpr.result_expr = jexpr->result_coercion
2142-
? ExecInitExpr((Expr *) jexpr->result_coercion->expr,
2143-
state->parent)
2145+
? ExecInitExprWithCaseValue((Expr *) jexpr->result_coercion->expr,
2146+
state->parent,
2147+
&scratch.d.jsonexpr.res_expr->value,
2148+
&scratch.d.jsonexpr.res_expr->isnull)
21442149
: NULL;
21452150

21462151
scratch.d.jsonexpr.default_on_empty =
@@ -2190,6 +2195,14 @@ ExecInitExprRec(Expr *node, ExprState *state,
21902195
{
21912196
JsonCoercion **coercion;
21922197
struct JsonCoercionState *cstate;
2198+
Datum *caseval;
2199+
bool *casenull;
2200+
2201+
scratch.d.jsonexpr.coercion_expr =
2202+
palloc(sizeof(*scratch.d.jsonexpr.coercion_expr));
2203+
2204+
caseval = &scratch.d.jsonexpr.coercion_expr->value;
2205+
casenull = &scratch.d.jsonexpr.coercion_expr->isnull;
21932206

21942207
for (cstate = &scratch.d.jsonexpr.coercions.null,
21952208
coercion = &jexpr->coercions->null;
@@ -2198,8 +2211,9 @@ ExecInitExprRec(Expr *node, ExprState *state,
21982211
{
21992212
cstate->coercion = *coercion;
22002213
cstate->estate = *coercion ?
2201-
ExecInitExpr((Expr *)(*coercion)->expr,
2202-
state->parent) : NULL;
2214+
ExecInitExprWithCaseValue((Expr *)(*coercion)->expr,
2215+
state->parent,
2216+
caseval, casenull) : NULL;
22032217
}
22042218
}
22052219

src/backend/executor/execExprInterp.c

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

4161-
/*
4162-
* Evaluate a expression substituting specified value in its CaseTestExpr nodes.
4163-
*/
4164-
static Datum
4165-
ExecEvalExprPassingCaseValue(ExprState *estate, ExprContext *econtext,
4166-
bool *isnull,
4167-
Datum caseval_datum, bool caseval_isnull)
4168-
{
4169-
Datum res;
4170-
Datum save_datum = econtext->caseValue_datum;
4171-
bool save_isNull = econtext->caseValue_isNull;
4172-
4173-
econtext->caseValue_datum = caseval_datum;
4174-
econtext->caseValue_isNull = caseval_isnull;
4175-
4176-
PG_TRY();
4177-
{
4178-
res = ExecEvalExpr(estate, econtext, isnull);
4179-
}
4180-
PG_CATCH();
4181-
{
4182-
econtext->caseValue_datum = save_datum;
4183-
econtext->caseValue_isNull = save_isNull;
4184-
4185-
PG_RE_THROW();
4186-
}
4187-
PG_END_TRY();
4188-
4189-
econtext->caseValue_datum = save_datum;
4190-
econtext->caseValue_isNull = save_isNull;
4191-
4192-
return res;
4193-
}
4194-
41954161
/*
41964162
* Evaluate a JSON error/empty behavior result.
41974163
*/
@@ -4251,8 +4217,12 @@ ExecEvalJsonExprCoercion(ExprEvalStep *op, ExprContext *econtext,
42514217
jexpr->returning.typmod);
42524218
}
42534219
else if (op->d.jsonexpr.result_expr)
4254-
res = ExecEvalExprPassingCaseValue(op->d.jsonexpr.result_expr, econtext,
4255-
isNull, res, *isNull);
4220+
{
4221+
op->d.jsonexpr.res_expr->value = res;
4222+
op->d.jsonexpr.res_expr->isnull = *isNull;
4223+
4224+
res = ExecEvalExpr(op->d.jsonexpr.result_expr, econtext, isNull);
4225+
}
42564226
else if (coercion && coercion->via_populate)
42574227
res = json_populate_type(res, JSONBOID,
42584228
jexpr->returning.typid,
@@ -4415,8 +4385,10 @@ ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op, ExprContext *econtext,
44154385
{
44164386
bool isnull;
44174387

4418-
item = ExecEvalExprPassingCaseValue(op->d.jsonexpr.formatted_expr,
4419-
econtext, &isnull, item, false);
4388+
op->d.jsonexpr.raw_expr->value = item;
4389+
op->d.jsonexpr.raw_expr->isnull = false;
4390+
4391+
item = ExecEvalExpr(op->d.jsonexpr.formatted_expr, econtext, &isnull);
44204392
if (isnull)
44214393
{
44224394
/* execute domain checks for NULLs */
@@ -4463,10 +4435,10 @@ ExecEvalJsonExpr(ExprState *state, ExprEvalStep *op, ExprContext *econtext,
44634435
}
44644436
else if (jcstate->estate)
44654437
{
4466-
res = ExecEvalExprPassingCaseValue(jcstate->estate,
4467-
econtext,
4468-
resnull,
4469-
res, false);
4438+
op->d.jsonexpr.coercion_expr->value = res;
4439+
op->d.jsonexpr.coercion_expr->isnull = false;
4440+
4441+
res = ExecEvalExpr(jcstate->estate, econtext, resnull);
44704442
}
44714443
/* else no coercion */
44724444
}

src/include/executor/execExpr.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,8 @@ typedef struct ExprEvalStep
673673
Datum value;
674674
bool isnull;
675675
} *raw_expr, /* raw context item value */
676+
*res_expr, /* result item */
677+
*coercion_expr, /* input for JSON item coercion */
676678
*pathspec; /* path specification value */
677679

678680
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
@@ -245,6 +245,8 @@ ExecProcNode(PlanState *node)
245245
*/
246246
extern ExprState *ExecInitExpr(Expr *node, PlanState *parent);
247247
extern ExprState *ExecInitExprWithParams(Expr *node, ParamListInfo ext_params);
248+
extern ExprState *ExecInitExprWithCaseValue(Expr *node, PlanState *parent,
249+
Datum *caseval, bool *casenull);
248250
extern ExprState *ExecInitQual(List *qual, PlanState *parent);
249251
extern ExprState *ExecInitCheck(List *qual, PlanState *parent);
250252
extern List *ExecInitExprList(List *nodes, PlanState *parent);

0 commit comments

Comments
 (0)