@@ -81,6 +81,40 @@ static void ExecBuildAggTransCall(ExprState *state, AggState *aggstate,
81
81
int transno , int setno , int setoff , bool ishash );
82
82
83
83
84
+ static ExprState *
85
+ ExecInitExprInternal (Expr * node , PlanState * parent , ParamListInfo ext_params ,
86
+ Datum * caseval , bool * casenull )
87
+ {
88
+ ExprState * state ;
89
+ ExprEvalStep scratch = {0 };
90
+
91
+ /* Special case: NULL expression produces a NULL ExprState pointer */
92
+ if (node == NULL )
93
+ return NULL ;
94
+
95
+ /* Initialize ExprState with empty step list */
96
+ state = makeNode (ExprState );
97
+ state -> expr = node ;
98
+ state -> parent = parent ;
99
+ state -> ext_params = ext_params ;
100
+ state -> innermost_caseval = caseval ;
101
+ state -> innermost_casenull = casenull ;
102
+
103
+ /* Insert EEOP_*_FETCHSOME steps as needed */
104
+ ExecInitExprSlots (state , (Node * ) node );
105
+
106
+ /* Compile the expression proper */
107
+ ExecInitExprRec (node , state , & state -> resvalue , & state -> resnull );
108
+
109
+ /* Finally, append a DONE step */
110
+ scratch .opcode = EEOP_DONE ;
111
+ ExprEvalPushStep (state , & scratch );
112
+
113
+ ExecReadyExpr (state );
114
+
115
+ return state ;
116
+ }
117
+
84
118
/*
85
119
* ExecInitExpr: prepare an expression tree for execution
86
120
*
@@ -119,32 +153,7 @@ static void ExecBuildAggTransCall(ExprState *state, AggState *aggstate,
119
153
ExprState *
120
154
ExecInitExpr (Expr * node , PlanState * parent )
121
155
{
122
- ExprState * state ;
123
- ExprEvalStep scratch = {0 };
124
-
125
- /* Special case: NULL expression produces a NULL ExprState pointer */
126
- if (node == NULL )
127
- return NULL ;
128
-
129
- /* Initialize ExprState with empty step list */
130
- state = makeNode (ExprState );
131
- state -> expr = node ;
132
- state -> parent = parent ;
133
- state -> ext_params = NULL ;
134
-
135
- /* Insert EEOP_*_FETCHSOME steps as needed */
136
- ExecInitExprSlots (state , (Node * ) node );
137
-
138
- /* Compile the expression proper */
139
- ExecInitExprRec (node , state , & state -> resvalue , & state -> resnull );
140
-
141
- /* Finally, append a DONE step */
142
- scratch .opcode = EEOP_DONE ;
143
- ExprEvalPushStep (state , & scratch );
144
-
145
- ExecReadyExpr (state );
146
-
147
- return state ;
156
+ return ExecInitExprInternal (node , parent , NULL , NULL , NULL );
148
157
}
149
158
150
159
/*
@@ -156,32 +165,20 @@ ExecInitExpr(Expr *node, PlanState *parent)
156
165
ExprState *
157
166
ExecInitExprWithParams (Expr * node , ParamListInfo ext_params )
158
167
{
159
- ExprState * state ;
160
- ExprEvalStep scratch = {0 };
161
-
162
- /* Special case: NULL expression produces a NULL ExprState pointer */
163
- if (node == NULL )
164
- return NULL ;
165
-
166
- /* Initialize ExprState with empty step list */
167
- state = makeNode (ExprState );
168
- state -> expr = node ;
169
- state -> parent = NULL ;
170
- state -> ext_params = ext_params ;
171
-
172
- /* Insert EEOP_*_FETCHSOME steps as needed */
173
- ExecInitExprSlots (state , (Node * ) node );
174
-
175
- /* Compile the expression proper */
176
- ExecInitExprRec (node , state , & state -> resvalue , & state -> resnull );
177
-
178
- /* Finally, append a DONE step */
179
- scratch .opcode = EEOP_DONE ;
180
- ExprEvalPushStep (state , & scratch );
181
-
182
- ExecReadyExpr (state );
168
+ return ExecInitExprInternal (node , NULL , ext_params , NULL , NULL );
169
+ }
183
170
184
- return state ;
171
+ /*
172
+ * ExecInitExprWithCaseValue: prepare an expression tree for execution
173
+ *
174
+ * This is the same as ExecInitExpr, except that a pointer to the value for
175
+ * CasTestExpr is passed here.
176
+ */
177
+ ExprState *
178
+ ExecInitExprWithCaseValue (Expr * node , PlanState * parent ,
179
+ Datum * caseval , bool * casenull )
180
+ {
181
+ return ExecInitExprInternal (node , parent , NULL , caseval , casenull );
185
182
}
186
183
187
184
/*
@@ -2129,7 +2126,7 @@ ExecInitExprRec(Expr *node, ExprState *state,
2129
2126
scratch .d .jsonexpr .jsexpr = jexpr ;
2130
2127
2131
2128
scratch .d .jsonexpr .raw_expr =
2132
- palloc (sizeof (* scratch .d .jsonexpr .raw_expr ));
2129
+ palloc (sizeof (* scratch .d .jsonexpr .raw_expr ));
2133
2130
2134
2131
ExecInitExprRec ((Expr * ) jexpr -> raw_expr , state ,
2135
2132
& scratch .d .jsonexpr .raw_expr -> value ,
@@ -2143,12 +2140,20 @@ ExecInitExprRec(Expr *node, ExprState *state,
2143
2140
& scratch .d .jsonexpr .pathspec -> isnull );
2144
2141
2145
2142
scratch .d .jsonexpr .formatted_expr =
2146
- ExecInitExpr ((Expr * ) jexpr -> formatted_expr ,
2147
- state -> parent );
2143
+ ExecInitExprWithCaseValue ((Expr * ) jexpr -> formatted_expr ,
2144
+ state -> parent ,
2145
+ & scratch .d .jsonexpr .raw_expr -> value ,
2146
+ & scratch .d .jsonexpr .raw_expr -> isnull );
2147
+
2148
+ scratch .d .jsonexpr .res_expr =
2149
+ palloc (sizeof (* scratch .d .jsonexpr .res_expr ));
2150
+
2148
2151
2149
2152
scratch .d .jsonexpr .result_expr = jexpr -> result_coercion
2150
- ? ExecInitExpr ((Expr * ) jexpr -> result_coercion -> expr ,
2151
- state -> parent )
2153
+ ? ExecInitExprWithCaseValue ((Expr * ) jexpr -> result_coercion -> expr ,
2154
+ state -> parent ,
2155
+ & scratch .d .jsonexpr .res_expr -> value ,
2156
+ & scratch .d .jsonexpr .res_expr -> isnull )
2152
2157
: NULL ;
2153
2158
2154
2159
scratch .d .jsonexpr .default_on_empty =
@@ -2200,6 +2205,14 @@ ExecInitExprRec(Expr *node, ExprState *state,
2200
2205
{
2201
2206
JsonCoercion * * coercion ;
2202
2207
struct JsonCoercionState * cstate ;
2208
+ Datum * caseval ;
2209
+ bool * casenull ;
2210
+
2211
+ scratch .d .jsonexpr .coercion_expr =
2212
+ palloc (sizeof (* scratch .d .jsonexpr .coercion_expr ));
2213
+
2214
+ caseval = & scratch .d .jsonexpr .coercion_expr -> value ;
2215
+ casenull = & scratch .d .jsonexpr .coercion_expr -> isnull ;
2203
2216
2204
2217
for (cstate = & scratch .d .jsonexpr .coercions .null ,
2205
2218
coercion = & jexpr -> coercions -> null ;
@@ -2208,8 +2221,9 @@ ExecInitExprRec(Expr *node, ExprState *state,
2208
2221
{
2209
2222
cstate -> coercion = * coercion ;
2210
2223
cstate -> estate = * coercion ?
2211
- ExecInitExpr ((Expr * )(* coercion )-> expr ,
2212
- state -> parent ) : NULL ;
2224
+ ExecInitExprWithCaseValue ((Expr * )(* coercion )-> expr ,
2225
+ state -> parent ,
2226
+ caseval , casenull ) : NULL ;
2213
2227
}
2214
2228
}
2215
2229
0 commit comments