8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeMaterial.c,v 1.30.2.1 2000/09/08 02:11:32 tgl Exp $
11
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeMaterial.c,v 1.30.2.2 2000/10/06 01:28:47 tgl Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
39
39
*calls to ExecMaterial return successive tuples from the temp
40
40
*relation.
41
41
*
42
- *Initial State:
43
- *
44
- *ExecMaterial assumes the temporary relation has been
45
- *created and opened by ExecInitMaterial during the prior
46
- *InitPlan() phase.
47
- *
48
42
* ----------------------------------------------------------------
49
43
*/
50
44
TupleTableSlot * /* result tuple from subplan */
@@ -78,25 +72,54 @@ ExecMaterial(Material *node)
78
72
79
73
if (matstate -> mat_Flag == false)
80
74
{
75
+ TupleDesc tupType ;
76
+
81
77
/* ----------------
82
- *set all relations to be scanned in the forward direction
83
- *while creating the temporary relation.
78
+ *get type information needed for ExecCreatR
84
79
* ----------------
85
80
*/
86
- estate -> es_direction = ForwardScanDirection ;
81
+ tupType = ExecGetScanType (& matstate -> csstate );
82
+
83
+ /* ----------------
84
+ *ExecCreatR wants its second argument to be an object id of
85
+ *a relation in the range table or a _NONAME_RELATION_ID
86
+ *indicating that the relation is not in the range table.
87
+ *
88
+ *In the second case ExecCreatR creates a temp relation.
89
+ *(currently this is the only case we support -cim 10/16/89)
90
+ * ----------------
91
+ */
92
+ /* ----------------
93
+ *create the temporary relation
94
+ * ----------------
95
+ */
96
+ tempRelation = ExecCreatR (tupType ,_NONAME_RELATION_ID_ );
87
97
88
98
/* ----------------
89
99
* if we couldn't create the temp relation then
90
100
* we print a warning and return NULL.
91
101
* ----------------
92
102
*/
93
- tempRelation = matstate -> mat_TempRelation ;
94
103
if (tempRelation == NULL )
95
104
{
96
105
elog (DEBUG ,"ExecMaterial: temp relation is NULL! aborting..." );
97
106
return NULL ;
98
107
}
99
108
109
+ /* ----------------
110
+ *save the relation descriptor in the sortstate
111
+ * ----------------
112
+ */
113
+ matstate -> mat_TempRelation = tempRelation ;
114
+ matstate -> csstate .css_currentRelation = NULL ;
115
+
116
+ /* ----------------
117
+ *set all relations to be scanned in the forward direction
118
+ *while creating the temporary relation.
119
+ * ----------------
120
+ */
121
+ estate -> es_direction = ForwardScanDirection ;
122
+
100
123
/* ----------------
101
124
* retrieve tuples from the subplan and
102
125
* insert them in the temporary relation
@@ -135,9 +158,6 @@ ExecMaterial(Material *node)
135
158
matstate -> csstate .css_currentRelation = currentRelation ;
136
159
matstate -> csstate .css_currentScanDesc = currentScanDesc ;
137
160
138
- ExecAssignScanType (& matstate -> csstate ,
139
- RelationGetDescr (currentRelation ));
140
-
141
161
/* ----------------
142
162
*finally set the sorted flag to true
143
163
* ----------------
@@ -178,10 +198,6 @@ ExecInitMaterial(Material *node, EState *estate, Plan *parent)
178
198
{
179
199
MaterialState * matstate ;
180
200
Plan * outerPlan ;
181
- TupleDesc tupType ;
182
- Relation tempDesc ;
183
-
184
- /* intlen; */
185
201
186
202
/* ----------------
187
203
*assign the node's execution state
@@ -225,12 +241,6 @@ ExecInitMaterial(Material *node, EState *estate, Plan *parent)
225
241
outerPlan = outerPlan ((Plan * )node );
226
242
ExecInitNode (outerPlan ,estate , (Plan * )node );
227
243
228
- /* ----------------
229
- *initialize matstate information
230
- * ----------------
231
- */
232
- matstate -> mat_Flag = false;
233
-
234
244
/* ----------------
235
245
*initialize tuple type.no need to initialize projection
236
246
*info because this node doesn't do projections.
@@ -239,39 +249,6 @@ ExecInitMaterial(Material *node, EState *estate, Plan *parent)
239
249
ExecAssignScanTypeFromOuterPlan ((Plan * )node ,& matstate -> csstate );
240
250
matstate -> csstate .cstate .cs_ProjInfo = NULL ;
241
251
242
- /* ----------------
243
- *get type information needed for ExecCreatR
244
- * ----------------
245
- */
246
- tupType = ExecGetScanType (& matstate -> csstate );
247
-
248
- /* ----------------
249
- *ExecCreatR wants its second argument to be an object id of
250
- *a relation in the range table or a _NONAME_RELATION_ID
251
- *indicating that the relation is not in the range table.
252
- *
253
- *In the second case ExecCreatR creates a temp relation.
254
- *(currently this is the only case we support -cim 10/16/89)
255
- * ----------------
256
- */
257
- /* ----------------
258
- *create the temporary relation
259
- * ----------------
260
- */
261
- tempDesc = ExecCreatR (tupType ,_NONAME_RELATION_ID_ );
262
-
263
- /* ----------------
264
- *save the relation descriptor in the sortstate
265
- * ----------------
266
- */
267
- matstate -> mat_TempRelation = tempDesc ;
268
- matstate -> csstate .css_currentRelation = NULL ;
269
-
270
- /* ----------------
271
- *return relation oid of temporary relation in a list
272
- *(someday -- for now we return LispTrue... cim 10/12/89)
273
- * ----------------
274
- */
275
252
return TRUE;
276
253
}
277
254
@@ -343,13 +320,39 @@ ExecMaterialReScan(Material *node, ExprContext *exprCtxt, Plan *parent)
343
320
{
344
321
MaterialState * matstate = node -> matstate ;
345
322
323
+ /*
324
+ * If we haven't materialized yet, just return. If outerplan' chgParam is
325
+ * not NULL then it will be re-scanned by ExecProcNode, else - no
326
+ * reason to re-scan it at all.
327
+ */
346
328
if (matstate -> mat_Flag == false)
347
329
return ;
348
330
349
- matstate -> csstate .css_currentScanDesc = ExecReScanR (matstate -> csstate .css_currentRelation ,
350
- matstate -> csstate .css_currentScanDesc ,
351
- node -> plan .state -> es_direction ,0 ,NULL );
352
-
331
+ /*
332
+ * If subnode is to be rescanned then we forget previous stored results;
333
+ * we have to re-read the subplan and re-store.
334
+ *
335
+ * Otherwise we can just rewind and rescan the stored output.
336
+ */
337
+ if (((Plan * )node )-> lefttree -> chgParam != NULL )
338
+ {
339
+ Relation tempRelation = matstate -> mat_TempRelation ;
340
+
341
+ matstate -> csstate .css_currentRelation = NULL ;
342
+ ExecCloseR ((Plan * )node );
343
+ ExecClearTuple (matstate -> csstate .css_ScanTupleSlot );
344
+ if (tempRelation != NULL )
345
+ heap_drop (tempRelation );
346
+ matstate -> mat_TempRelation = NULL ;
347
+ matstate -> mat_Flag = false;
348
+ }
349
+ else
350
+ {
351
+ matstate -> csstate .css_currentScanDesc =
352
+ ExecReScanR (matstate -> csstate .css_currentRelation ,
353
+ matstate -> csstate .css_currentScanDesc ,
354
+ node -> plan .state -> es_direction ,0 ,NULL );
355
+ }
353
356
}
354
357
355
358
/* ----------------------------------------------------------------