summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2000-10-06 01:28:47 +0000
committerTom Lane2000-10-06 01:28:47 +0000
commitc3bbbb1dcc2356a94409af71e9a85925e86d873c (patch)
tree40ee7aac0c96d5687788bd690334cb7af05d16a3
parent201d35d47fb2fcda413a54c5c2889f9123e9fa33 (diff)
Back-patch nodeMaterial to honor chgParam by recomputing its output.
-rw-r--r--src/backend/executor/nodeMaterial.c125
1 files changed, 64 insertions, 61 deletions
diff --git a/src/backend/executor/nodeMaterial.c b/src/backend/executor/nodeMaterial.c
index 4f67892682b..bbe4fad4e50 100644
--- a/src/backend/executor/nodeMaterial.c
+++ b/src/backend/executor/nodeMaterial.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeMaterial.c,v 1.30.2.1 2000/09/08 02:11:32 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeMaterial.c,v 1.30.2.2 2000/10/06 01:28:47 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -39,12 +39,6 @@
* calls to ExecMaterial return successive tuples from the temp
* relation.
*
- * Initial State:
- *
- * ExecMaterial assumes the temporary relation has been
- * created and opened by ExecInitMaterial during the prior
- * InitPlan() phase.
- *
* ----------------------------------------------------------------
*/
TupleTableSlot * /* result tuple from subplan */
@@ -78,19 +72,34 @@ ExecMaterial(Material *node)
if (matstate->mat_Flag == false)
{
+ TupleDesc tupType;
+
/* ----------------
- * set all relations to be scanned in the forward direction
- * while creating the temporary relation.
+ * get type information needed for ExecCreatR
* ----------------
*/
- estate->es_direction = ForwardScanDirection;
+ tupType = ExecGetScanType(&matstate->csstate);
+
+ /* ----------------
+ * ExecCreatR wants its second argument to be an object id of
+ * a relation in the range table or a _NONAME_RELATION_ID
+ * indicating that the relation is not in the range table.
+ *
+ * In the second case ExecCreatR creates a temp relation.
+ * (currently this is the only case we support -cim 10/16/89)
+ * ----------------
+ */
+ /* ----------------
+ * create the temporary relation
+ * ----------------
+ */
+ tempRelation = ExecCreatR(tupType, _NONAME_RELATION_ID_);
/* ----------------
* if we couldn't create the temp relation then
* we print a warning and return NULL.
* ----------------
*/
- tempRelation = matstate->mat_TempRelation;
if (tempRelation == NULL)
{
elog(DEBUG, "ExecMaterial: temp relation is NULL! aborting...");
@@ -98,6 +107,20 @@ ExecMaterial(Material *node)
}
/* ----------------
+ * save the relation descriptor in the sortstate
+ * ----------------
+ */
+ matstate->mat_TempRelation = tempRelation;
+ matstate->csstate.css_currentRelation = NULL;
+
+ /* ----------------
+ * set all relations to be scanned in the forward direction
+ * while creating the temporary relation.
+ * ----------------
+ */
+ estate->es_direction = ForwardScanDirection;
+
+ /* ----------------
* retrieve tuples from the subplan and
* insert them in the temporary relation
* ----------------
@@ -135,9 +158,6 @@ ExecMaterial(Material *node)
matstate->csstate.css_currentRelation = currentRelation;
matstate->csstate.css_currentScanDesc = currentScanDesc;
- ExecAssignScanType(&matstate->csstate,
- RelationGetDescr(currentRelation));
-
/* ----------------
* finally set the sorted flag to true
* ----------------
@@ -178,10 +198,6 @@ ExecInitMaterial(Material *node, EState *estate, Plan *parent)
{
MaterialState *matstate;
Plan *outerPlan;
- TupleDesc tupType;
- Relation tempDesc;
-
- /* int len; */
/* ----------------
* assign the node's execution state
@@ -226,12 +242,6 @@ ExecInitMaterial(Material *node, EState *estate, Plan *parent)
ExecInitNode(outerPlan, estate, (Plan *) node);
/* ----------------
- * initialize matstate information
- * ----------------
- */
- matstate->mat_Flag = false;
-
- /* ----------------
* initialize tuple type. no need to initialize projection
* info because this node doesn't do projections.
* ----------------
@@ -239,39 +249,6 @@ ExecInitMaterial(Material *node, EState *estate, Plan *parent)
ExecAssignScanTypeFromOuterPlan((Plan *) node, &matstate->csstate);
matstate->csstate.cstate.cs_ProjInfo = NULL;
- /* ----------------
- * get type information needed for ExecCreatR
- * ----------------
- */
- tupType = ExecGetScanType(&matstate->csstate);
-
- /* ----------------
- * ExecCreatR wants its second argument to be an object id of
- * a relation in the range table or a _NONAME_RELATION_ID
- * indicating that the relation is not in the range table.
- *
- * In the second case ExecCreatR creates a temp relation.
- * (currently this is the only case we support -cim 10/16/89)
- * ----------------
- */
- /* ----------------
- * create the temporary relation
- * ----------------
- */
- tempDesc = ExecCreatR(tupType, _NONAME_RELATION_ID_);
-
- /* ----------------
- * save the relation descriptor in the sortstate
- * ----------------
- */
- matstate->mat_TempRelation = tempDesc;
- matstate->csstate.css_currentRelation = NULL;
-
- /* ----------------
- * return relation oid of temporary relation in a list
- * (someday -- for now we return LispTrue... cim 10/12/89)
- * ----------------
- */
return TRUE;
}
@@ -343,13 +320,39 @@ ExecMaterialReScan(Material *node, ExprContext *exprCtxt, Plan *parent)
{
MaterialState *matstate = node->matstate;
+ /*
+ * If we haven't materialized yet, just return. If outerplan' chgParam is
+ * not NULL then it will be re-scanned by ExecProcNode, else - no
+ * reason to re-scan it at all.
+ */
if (matstate->mat_Flag == false)
return;
- matstate->csstate.css_currentScanDesc = ExecReScanR(matstate->csstate.css_currentRelation,
- matstate->csstate.css_currentScanDesc,
- node->plan.state->es_direction, 0, NULL);
-
+ /*
+ * If subnode is to be rescanned then we forget previous stored results;
+ * we have to re-read the subplan and re-store.
+ *
+ * Otherwise we can just rewind and rescan the stored output.
+ */
+ if (((Plan *) node)->lefttree->chgParam != NULL)
+ {
+ Relation tempRelation = matstate->mat_TempRelation;
+
+ matstate->csstate.css_currentRelation = NULL;
+ ExecCloseR((Plan *) node);
+ ExecClearTuple(matstate->csstate.css_ScanTupleSlot);
+ if (tempRelation != NULL)
+ heap_drop(tempRelation);
+ matstate->mat_TempRelation = NULL;
+ matstate->mat_Flag = false;
+ }
+ else
+ {
+ matstate->csstate.css_currentScanDesc =
+ ExecReScanR(matstate->csstate.css_currentRelation,
+ matstate->csstate.css_currentScanDesc,
+ node->plan.state->es_direction, 0, NULL);
+ }
}
/* ----------------------------------------------------------------