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

Phase 1 of read-only-plans project: cause executor state nodes to point

to plan nodes, not vice-versa.  All executor state nodes now inherit from
struct PlanState.  Copying of plan trees has been simplified by not
storing a list of SubPlans in Plan nodes (eliminating duplicate links).
The executor still needs such a list, but it can build it during
ExecutorStart since it has to scan the plan tree anyway.
No initdb forced since no stored-on-disk structures changed, but you
will need a full recompile because of node-numbering changes.
This commit is contained in:
Tom Lane
2002-12-05 15:50:39 +00:00
parent 0f3b83edfa
commit 1fd0c59e25
71 changed files with 3032 additions and 3758 deletions

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeMaterial.c,v 1.38 2002/06/20 20:29:28 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/nodeMaterial.c,v 1.39 2002/12/05 15:50:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -43,10 +43,9 @@
* ----------------------------------------------------------------
*/
TupleTableSlot * /* result tuple from subplan */
ExecMaterial(Material *node)
ExecMaterial(MaterialState *node)
{
EState *estate;
MaterialState *matstate;
ScanDirection dir;
Tuplestorestate *tuplestorestate;
HeapTuple heapTuple;
@ -56,10 +55,9 @@ ExecMaterial(Material *node)
/*
* get state info from node
*/
matstate = node->matstate;
estate = node->plan.state;
estate = node->ss.ps.state;
dir = estate->es_direction;
tuplestorestate = (Tuplestorestate *) matstate->tuplestorestate;
tuplestorestate = (Tuplestorestate *) node->tuplestorestate;
/*
* If first time through, read all tuples from outer plan and pass
@ -69,7 +67,7 @@ ExecMaterial(Material *node)
if (tuplestorestate == NULL)
{
Plan *outerNode;
PlanState *outerNode;
/*
* Want to scan subplan in the forward direction while creating
@ -84,16 +82,16 @@ ExecMaterial(Material *node)
tuplestorestate = tuplestore_begin_heap(true, /* randomAccess */
SortMem);
matstate->tuplestorestate = (void *) tuplestorestate;
node->tuplestorestate = (void *) tuplestorestate;
/*
* Scan the subplan and feed all the tuples to tuplestore.
*/
outerNode = outerPlan((Plan *) node);
outerNode = outerPlanState(node);
for (;;)
{
slot = ExecProcNode(outerNode, (Plan *) node);
slot = ExecProcNode(outerNode);
if (TupIsNull(slot))
break;
@ -117,7 +115,7 @@ ExecMaterial(Material *node)
* Get the first or next tuple from tuplestore. Returns NULL if no
* more tuples.
*/
slot = (TupleTableSlot *) matstate->csstate.cstate.cs_ResultTupleSlot;
slot = (TupleTableSlot *) node->ss.ps.ps_ResultTupleSlot;
heapTuple = tuplestore_getheaptuple(tuplestorestate,
ScanDirectionIsForward(dir),
&should_free);
@ -129,23 +127,20 @@ ExecMaterial(Material *node)
* ExecInitMaterial
* ----------------------------------------------------------------
*/
bool /* initialization status */
ExecInitMaterial(Material *node, EState *estate, Plan *parent)
MaterialState *
ExecInitMaterial(Material *node, EState *estate)
{
MaterialState *matstate;
Plan *outerPlan;
/*
* assign the node's execution state
*/
node->plan.state = estate;
/*
* create state structure
*/
matstate = makeNode(MaterialState);
matstate->ss.ps.plan = (Plan *) node;
matstate->ss.ps.state = estate;
matstate->tuplestorestate = NULL;
node->matstate = matstate;
/*
* Miscellaneous initialization
@ -161,24 +156,24 @@ ExecInitMaterial(Material *node, EState *estate, Plan *parent)
*
* material nodes only return tuples from their materialized relation.
*/
ExecInitResultTupleSlot(estate, &matstate->csstate.cstate);
ExecInitScanTupleSlot(estate, &matstate->csstate);
ExecInitResultTupleSlot(estate, &matstate->ss.ps);
ExecInitScanTupleSlot(estate, &matstate->ss);
/*
* initializes child nodes
*/
outerPlan = outerPlan((Plan *) node);
ExecInitNode(outerPlan, estate, (Plan *) node);
outerPlan = outerPlan(node);
outerPlanState(matstate) = ExecInitNode(outerPlan, estate);
/*
* initialize tuple type. no need to initialize projection info
* because this node doesn't do projections.
*/
ExecAssignResultTypeFromOuterPlan((Plan *) node, &matstate->csstate.cstate);
ExecAssignScanTypeFromOuterPlan((Plan *) node, &matstate->csstate);
matstate->csstate.cstate.cs_ProjInfo = NULL;
ExecAssignResultTypeFromOuterPlan(&matstate->ss.ps);
ExecAssignScanTypeFromOuterPlan(&matstate->ss);
matstate->ss.ps.ps_ProjInfo = NULL;
return TRUE;
return matstate;
}
int
@ -194,33 +189,24 @@ ExecCountSlotsMaterial(Material *node)
* ----------------------------------------------------------------
*/
void
ExecEndMaterial(Material *node)
ExecEndMaterial(MaterialState *node)
{
MaterialState *matstate;
Plan *outerPlan;
/*
* get info from the material state
* clean out the tuple table
*/
matstate = node->matstate;
ExecClearTuple(node->ss.ss_ScanTupleSlot);
/*
* shut down the subplan
*/
outerPlan = outerPlan((Plan *) node);
ExecEndNode(outerPlan, (Plan *) node);
/*
* clean out the tuple table
*/
ExecClearTuple(matstate->csstate.css_ScanTupleSlot);
ExecEndNode(outerPlanState(node));
/*
* Release tuplestore resources
*/
if (matstate->tuplestorestate != NULL)
tuplestore_end((Tuplestorestate *) matstate->tuplestorestate);
matstate->tuplestorestate = NULL;
if (node->tuplestorestate != NULL)
tuplestore_end((Tuplestorestate *) node->tuplestorestate);
node->tuplestorestate = NULL;
}
/* ----------------------------------------------------------------
@ -230,17 +216,15 @@ ExecEndMaterial(Material *node)
* ----------------------------------------------------------------
*/
void
ExecMaterialMarkPos(Material *node)
ExecMaterialMarkPos(MaterialState *node)
{
MaterialState *matstate = node->matstate;
/*
* if we haven't materialized yet, just return.
*/
if (!matstate->tuplestorestate)
if (!node->tuplestorestate)
return;
tuplestore_markpos((Tuplestorestate *) matstate->tuplestorestate);
tuplestore_markpos((Tuplestorestate *) node->tuplestorestate);
}
/* ----------------------------------------------------------------
@ -250,20 +234,18 @@ ExecMaterialMarkPos(Material *node)
* ----------------------------------------------------------------
*/
void
ExecMaterialRestrPos(Material *node)
ExecMaterialRestrPos(MaterialState *node)
{
MaterialState *matstate = node->matstate;
/*
* if we haven't materialized yet, just return.
*/
if (!matstate->tuplestorestate)
if (!node->tuplestorestate)
return;
/*
* restore the scan to the previously marked position
*/
tuplestore_restorepos((Tuplestorestate *) matstate->tuplestorestate);
tuplestore_restorepos((Tuplestorestate *) node->tuplestorestate);
}
/* ----------------------------------------------------------------
@ -273,19 +255,17 @@ ExecMaterialRestrPos(Material *node)
* ----------------------------------------------------------------
*/
void
ExecMaterialReScan(Material *node, ExprContext *exprCtxt, Plan *parent)
ExecMaterialReScan(MaterialState *node, ExprContext *exprCtxt)
{
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->tuplestorestate)
if (!node->tuplestorestate)
return;
ExecClearTuple(matstate->csstate.cstate.cs_ResultTupleSlot);
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
/*
* If subnode is to be rescanned then we forget previous stored
@ -293,11 +273,11 @@ ExecMaterialReScan(Material *node, ExprContext *exprCtxt, Plan *parent)
*
* Otherwise we can just rewind and rescan the stored output.
*/
if (((Plan *) node)->lefttree->chgParam != NULL)
if (((PlanState *) node)->lefttree->chgParam != NULL)
{
tuplestore_end((Tuplestorestate *) matstate->tuplestorestate);
matstate->tuplestorestate = NULL;
tuplestore_end((Tuplestorestate *) node->tuplestorestate);
node->tuplestorestate = NULL;
}
else
tuplestore_rescan((Tuplestorestate *) matstate->tuplestorestate);
tuplestore_rescan((Tuplestorestate *) node->tuplestorestate);
}