@@ -85,6 +85,40 @@ static void ExecBuildAggTransCall(ExprState *state, AggState *aggstate,
85
85
bool nullcheck );
86
86
87
87
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
+
88
122
/*
89
123
* ExecInitExpr: prepare an expression tree for execution
90
124
*
@@ -123,32 +157,7 @@ static void ExecBuildAggTransCall(ExprState *state, AggState *aggstate,
123
157
ExprState *
124
158
ExecInitExpr (Expr * node , PlanState * parent )
125
159
{
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 );
152
161
}
153
162
154
163
/*
@@ -160,32 +169,20 @@ ExecInitExpr(Expr *node, PlanState *parent)
160
169
ExprState *
161
170
ExecInitExprWithParams (Expr * node , ParamListInfo ext_params )
162
171
{
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
+ }
187
174
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 );
189
186
}
190
187
191
188
/*
@@ -2231,11 +2228,19 @@ ExecInitExprRec(Expr *node, ExprState *state,
2231
2228
& scratch .d .jsonexpr .pathspec -> isnull );
2232
2229
2233
2230
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 ));
2235
2238
2236
2239
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 )
2239
2244
: NULL ;
2240
2245
2241
2246
scratch .d .jsonexpr .default_on_empty = !jexpr -> on_empty ? NULL :
@@ -2285,6 +2290,14 @@ ExecInitExprRec(Expr *node, ExprState *state,
2285
2290
{
2286
2291
JsonCoercion * * coercion ;
2287
2292
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 ;
2288
2301
2289
2302
for (cstate = & scratch .d .jsonexpr .coercions .null ,
2290
2303
coercion = & jexpr -> coercions -> null ;
@@ -2293,8 +2306,9 @@ ExecInitExprRec(Expr *node, ExprState *state,
2293
2306
{
2294
2307
cstate -> coercion = * coercion ;
2295
2308
cstate -> estate = * coercion ?
2296
- ExecInitExpr ((Expr * )(* coercion )-> expr ,
2297
- state -> parent ) : NULL ;
2309
+ ExecInitExprWithCaseValue ((Expr * )(* coercion )-> expr ,
2310
+ state -> parent ,
2311
+ caseval , casenull ) : NULL ;
2298
2312
}
2299
2313
}
2300
2314
0 commit comments