From c3bbbb1dcc2356a94409af71e9a85925e86d873c Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 6 Oct 2000 01:28:47 +0000 Subject: [PATCH] Back-patch nodeMaterial to honor chgParam by recomputing its output. --- src/backend/executor/nodeMaterial.c | 125 ++++++++++++++-------------- 1 file 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,25 +72,54 @@ 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..."); return NULL; } + /* ---------------- + * 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 @@ -225,12 +241,6 @@ ExecInitMaterial(Material *node, EState *estate, Plan *parent) outerPlan = outerPlan((Plan *) node); 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); + } } /* ---------------------------------------------------------------- -- 2.39.5