Skip to content

Commit c3bbbb1

Browse files
committed
Back-patch nodeMaterial to honor chgParam by recomputing its output.
1 parent 201d35d commit c3bbbb1

File tree

1 file changed

+64
-61
lines changed

1 file changed

+64
-61
lines changed

src/backend/executor/nodeMaterial.c

Lines changed: 64 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
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
*/
@@ -39,12 +39,6 @@
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
*/
5044
TupleTableSlot * /* 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

Comments
 (0)