@@ -160,6 +160,12 @@ static Datum ExecJustAssignOuterVar(ExprState *state, ExprContext *econtext, boo
160
160
static Datum ExecJustAssignScanVar (ExprState * state , ExprContext * econtext , bool * isnull );
161
161
static Datum ExecJustApplyFuncToCase (ExprState * state , ExprContext * econtext , bool * isnull );
162
162
static Datum ExecJustConst (ExprState * state , ExprContext * econtext , bool * isnull );
163
+ static Datum ExecJustInnerVarVirt (ExprState * state , ExprContext * econtext , bool * isnull );
164
+ static Datum ExecJustOuterVarVirt (ExprState * state , ExprContext * econtext , bool * isnull );
165
+ static Datum ExecJustScanVarVirt (ExprState * state , ExprContext * econtext , bool * isnull );
166
+ static Datum ExecJustAssignInnerVarVirt (ExprState * state , ExprContext * econtext , bool * isnull );
167
+ static Datum ExecJustAssignOuterVarVirt (ExprState * state , ExprContext * econtext , bool * isnull );
168
+ static Datum ExecJustAssignScanVarVirt (ExprState * state , ExprContext * econtext , bool * isnull );
163
169
164
170
165
171
/*
@@ -255,11 +261,45 @@ ExecReadyInterpretedExpr(ExprState *state)
255
261
return ;
256
262
}
257
263
}
258
- else if (state -> steps_len == 2 &&
259
- state -> steps [0 ].opcode == EEOP_CONST )
264
+ else if (state -> steps_len == 2 )
260
265
{
261
- state -> evalfunc_private = (void * ) ExecJustConst ;
262
- return ;
266
+ ExprEvalOp step0 = state -> steps [0 ].opcode ;
267
+
268
+ if (step0 == EEOP_CONST )
269
+ {
270
+ state -> evalfunc_private = (void * ) ExecJustConst ;
271
+ return ;
272
+ }
273
+ else if (step0 == EEOP_INNER_VAR )
274
+ {
275
+ state -> evalfunc_private = (void * ) ExecJustInnerVarVirt ;
276
+ return ;
277
+ }
278
+ else if (step0 == EEOP_OUTER_VAR )
279
+ {
280
+ state -> evalfunc_private = (void * ) ExecJustOuterVarVirt ;
281
+ return ;
282
+ }
283
+ else if (step0 == EEOP_SCAN_VAR )
284
+ {
285
+ state -> evalfunc_private = (void * ) ExecJustScanVarVirt ;
286
+ return ;
287
+ }
288
+ else if (step0 == EEOP_ASSIGN_INNER_VAR )
289
+ {
290
+ state -> evalfunc_private = (void * ) ExecJustAssignInnerVarVirt ;
291
+ return ;
292
+ }
293
+ else if (step0 == EEOP_ASSIGN_OUTER_VAR )
294
+ {
295
+ state -> evalfunc_private = (void * ) ExecJustAssignOuterVarVirt ;
296
+ return ;
297
+ }
298
+ else if (step0 == EEOP_ASSIGN_SCAN_VAR )
299
+ {
300
+ state -> evalfunc_private = (void * ) ExecJustAssignScanVarVirt ;
301
+ return ;
302
+ }
263
303
}
264
304
265
305
#if defined(EEO_USE_COMPUTED_GOTO )
@@ -2096,6 +2136,91 @@ ExecJustConst(ExprState *state, ExprContext *econtext, bool *isnull)
2096
2136
return op -> d .constval .value ;
2097
2137
}
2098
2138
2139
+ /* implementation of ExecJust(Inner|Outer|Scan)VarVirt */
2140
+ static pg_attribute_always_inline Datum
2141
+ ExecJustVarVirtImpl (ExprState * state , TupleTableSlot * slot , bool * isnull )
2142
+ {
2143
+ ExprEvalStep * op = & state -> steps [0 ];
2144
+ int attnum = op -> d .var .attnum ;
2145
+
2146
+ /*
2147
+ * As it is guaranteed that a virtual slot is used, there never is a need
2148
+ * to perform tuple deforming (nor would it be possible). Therefore
2149
+ * execExpr.c has not emitted an EEOP_*_FETCHSOME step. Verify, as much as
2150
+ * possible, that that determination was accurate.
2151
+ */
2152
+ Assert (TTS_IS_VIRTUAL (slot ));
2153
+ Assert (TTS_FIXED (slot ));
2154
+ Assert (attnum >= 0 && attnum < slot -> tts_nvalid );
2155
+
2156
+ * isnull = slot -> tts_isnull [attnum ];
2157
+
2158
+ return slot -> tts_values [attnum ];
2159
+ }
2160
+
2161
+ /* Like ExecJustInnerVar, optimized for virtual slots */
2162
+ static Datum
2163
+ ExecJustInnerVarVirt (ExprState * state , ExprContext * econtext , bool * isnull )
2164
+ {
2165
+ return ExecJustVarVirtImpl (state , econtext -> ecxt_innertuple , isnull );
2166
+ }
2167
+
2168
+ /* Like ExecJustOuterVar, optimized for virtual slots */
2169
+ static Datum
2170
+ ExecJustOuterVarVirt (ExprState * state , ExprContext * econtext , bool * isnull )
2171
+ {
2172
+ return ExecJustVarVirtImpl (state , econtext -> ecxt_outertuple , isnull );
2173
+ }
2174
+
2175
+ /* Like ExecJustScanVar, optimized for virtual slots */
2176
+ static Datum
2177
+ ExecJustScanVarVirt (ExprState * state , ExprContext * econtext , bool * isnull )
2178
+ {
2179
+ return ExecJustVarVirtImpl (state , econtext -> ecxt_scantuple , isnull );
2180
+ }
2181
+
2182
+ /* implementation of ExecJustAssign(Inner|Outer|Scan)VarVirt */
2183
+ static pg_attribute_always_inline Datum
2184
+ ExecJustAssignVarVirtImpl (ExprState * state , TupleTableSlot * inslot , bool * isnull )
2185
+ {
2186
+ ExprEvalStep * op = & state -> steps [0 ];
2187
+ int attnum = op -> d .assign_var .attnum ;
2188
+ int resultnum = op -> d .assign_var .resultnum ;
2189
+ TupleTableSlot * outslot = state -> resultslot ;
2190
+
2191
+ /* see ExecJustVarVirtImpl for comments */
2192
+
2193
+ Assert (TTS_IS_VIRTUAL (inslot ));
2194
+ Assert (TTS_FIXED (inslot ));
2195
+ Assert (attnum >= 0 && attnum < inslot -> tts_nvalid );
2196
+
2197
+ outslot -> tts_values [resultnum ] = inslot -> tts_values [attnum ];
2198
+ outslot -> tts_isnull [resultnum ] = inslot -> tts_isnull [attnum ];
2199
+
2200
+ return 0 ;
2201
+ }
2202
+
2203
+ /* Like ExecJustAssignInnerVar, optimized for virtual slots */
2204
+ static Datum
2205
+ ExecJustAssignInnerVarVirt (ExprState * state , ExprContext * econtext , bool * isnull )
2206
+ {
2207
+ return ExecJustAssignVarVirtImpl (state , econtext -> ecxt_innertuple , isnull );
2208
+ }
2209
+
2210
+ /* Like ExecJustAssignOuterVar, optimized for virtual slots */
2211
+ static Datum
2212
+ ExecJustAssignOuterVarVirt (ExprState * state , ExprContext * econtext , bool * isnull )
2213
+ {
2214
+ return ExecJustAssignVarVirtImpl (state , econtext -> ecxt_outertuple , isnull );
2215
+ }
2216
+
2217
+ /* Like ExecJustAssignScanVar, optimized for virtual slots */
2218
+ static Datum
2219
+ ExecJustAssignScanVarVirt (ExprState * state , ExprContext * econtext , bool * isnull )
2220
+ {
2221
+ return ExecJustAssignVarVirtImpl (state , econtext -> ecxt_scantuple , isnull );
2222
+ }
2223
+
2099
2224
#if defined(EEO_USE_COMPUTED_GOTO )
2100
2225
/*
2101
2226
* Comparator used when building address->opcode lookup table for
0 commit comments