@@ -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,
123157ExprState *
124158ExecInitExpr (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)
160169ExprState *
161170ExecInitExprWithParams (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
0 commit comments