@@ -82,6 +82,40 @@ static void ExecBuildAggTransCall(ExprState *state, AggState *aggstate,
82
82
int transno , int setno , int setoff , bool ishash );
83
83
84
84
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
+
85
119
/*
86
120
* ExecInitExpr: prepare an expression tree for execution
87
121
*
@@ -120,32 +154,7 @@ static void ExecBuildAggTransCall(ExprState *state, AggState *aggstate,
120
154
ExprState *
121
155
ExecInitExpr (Expr * node , PlanState * parent )
122
156
{
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 );
149
158
}
150
159
151
160
/*
@@ -157,32 +166,20 @@ ExecInitExpr(Expr *node, PlanState *parent)
157
166
ExprState *
158
167
ExecInitExprWithParams (Expr * node , ParamListInfo ext_params )
159
168
{
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
+ }
184
171
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 );
186
183
}
187
184
188
185
/*
@@ -2136,11 +2133,19 @@ ExecInitExprRec(Expr *node, ExprState *state,
2136
2133
& scratch .d .jsonexpr .pathspec -> isnull );
2137
2134
2138
2135
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 ));
2140
2143
2141
2144
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 )
2144
2149
: NULL ;
2145
2150
2146
2151
scratch .d .jsonexpr .default_on_empty =
@@ -2190,6 +2195,14 @@ ExecInitExprRec(Expr *node, ExprState *state,
2190
2195
{
2191
2196
JsonCoercion * * coercion ;
2192
2197
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 ;
2193
2206
2194
2207
for (cstate = & scratch .d .jsonexpr .coercions .null ,
2195
2208
coercion = & jexpr -> coercions -> null ;
@@ -2198,8 +2211,9 @@ ExecInitExprRec(Expr *node, ExprState *state,
2198
2211
{
2199
2212
cstate -> coercion = * coercion ;
2200
2213
cstate -> estate = * coercion ?
2201
- ExecInitExpr ((Expr * )(* coercion )-> expr ,
2202
- state -> parent ) : NULL ;
2214
+ ExecInitExprWithCaseValue ((Expr * )(* coercion )-> expr ,
2215
+ state -> parent ,
2216
+ caseval , casenull ) : NULL ;
2203
2217
}
2204
2218
}
2205
2219
0 commit comments