aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeMaterial.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor/nodeMaterial.c')
-rw-r--r--src/backend/executor/nodeMaterial.c631
1 files changed, 318 insertions, 313 deletions
diff --git a/src/backend/executor/nodeMaterial.c b/src/backend/executor/nodeMaterial.c
index daf324bb77a..49ba73d3bf0 100644
--- a/src/backend/executor/nodeMaterial.c
+++ b/src/backend/executor/nodeMaterial.c
@@ -1,21 +1,21 @@
/*-------------------------------------------------------------------------
*
* nodeMaterial.c--
- * Routines to handle materialization nodes.
+ * Routines to handle materialization nodes.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeMaterial.c,v 1.6 1997/08/20 14:53:24 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeMaterial.c,v 1.7 1997/09/07 04:41:36 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
* INTERFACE ROUTINES
- * ExecMaterial - generate a temporary relation
- * ExecInitMaterial - initialize node and subnodes..
- * ExecEndMaterial - shutdown node and subnodes
+ * ExecMaterial - generate a temporary relation
+ * ExecInitMaterial - initialize node and subnodes..
+ * ExecEndMaterial - shutdown node and subnodes
*
*/
#include "postgres.h"
@@ -29,368 +29,373 @@
#include "access/heapam.h"
/* ----------------------------------------------------------------
- * ExecMaterial
+ * ExecMaterial
*
- * The first time this is called, ExecMaterial retrieves tuples
- * this node's outer subplan and inserts them into a temporary
- * relation. After this is done, a flag is set indicating that
- * the subplan has been materialized. Once the relation is
- * materialized, the first tuple is then returned. Successive
- * calls to ExecMaterial return successive tuples from the temp
- * relation.
+ * The first time this is called, ExecMaterial retrieves tuples
+ * this node's outer subplan and inserts them into a temporary
+ * relation. After this is done, a flag is set indicating that
+ * the subplan has been materialized. Once the relation is
+ * materialized, the first tuple is then returned. Successive
+ * calls to ExecMaterial return successive tuples from the temp
+ * relation.
*
- * Initial State:
+ * Initial State:
*
- * ExecMaterial assumes the temporary relation has been
- * created and openend by ExecInitMaterial during the prior
- * InitPlan() phase.
+ * ExecMaterial assumes the temporary relation has been
+ * created and openend by ExecInitMaterial during the prior
+ * InitPlan() phase.
*
* ----------------------------------------------------------------
*/
-TupleTableSlot * /* result tuple from subplan */
-ExecMaterial(Material *node)
+TupleTableSlot * /* result tuple from subplan */
+ExecMaterial(Material * node)
{
- EState *estate;
- MaterialState *matstate;
- Plan *outerNode;
- ScanDirection dir;
- Relation tempRelation;
- Relation currentRelation;
- HeapScanDesc currentScanDesc;
- HeapTuple heapTuple;
- TupleTableSlot *slot;
- Buffer buffer;
-
- /* ----------------
- * get state info from node
- * ----------------
- */
- matstate = node->matstate;
- estate = node->plan.state;
- dir = estate->es_direction;
-
- /* ----------------
- * the first time we call this, we retrieve all tuples
- * from the subplan into a temporary relation and then
- * we sort the relation. Subsequent calls return tuples
- * from the temporary relation.
- * ----------------
- */
-
- if (matstate->mat_Flag == false) {
+ EState *estate;
+ MaterialState *matstate;
+ Plan *outerNode;
+ ScanDirection dir;
+ Relation tempRelation;
+ Relation currentRelation;
+ HeapScanDesc currentScanDesc;
+ HeapTuple heapTuple;
+ TupleTableSlot *slot;
+ Buffer buffer;
+
/* ----------------
- * set all relations to be scanned in the forward direction
- * while creating the temporary relation.
+ * get state info from node
* ----------------
*/
- estate->es_direction = ForwardScanDirection;
-
+ matstate = node->matstate;
+ estate = node->plan.state;
+ dir = estate->es_direction;
+
/* ----------------
- * if we couldn't create the temp or current relations then
- * we print a warning and return NULL.
+ * the first time we call this, we retrieve all tuples
+ * from the subplan into a temporary relation and then
+ * we sort the relation. Subsequent calls return tuples
+ * from the temporary relation.
* ----------------
*/
- tempRelation = matstate->mat_TempRelation;
- if (tempRelation == NULL) {
- elog(DEBUG, "ExecMaterial: temp relation is NULL! aborting...");
- return NULL;
- }
-
- currentRelation = matstate->csstate.css_currentRelation;
- if (currentRelation == NULL) {
- elog(DEBUG, "ExecMaterial: current relation is NULL! aborting...");
- return NULL;
+
+ if (matstate->mat_Flag == false)
+ {
+ /* ----------------
+ * set all relations to be scanned in the forward direction
+ * while creating the temporary relation.
+ * ----------------
+ */
+ estate->es_direction = ForwardScanDirection;
+
+ /* ----------------
+ * if we couldn't create the temp or current relations 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;
+ }
+
+ currentRelation = matstate->csstate.css_currentRelation;
+ if (currentRelation == NULL)
+ {
+ elog(DEBUG, "ExecMaterial: current relation is NULL! aborting...");
+ return NULL;
+ }
+
+ /* ----------------
+ * retrieve tuples from the subplan and
+ * insert them in the temporary relation
+ * ----------------
+ */
+ outerNode = outerPlan((Plan *) node);
+ for (;;)
+ {
+ slot = ExecProcNode(outerNode, (Plan *) node);
+
+ heapTuple = slot->val;
+ if (heapTuple == NULL)
+ break;
+
+ heap_insert(tempRelation, /* relation desc */
+ heapTuple); /* heap tuple to insert */
+
+ ExecClearTuple(slot);
+ }
+ currentRelation = tempRelation;
+
+ /* ----------------
+ * restore to user specified direction
+ * ----------------
+ */
+ estate->es_direction = dir;
+
+ /* ----------------
+ * now initialize the scan descriptor to scan the
+ * sorted relation and update the sortstate information
+ * ----------------
+ */
+ currentScanDesc = heap_beginscan(currentRelation, /* relation */
+ ScanDirectionIsBackward(dir),
+ /* bkwd flag */
+ NowTimeQual, /* time qual */
+ 0, /* num scan keys */
+ NULL); /* scan keys */
+ matstate->csstate.css_currentRelation = currentRelation;
+ matstate->csstate.css_currentScanDesc = currentScanDesc;
+
+ ExecAssignScanType(&matstate->csstate,
+ RelationGetTupleDescriptor(currentRelation));
+
+ /* ----------------
+ * finally set the sorted flag to true
+ * ----------------
+ */
+ matstate->mat_Flag = true;
}
-
+
/* ----------------
- * retrieve tuples from the subplan and
- * insert them in the temporary relation
+ * at this point we know we have a sorted relation so
+ * we preform a simple scan on it with amgetnext()..
* ----------------
*/
- outerNode = outerPlan((Plan *) node);
- for (;;) {
- slot = ExecProcNode(outerNode, (Plan*) node);
-
- heapTuple = slot->val;
- if (heapTuple == NULL)
- break;
-
- heap_insert(tempRelation, /* relation desc */
- heapTuple); /* heap tuple to insert */
-
- ExecClearTuple( slot);
- }
- currentRelation = tempRelation;
-
+ currentScanDesc = matstate->csstate.css_currentScanDesc;
+
+ heapTuple = heap_getnext(currentScanDesc, /* scan desc */
+ ScanDirectionIsBackward(dir),
+ /* bkwd flag */
+ &buffer); /* return: buffer */
+
/* ----------------
- * restore to user specified direction
+ * put the tuple into the scan tuple slot and return the slot.
+ * Note: since the tuple is really a pointer to a page, we don't want
+ * to call pfree() on it..
* ----------------
*/
- estate->es_direction = dir;
-
+ slot = (TupleTableSlot *) matstate->csstate.css_ScanTupleSlot;
+
+ return ExecStoreTuple(heapTuple, /* tuple to store */
+ slot, /* slot to store in */
+ buffer, /* buffer for this tuple */
+ false); /* don't pfree this pointer */
+
+}
+
+/* ----------------------------------------------------------------
+ * ExecInitMaterial
+ * ----------------------------------------------------------------
+ */
+bool /* initialization status */
+ExecInitMaterial(Material * node, EState * estate, Plan * parent)
+{
+ MaterialState *matstate;
+ Plan *outerPlan;
+ TupleDesc tupType;
+ Relation tempDesc;
+
+ /* int len; */
+
/* ----------------
- * now initialize the scan descriptor to scan the
- * sorted relation and update the sortstate information
+ * assign the node's execution state
* ----------------
*/
- currentScanDesc = heap_beginscan(currentRelation, /* relation */
- ScanDirectionIsBackward(dir),
- /* bkwd flag */
- NowTimeQual, /* time qual */
- 0, /* num scan keys */
- NULL); /* scan keys */
- matstate->csstate.css_currentRelation = currentRelation;
- matstate->csstate.css_currentScanDesc = currentScanDesc;
-
- ExecAssignScanType(&matstate->csstate,
- RelationGetTupleDescriptor(currentRelation));
-
+ node->plan.state = estate;
+
/* ----------------
- * finally set the sorted flag to true
+ * create state structure
* ----------------
*/
- matstate->mat_Flag = true;
- }
-
- /* ----------------
- * at this point we know we have a sorted relation so
- * we preform a simple scan on it with amgetnext()..
- * ----------------
- */
- currentScanDesc = matstate->csstate.css_currentScanDesc;
-
- heapTuple = heap_getnext(currentScanDesc, /* scan desc */
- ScanDirectionIsBackward(dir),
- /* bkwd flag */
- &buffer); /* return: buffer */
-
- /* ----------------
- * put the tuple into the scan tuple slot and return the slot.
- * Note: since the tuple is really a pointer to a page, we don't want
- * to call pfree() on it..
- * ----------------
- */
- slot = (TupleTableSlot *)matstate->csstate.css_ScanTupleSlot;
-
- return ExecStoreTuple(heapTuple, /* tuple to store */
- slot, /* slot to store in */
- buffer, /* buffer for this tuple */
- false); /* don't pfree this pointer */
-
-}
+ matstate = makeNode(MaterialState);
+ matstate->mat_Flag = false;
+ matstate->mat_TempRelation = NULL;
+ node->matstate = matstate;
+
+ /* ----------------
+ * Miscellanious initialization
+ *
+ * + assign node's base_id
+ * + assign debugging hooks and
+ * + assign result tuple slot
+ *
+ * Materialization nodes don't need ExprContexts because
+ * they never call ExecQual or ExecTargetList.
+ * ----------------
+ */
+ ExecAssignNodeBaseInfo(estate, &matstate->csstate.cstate, parent);
-/* ----------------------------------------------------------------
- * ExecInitMaterial
- * ----------------------------------------------------------------
- */
-bool /* initialization status */
-ExecInitMaterial(Material *node, EState *estate, Plan *parent)
-{
- MaterialState *matstate;
- Plan *outerPlan;
- TupleDesc tupType;
- Relation tempDesc;
- /* int len; */
-
- /* ----------------
- * assign the node's execution state
- * ----------------
- */
- node->plan.state = estate;
-
- /* ----------------
- * create state structure
- * ----------------
- */
- matstate = makeNode(MaterialState);
- matstate->mat_Flag = false;
- matstate->mat_TempRelation = NULL;
- node->matstate = matstate;
-
- /* ----------------
- * Miscellanious initialization
- *
- * + assign node's base_id
- * + assign debugging hooks and
- * + assign result tuple slot
- *
- * Materialization nodes don't need ExprContexts because
- * they never call ExecQual or ExecTargetList.
- * ----------------
- */
- ExecAssignNodeBaseInfo(estate, &matstate->csstate.cstate, parent);
-
#define MATERIAL_NSLOTS 1
- /* ----------------
- * tuple table initialization
- * ----------------
- */
- ExecInitScanTupleSlot(estate, &matstate->csstate);
-
- /* ----------------
- * initializes child nodes
- * ----------------
- */
- 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.
- * ----------------
- */
- ExecAssignScanTypeFromOuterPlan((Plan *) node, &matstate->csstate);
- matstate->csstate.cstate.cs_ProjInfo = NULL;
-
- /* ----------------
- * get type information needed for ExecCreatR
- * ----------------
- */
- tupType = ExecGetScanType(&matstate->csstate);
-
- /* ----------------
- * ExecCreatR wants it's second argument to be an object id of
- * a relation in the range table or a _TEMP_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
- * ----------------
- */
-/* len = ExecTargetListLength(node->plan.targetlist); */
- tempDesc = ExecCreatR(tupType, _TEMP_RELATION_ID_);
-
- /* ----------------
- * save the relation descriptor in the sortstate
- * ----------------
- */
- matstate->mat_TempRelation = tempDesc;
- matstate->csstate.css_currentRelation = tempDesc;
-
- /* ----------------
- * return relation oid of temporary relation in a list
- * (someday -- for now we return LispTrue... cim 10/12/89)
- * ----------------
- */
- return TRUE;
+ /* ----------------
+ * tuple table initialization
+ * ----------------
+ */
+ ExecInitScanTupleSlot(estate, &matstate->csstate);
+
+ /* ----------------
+ * initializes child nodes
+ * ----------------
+ */
+ 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.
+ * ----------------
+ */
+ ExecAssignScanTypeFromOuterPlan((Plan *) node, &matstate->csstate);
+ matstate->csstate.cstate.cs_ProjInfo = NULL;
+
+ /* ----------------
+ * get type information needed for ExecCreatR
+ * ----------------
+ */
+ tupType = ExecGetScanType(&matstate->csstate);
+
+ /* ----------------
+ * ExecCreatR wants it's second argument to be an object id of
+ * a relation in the range table or a _TEMP_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
+ * ----------------
+ */
+/* len = ExecTargetListLength(node->plan.targetlist); */
+ tempDesc = ExecCreatR(tupType, _TEMP_RELATION_ID_);
+
+ /* ----------------
+ * save the relation descriptor in the sortstate
+ * ----------------
+ */
+ matstate->mat_TempRelation = tempDesc;
+ matstate->csstate.css_currentRelation = tempDesc;
+
+ /* ----------------
+ * return relation oid of temporary relation in a list
+ * (someday -- for now we return LispTrue... cim 10/12/89)
+ * ----------------
+ */
+ return TRUE;
}
int
-ExecCountSlotsMaterial(Material *node)
+ExecCountSlotsMaterial(Material * node)
{
- return ExecCountSlotsNode(outerPlan((Plan *)node)) +
- ExecCountSlotsNode(innerPlan((Plan *)node)) +
- MATERIAL_NSLOTS;
+ return ExecCountSlotsNode(outerPlan((Plan *) node)) +
+ ExecCountSlotsNode(innerPlan((Plan *) node)) +
+ MATERIAL_NSLOTS;
}
/* ----------------------------------------------------------------
- * ExecEndMaterial
+ * ExecEndMaterial
*
* old comments
- * destroys the temporary relation.
+ * destroys the temporary relation.
* ----------------------------------------------------------------
*/
void
-ExecEndMaterial(Material *node)
+ExecEndMaterial(Material * node)
{
- MaterialState *matstate;
- Relation tempRelation;
- Plan *outerPlan;
-
- /* ----------------
- * get info from the material state
- * ----------------
- */
- matstate = node->matstate;
- tempRelation = matstate->mat_TempRelation;
-
- heap_destroyr(tempRelation);
-
- /* ----------------
- * close the temp relation and shut down the scan.
- * ----------------
- */
- ExecCloseR((Plan *) node);
-
- /* ----------------
- * shut down the subplan
- * ----------------
- */
- outerPlan = outerPlan((Plan *) node);
- ExecEndNode(outerPlan, (Plan*) node);
-
- /* ----------------
- * clean out the tuple table
- * ----------------
- */
- ExecClearTuple(matstate->csstate.css_ScanTupleSlot);
-}
-
-#ifdef NOT_USED /* not used */
+ MaterialState *matstate;
+ Relation tempRelation;
+ Plan *outerPlan;
+
+ /* ----------------
+ * get info from the material state
+ * ----------------
+ */
+ matstate = node->matstate;
+ tempRelation = matstate->mat_TempRelation;
+
+ heap_destroyr(tempRelation);
+
+ /* ----------------
+ * close the temp relation and shut down the scan.
+ * ----------------
+ */
+ ExecCloseR((Plan *) node);
+
+ /* ----------------
+ * shut down the subplan
+ * ----------------
+ */
+ outerPlan = outerPlan((Plan *) node);
+ ExecEndNode(outerPlan, (Plan *) node);
+
+ /* ----------------
+ * clean out the tuple table
+ * ----------------
+ */
+ ExecClearTuple(matstate->csstate.css_ScanTupleSlot);
+}
+
+#ifdef NOT_USED /* not used */
/* ----------------------------------------------------------------
- * ExecMaterialMarkPos
+ * ExecMaterialMarkPos
* ----------------------------------------------------------------
*/
-List /* nothing of interest */
+List /* nothing of interest */
ExecMaterialMarkPos(Material node)
{
- MaterialState matstate;
- HeapScanDesc sdesc;
-
- /* ----------------
- * if we haven't materialized yet, just return NIL.
- * ----------------
- */
- matstate = get_matstate(node);
- if (get_mat_Flag(matstate) == false)
+ MaterialState matstate;
+ HeapScanDesc sdesc;
+
+ /* ----------------
+ * if we haven't materialized yet, just return NIL.
+ * ----------------
+ */
+ matstate = get_matstate(node);
+ if (get_mat_Flag(matstate) == false)
+ return NIL;
+
+ /* ----------------
+ * XXX access methods don't return positions yet so
+ * for now we return NIL. It's possible that
+ * they will never return positions for all I know -cim 10/16/89
+ * ----------------
+ */
+ sdesc = get_css_currentScanDesc((CommonScanState) matstate);
+ heap_markpos(sdesc);
+
return NIL;
-
- /* ----------------
- * XXX access methods don't return positions yet so
- * for now we return NIL. It's possible that
- * they will never return positions for all I know -cim 10/16/89
- * ----------------
- */
- sdesc = get_css_currentScanDesc((CommonScanState)matstate);
- heap_markpos(sdesc);
-
- return NIL;
}
/* ----------------------------------------------------------------
- * ExecMaterialRestrPos
+ * ExecMaterialRestrPos
* ----------------------------------------------------------------
*/
void
ExecMaterialRestrPos(Material node)
{
- MaterialState matstate;
- HeapScanDesc sdesc;
-
- /* ----------------
- * if we haven't materialized yet, just return.
- * ----------------
- */
- matstate = get_matstate(node);
- if (get_mat_Flag(matstate) == false)
- return;
-
- /* ----------------
- * restore the scan to the previously marked position
- * ----------------
- */
- sdesc = get_css_currentScanDesc((CommonScanState)matstate);
- heap_restrpos(sdesc);
+ MaterialState matstate;
+ HeapScanDesc sdesc;
+
+ /* ----------------
+ * if we haven't materialized yet, just return.
+ * ----------------
+ */
+ matstate = get_matstate(node);
+ if (get_mat_Flag(matstate) == false)
+ return;
+
+ /* ----------------
+ * restore the scan to the previously marked position
+ * ----------------
+ */
+ sdesc = get_css_currentScanDesc((CommonScanState) matstate);
+ heap_restrpos(sdesc);
}
-#endif
+#endif