1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-17 06:41:09 +03:00

Back-patch nodeMaterial to honor chgParam by recomputing its output.

This commit is contained in:
Tom Lane
2000-10-06 01:28:47 +00:00
parent 201d35d47f
commit c3bbbb1dcc

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * calls to ExecMaterial return successive tuples from the temp
* relation. * 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 */ TupleTableSlot * /* result tuple from subplan */
@ -78,25 +72,54 @@ ExecMaterial(Material *node)
if (matstate->mat_Flag == false) if (matstate->mat_Flag == false)
{ {
TupleDesc tupType;
/* ---------------- /* ----------------
* set all relations to be scanned in the forward direction * get type information needed for ExecCreatR
* while creating the temporary relation.
* ---------------- * ----------------
*/ */
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 * if we couldn't create the temp relation then
* we print a warning and return NULL. * we print a warning and return NULL.
* ---------------- * ----------------
*/ */
tempRelation = matstate->mat_TempRelation;
if (tempRelation == NULL) if (tempRelation == NULL)
{ {
elog(DEBUG, "ExecMaterial: temp relation is NULL! aborting..."); elog(DEBUG, "ExecMaterial: temp relation is NULL! aborting...");
return NULL; 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 * retrieve tuples from the subplan and
* insert them in the temporary relation * insert them in the temporary relation
@ -135,9 +158,6 @@ ExecMaterial(Material *node)
matstate->csstate.css_currentRelation = currentRelation; matstate->csstate.css_currentRelation = currentRelation;
matstate->csstate.css_currentScanDesc = currentScanDesc; matstate->csstate.css_currentScanDesc = currentScanDesc;
ExecAssignScanType(&matstate->csstate,
RelationGetDescr(currentRelation));
/* ---------------- /* ----------------
* finally set the sorted flag to true * finally set the sorted flag to true
* ---------------- * ----------------
@ -178,10 +198,6 @@ ExecInitMaterial(Material *node, EState *estate, Plan *parent)
{ {
MaterialState *matstate; MaterialState *matstate;
Plan *outerPlan; Plan *outerPlan;
TupleDesc tupType;
Relation tempDesc;
/* int len; */
/* ---------------- /* ----------------
* assign the node's execution state * assign the node's execution state
@ -225,12 +241,6 @@ ExecInitMaterial(Material *node, EState *estate, Plan *parent)
outerPlan = outerPlan((Plan *) node); outerPlan = outerPlan((Plan *) node);
ExecInitNode(outerPlan, estate, (Plan *) node); ExecInitNode(outerPlan, estate, (Plan *) node);
/* ----------------
* initialize matstate information
* ----------------
*/
matstate->mat_Flag = false;
/* ---------------- /* ----------------
* initialize tuple type. no need to initialize projection * initialize tuple type. no need to initialize projection
* info because this node doesn't do projections. * info because this node doesn't do projections.
@ -239,39 +249,6 @@ ExecInitMaterial(Material *node, EState *estate, Plan *parent)
ExecAssignScanTypeFromOuterPlan((Plan *) node, &matstate->csstate); ExecAssignScanTypeFromOuterPlan((Plan *) node, &matstate->csstate);
matstate->csstate.cstate.cs_ProjInfo = NULL; 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; return TRUE;
} }
@ -343,13 +320,39 @@ ExecMaterialReScan(Material *node, ExprContext *exprCtxt, Plan *parent)
{ {
MaterialState *matstate = node->matstate; 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) if (matstate->mat_Flag == false)
return; return;
matstate->csstate.css_currentScanDesc = ExecReScanR(matstate->csstate.css_currentRelation, /*
matstate->csstate.css_currentScanDesc, * If subnode is to be rescanned then we forget previous stored results;
node->plan.state->es_direction, 0, NULL); * 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);
}
} }
/* ---------------------------------------------------------------- /* ----------------------------------------------------------------