88 *
99 *
1010 * 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 $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
3939 * calls to ExecMaterial return successive tuples from the temp
4040 * relation.
4141 *
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- *
4842 * ----------------------------------------------------------------
4943 */
5044TupleTableSlot * /* result tuple from subplan */
@@ -78,25 +72,54 @@ ExecMaterial(Material *node)
7872
7973 if (matstate -> mat_Flag == false)
8074 {
75+ TupleDesc tupType ;
76+
8177 /* ----------------
82- * set all relations to be scanned in the forward direction
83- * while creating the temporary relation.
78+ * get type information needed for ExecCreatR
8479 * ----------------
8580 */
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_ );
8797
8898 /* ----------------
8999 * if we couldn't create the temp relation then
90100 * we print a warning and return NULL.
91101 * ----------------
92102 */
93- tempRelation = matstate -> mat_TempRelation ;
94103 if (tempRelation == NULL )
95104 {
96105 elog (DEBUG , "ExecMaterial: temp relation is NULL! aborting..." );
97106 return NULL ;
98107 }
99108
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+
100123 /* ----------------
101124 * retrieve tuples from the subplan and
102125 * insert them in the temporary relation
@@ -135,9 +158,6 @@ ExecMaterial(Material *node)
135158 matstate -> csstate .css_currentRelation = currentRelation ;
136159 matstate -> csstate .css_currentScanDesc = currentScanDesc ;
137160
138- ExecAssignScanType (& matstate -> csstate ,
139- RelationGetDescr (currentRelation ));
140-
141161 /* ----------------
142162 * finally set the sorted flag to true
143163 * ----------------
@@ -178,10 +198,6 @@ ExecInitMaterial(Material *node, EState *estate, Plan *parent)
178198{
179199 MaterialState * matstate ;
180200 Plan * outerPlan ;
181- TupleDesc tupType ;
182- Relation tempDesc ;
183-
184- /* int len; */
185201
186202 /* ----------------
187203 * assign the node's execution state
@@ -225,12 +241,6 @@ ExecInitMaterial(Material *node, EState *estate, Plan *parent)
225241 outerPlan = outerPlan ((Plan * ) node );
226242 ExecInitNode (outerPlan , estate , (Plan * ) node );
227243
228- /* ----------------
229- * initialize matstate information
230- * ----------------
231- */
232- matstate -> mat_Flag = false;
233-
234244 /* ----------------
235245 * initialize tuple type. no need to initialize projection
236246 * info because this node doesn't do projections.
@@ -239,39 +249,6 @@ ExecInitMaterial(Material *node, EState *estate, Plan *parent)
239249 ExecAssignScanTypeFromOuterPlan ((Plan * ) node , & matstate -> csstate );
240250 matstate -> csstate .cstate .cs_ProjInfo = NULL ;
241251
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- */
275252 return TRUE;
276253}
277254
@@ -343,13 +320,39 @@ ExecMaterialReScan(Material *node, ExprContext *exprCtxt, Plan *parent)
343320{
344321 MaterialState * matstate = node -> matstate ;
345322
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+ */
346328 if (matstate -> mat_Flag == false)
347329 return ;
348330
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+ }
353356}
354357
355358/* ----------------------------------------------------------------
0 commit comments