8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.243 2009/03/27 18:30:21 tgl Exp $
11
+ * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.244 2009/04/02 22:39:29 tgl Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -4966,6 +4966,7 @@ ExecCleanTargetListLength(List *targetlist)
4966
4966
* prepared to deal with sets of result tuples. Otherwise, a return
4967
4967
* of *isDone = ExprMultipleResult signifies a set element, and a return
4968
4968
* of *isDone = ExprEndResult signifies end of the set of tuple.
4969
+ * We assume that *isDone has been initialized to ExprSingleResult by caller.
4969
4970
*/
4970
4971
static bool
4971
4972
ExecTargetList (List * targetlist ,
@@ -4987,9 +4988,6 @@ ExecTargetList(List *targetlist,
4987
4988
/*
4988
4989
* evaluate all the expressions in the target list
4989
4990
*/
4990
- if (isDone )
4991
- * isDone = ExprSingleResult ; /* until proven otherwise */
4992
-
4993
4991
haveDoneSets = false; /* any exhausted set exprs in tlist? */
4994
4992
4995
4993
foreach (tl , targetlist )
@@ -5104,50 +5102,6 @@ ExecTargetList(List *targetlist,
5104
5102
return true;
5105
5103
}
5106
5104
5107
- /*
5108
- * ExecVariableList
5109
- * Evaluates a simple-Variable-list projection.
5110
- *
5111
- * Results are stored into the passed values and isnull arrays.
5112
- */
5113
- static void
5114
- ExecVariableList (ProjectionInfo * projInfo ,
5115
- Datum * values ,
5116
- bool * isnull )
5117
- {
5118
- ExprContext * econtext = projInfo -> pi_exprContext ;
5119
- int * varSlotOffsets = projInfo -> pi_varSlotOffsets ;
5120
- int * varNumbers = projInfo -> pi_varNumbers ;
5121
- int i ;
5122
-
5123
- /*
5124
- * Force extraction of all input values that we need.
5125
- */
5126
- if (projInfo -> pi_lastInnerVar > 0 )
5127
- slot_getsomeattrs (econtext -> ecxt_innertuple ,
5128
- projInfo -> pi_lastInnerVar );
5129
- if (projInfo -> pi_lastOuterVar > 0 )
5130
- slot_getsomeattrs (econtext -> ecxt_outertuple ,
5131
- projInfo -> pi_lastOuterVar );
5132
- if (projInfo -> pi_lastScanVar > 0 )
5133
- slot_getsomeattrs (econtext -> ecxt_scantuple ,
5134
- projInfo -> pi_lastScanVar );
5135
-
5136
- /*
5137
- * Assign to result by direct extraction of fields from source slots ... a
5138
- * mite ugly, but fast ...
5139
- */
5140
- for (i = list_length (projInfo -> pi_targetlist ) - 1 ; i >= 0 ; i -- )
5141
- {
5142
- char * slotptr = ((char * ) econtext ) + varSlotOffsets [i ];
5143
- TupleTableSlot * varSlot = * ((TupleTableSlot * * ) slotptr );
5144
- int varNumber = varNumbers [i ] - 1 ;
5145
-
5146
- values [i ] = varSlot -> tts_values [varNumber ];
5147
- isnull [i ] = varSlot -> tts_isnull [varNumber ];
5148
- }
5149
- }
5150
-
5151
5105
/*
5152
5106
* ExecProject
5153
5107
*
@@ -5165,6 +5119,8 @@ TupleTableSlot *
5165
5119
ExecProject (ProjectionInfo * projInfo , ExprDoneCond * isDone )
5166
5120
{
5167
5121
TupleTableSlot * slot ;
5122
+ ExprContext * econtext ;
5123
+ int numSimpleVars ;
5168
5124
5169
5125
/*
5170
5126
* sanity checks
@@ -5175,6 +5131,11 @@ ExecProject(ProjectionInfo *projInfo, ExprDoneCond *isDone)
5175
5131
* get the projection info we want
5176
5132
*/
5177
5133
slot = projInfo -> pi_slot ;
5134
+ econtext = projInfo -> pi_exprContext ;
5135
+
5136
+ /* Assume single result row until proven otherwise */
5137
+ if (isDone )
5138
+ * isDone = ExprSingleResult ;
5178
5139
5179
5140
/*
5180
5141
* Clear any former contents of the result slot. This makes it safe for
@@ -5184,29 +5145,84 @@ ExecProject(ProjectionInfo *projInfo, ExprDoneCond *isDone)
5184
5145
ExecClearTuple (slot );
5185
5146
5186
5147
/*
5187
- * form a new result tuple (if possible); if successful, mark the result
5188
- * slot as containing a valid virtual tuple
5148
+ * Force extraction of all input values that we'll need. The
5149
+ * Var-extraction loops below depend on this, and we are also prefetching
5150
+ * all attributes that will be referenced in the generic expressions.
5151
+ */
5152
+ if (projInfo -> pi_lastInnerVar > 0 )
5153
+ slot_getsomeattrs (econtext -> ecxt_innertuple ,
5154
+ projInfo -> pi_lastInnerVar );
5155
+ if (projInfo -> pi_lastOuterVar > 0 )
5156
+ slot_getsomeattrs (econtext -> ecxt_outertuple ,
5157
+ projInfo -> pi_lastOuterVar );
5158
+ if (projInfo -> pi_lastScanVar > 0 )
5159
+ slot_getsomeattrs (econtext -> ecxt_scantuple ,
5160
+ projInfo -> pi_lastScanVar );
5161
+
5162
+ /*
5163
+ * Assign simple Vars to result by direct extraction of fields from source
5164
+ * slots ... a mite ugly, but fast ...
5189
5165
*/
5190
- if (projInfo -> pi_isVarList )
5166
+ numSimpleVars = projInfo -> pi_numSimpleVars ;
5167
+ if (numSimpleVars > 0 )
5191
5168
{
5192
- /* simple Var list: this always succeeds with one result row */
5193
- if (isDone )
5194
- * isDone = ExprSingleResult ;
5195
- ExecVariableList (projInfo ,
5196
- slot -> tts_values ,
5197
- slot -> tts_isnull );
5198
- ExecStoreVirtualTuple (slot );
5169
+ Datum * values = slot -> tts_values ;
5170
+ bool * isnull = slot -> tts_isnull ;
5171
+ int * varSlotOffsets = projInfo -> pi_varSlotOffsets ;
5172
+ int * varNumbers = projInfo -> pi_varNumbers ;
5173
+ int i ;
5174
+
5175
+ if (projInfo -> pi_directMap )
5176
+ {
5177
+ /* especially simple case where vars go to output in order */
5178
+ for (i = 0 ; i < numSimpleVars ; i ++ )
5179
+ {
5180
+ char * slotptr = ((char * ) econtext ) + varSlotOffsets [i ];
5181
+ TupleTableSlot * varSlot = * ((TupleTableSlot * * ) slotptr );
5182
+ int varNumber = varNumbers [i ] - 1 ;
5183
+
5184
+ values [i ] = varSlot -> tts_values [varNumber ];
5185
+ isnull [i ] = varSlot -> tts_isnull [varNumber ];
5186
+ }
5187
+ }
5188
+ else
5189
+ {
5190
+ /* we have to pay attention to varOutputCols[] */
5191
+ int * varOutputCols = projInfo -> pi_varOutputCols ;
5192
+
5193
+ for (i = 0 ; i < numSimpleVars ; i ++ )
5194
+ {
5195
+ char * slotptr = ((char * ) econtext ) + varSlotOffsets [i ];
5196
+ TupleTableSlot * varSlot = * ((TupleTableSlot * * ) slotptr );
5197
+ int varNumber = varNumbers [i ] - 1 ;
5198
+ int varOutputCol = varOutputCols [i ] - 1 ;
5199
+
5200
+ values [varOutputCol ] = varSlot -> tts_values [varNumber ];
5201
+ isnull [varOutputCol ] = varSlot -> tts_isnull [varNumber ];
5202
+ }
5203
+ }
5199
5204
}
5200
- else
5205
+
5206
+ /*
5207
+ * If there are any generic expressions, evaluate them. It's possible
5208
+ * that there are set-returning functions in such expressions; if so
5209
+ * and we have reached the end of the set, we return the result slot,
5210
+ * which we already marked empty.
5211
+ */
5212
+ if (projInfo -> pi_targetlist )
5201
5213
{
5202
- if (ExecTargetList (projInfo -> pi_targetlist ,
5203
- projInfo -> pi_exprContext ,
5204
- slot -> tts_values ,
5205
- slot -> tts_isnull ,
5206
- projInfo -> pi_itemIsDone ,
5207
- isDone ))
5208
- ExecStoreVirtualTuple ( slot );
5214
+ if (! ExecTargetList (projInfo -> pi_targetlist ,
5215
+ econtext ,
5216
+ slot -> tts_values ,
5217
+ slot -> tts_isnull ,
5218
+ projInfo -> pi_itemIsDone ,
5219
+ isDone ))
5220
+ return slot ; /* no more result rows, return empty slot */
5209
5221
}
5210
5222
5211
- return slot ;
5223
+ /*
5224
+ * Successfully formed a result row. Mark the result slot as containing a
5225
+ * valid virtual tuple.
5226
+ */
5227
+ return ExecStoreVirtualTuple (slot );
5212
5228
}
0 commit comments