aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor')
-rw-r--r--src/backend/executor/execJunk.c65
-rw-r--r--src/backend/executor/execMain.c37
-rw-r--r--src/backend/executor/execProcnode.c187
-rw-r--r--src/backend/executor/execQual.c16
-rw-r--r--src/backend/executor/execTuples.c388
-rw-r--r--src/backend/executor/execUtils.c242
-rw-r--r--src/backend/executor/functions.c63
-rw-r--r--src/backend/executor/nodeHashjoin.c5
-rw-r--r--src/backend/executor/nodeIndexscan.c12
-rw-r--r--src/backend/executor/nodeMergejoin.c5
-rw-r--r--src/backend/executor/nodeSeqscan.c9
-rw-r--r--src/backend/executor/nodeSort.c17
-rw-r--r--src/backend/executor/nodeSubqueryscan.c7
-rw-r--r--src/backend/executor/nodeTidscan.c9
14 files changed, 358 insertions, 704 deletions
diff --git a/src/backend/executor/execJunk.c b/src/backend/executor/execJunk.c
index e9556900ca4..f23ba273462 100644
--- a/src/backend/executor/execJunk.c
+++ b/src/backend/executor/execJunk.c
@@ -8,12 +8,10 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execJunk.c,v 1.24 2001/01/24 19:42:53 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execJunk.c,v 1.25 2001/01/29 00:39:17 tgl Exp $
*
*-------------------------------------------------------------------------
*/
-
-
#include "postgres.h"
#include "access/heapam.h"
@@ -37,7 +35,7 @@
* called 'resjunk'. If the value of this attribute is true then the
* corresponding attribute is a "junk" attribute.
*
- * When we initialize a plan we call 'ExecInitJunkFilter' to create
+ * When we initialize a plan we call 'ExecInitJunkFilter' to create
* and store the appropriate information in the 'es_junkFilter' attribute of
* EState.
*
@@ -63,6 +61,8 @@
JunkFilter *
ExecInitJunkFilter(List *targetList, TupleDesc tupType)
{
+ MemoryContext oldContext;
+ MemoryContext junkContext;
JunkFilter *junkfilter;
List *cleanTargetList;
int len,
@@ -75,9 +75,21 @@ ExecInitJunkFilter(List *targetList, TupleDesc tupType)
bool resjunk;
AttrNumber cleanResno;
AttrNumber *cleanMap;
- Size size;
Node *expr;
+ /*
+ * Make a memory context that will hold the JunkFilter as well as all
+ * the subsidiary structures we are about to create. We use smaller-
+ * than-default sizing parameters since we don't expect a very large
+ * volume of stuff here.
+ */
+ junkContext = AllocSetContextCreate(CurrentMemoryContext,
+ "JunkFilterContext",
+ 1024,
+ 1024,
+ ALLOCSET_DEFAULT_MAXSIZE);
+ oldContext = MemoryContextSwitchTo(junkContext);
+
/* ---------------------
* First find the "clean" target list, i.e. all the entries
* in the original target list which have a false 'resjunk'
@@ -166,7 +178,7 @@ ExecInitJunkFilter(List *targetList, TupleDesc tupType)
cleanLength = ExecTargetListLength(cleanTargetList);
/* ---------------------
- * Now calculate the "map" between the original tuples attributes
+ * Now calculate the "map" between the original tuple's attributes
* and the "clean" tuple's attributes.
*
* The "map" is an array of "cleanLength" attribute numbers, i.e.
@@ -177,8 +189,7 @@ ExecInitJunkFilter(List *targetList, TupleDesc tupType)
*/
if (cleanLength > 0)
{
- size = cleanLength * sizeof(AttrNumber);
- cleanMap = (AttrNumber *) palloc(size);
+ cleanMap = (AttrNumber *) palloc(cleanLength * sizeof(AttrNumber));
cleanResno = 1;
foreach(t, targetList)
{
@@ -226,7 +237,7 @@ ExecInitJunkFilter(List *targetList, TupleDesc tupType)
cleanMap = NULL;
/* ---------------------
- * Finally create and initialize the JunkFilter.
+ * Finally create and initialize the JunkFilter struct.
* ---------------------
*/
junkfilter = makeNode(JunkFilter);
@@ -238,20 +249,36 @@ ExecInitJunkFilter(List *targetList, TupleDesc tupType)
junkfilter->jf_cleanLength = cleanLength;
junkfilter->jf_cleanTupType = cleanTupType;
junkfilter->jf_cleanMap = cleanMap;
+ junkfilter->jf_junkContext = junkContext;
+
+ MemoryContextSwitchTo(oldContext);
return junkfilter;
+}
+/*-------------------------------------------------------------------------
+ * ExecFreeJunkFilter
+ *
+ * Release the data structures created by ExecInitJunkFilter.
+ *-------------------------------------------------------------------------
+ */
+void
+ExecFreeJunkFilter(JunkFilter *junkfilter)
+{
+ /*
+ * Since the junkfilter is inside its own context, we just have to
+ * delete the context and we're set.
+ */
+ MemoryContextDelete(junkfilter->jf_junkContext);
}
/*-------------------------------------------------------------------------
* ExecGetJunkAttribute
*
* Given a tuple (slot), the junk filter and a junk attribute's name,
- * extract & return the value of this attribute.
+ * extract & return the value and isNull flag of this attribute.
*
* It returns false iff no junk attribute with such name was found.
- *
- * NOTE: isNull might be NULL !
*-------------------------------------------------------------------------
*/
bool
@@ -304,7 +331,7 @@ ExecGetJunkAttribute(JunkFilter *junkfilter,
* ---------------------
*/
tuple = slot->val;
- tupType = (TupleDesc) junkfilter->jf_tupType;
+ tupType = junkfilter->jf_tupType;
*value = heap_getattr(tuple, resno, tupType, isNull);
@@ -328,7 +355,6 @@ ExecRemoveJunk(JunkFilter *junkfilter, TupleTableSlot *slot)
int cleanLength;
bool isNull;
int i;
- Size size;
Datum *values;
char *nulls;
Datum values_array[64];
@@ -340,8 +366,8 @@ ExecRemoveJunk(JunkFilter *junkfilter, TupleTableSlot *slot)
*/
tuple = slot->val;
- tupType = (TupleDesc) junkfilter->jf_tupType;
- cleanTupType = (TupleDesc) junkfilter->jf_cleanTupType;
+ tupType = junkfilter->jf_tupType;
+ cleanTupType = junkfilter->jf_cleanTupType;
cleanLength = junkfilter->jf_cleanLength;
cleanMap = junkfilter->jf_cleanMap;
@@ -363,11 +389,8 @@ ExecRemoveJunk(JunkFilter *junkfilter, TupleTableSlot *slot)
*/
if (cleanLength > 64)
{
- size = cleanLength * sizeof(Datum);
- values = (Datum *) palloc(size);
-
- size = cleanLength * sizeof(char);
- nulls = (char *) palloc(size);
+ values = (Datum *) palloc(cleanLength * sizeof(Datum));
+ nulls = (char *) palloc(cleanLength * sizeof(char));
}
else
{
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 77af5e7ecce..929134209ba 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -27,7 +27,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.137 2001/01/27 05:16:58 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.138 2001/01/29 00:39:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -252,12 +252,8 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature, long count)
/* ----------------------------------------------------------------
* ExecutorEnd
*
- * This routine must be called at the end of any execution of any
+ * This routine must be called at the end of execution of any
* query plan
- *
- * returns (AttrInfo*) which describes the attributes of the tuples to
- * be returned by the query.
- *
* ----------------------------------------------------------------
*/
void
@@ -268,23 +264,15 @@ ExecutorEnd(QueryDesc *queryDesc, EState *estate)
EndPlan(queryDesc->plantree, estate);
- /* XXX - clean up some more from ExecutorStart() - er1p */
- if (NULL == estate->es_snapshot)
- {
- /* nothing to free */
- }
- else
+ if (estate->es_snapshot != NULL)
{
if (estate->es_snapshot->xcnt > 0)
pfree(estate->es_snapshot->xip);
pfree(estate->es_snapshot);
+ estate->es_snapshot = NULL;
}
- if (NULL == estate->es_param_exec_vals)
- {
- /* nothing to free */
- }
- else
+ if (estate->es_param_exec_vals != NULL)
{
pfree(estate->es_param_exec_vals);
estate->es_param_exec_vals = NULL;
@@ -870,7 +858,7 @@ EndPlan(Plan *plan, EState *estate)
/*
* close the result relation(s) if any, but hold locks
- * until xact commit.
+ * until xact commit. Also clean up junkfilters if present.
*/
resultRelInfo = estate->es_result_relations;
for (i = estate->es_num_result_relations; i > 0; i--)
@@ -878,6 +866,9 @@ EndPlan(Plan *plan, EState *estate)
/* Close indices and then the relation itself */
ExecCloseIndices(resultRelInfo);
heap_close(resultRelInfo->ri_RelationDesc, NoLock);
+ /* Delete the junkfilter if any */
+ if (resultRelInfo->ri_junkFilter != NULL)
+ ExecFreeJunkFilter(resultRelInfo->ri_junkFilter);
resultRelInfo++;
}
@@ -888,6 +879,16 @@ EndPlan(Plan *plan, EState *estate)
heap_close(estate->es_into_relation_descriptor, NoLock);
/*
+ * There might be a junkfilter without a result relation.
+ */
+ if (estate->es_num_result_relations == 0 &&
+ estate->es_junkFilter != NULL)
+ {
+ ExecFreeJunkFilter(estate->es_junkFilter);
+ estate->es_junkFilter = NULL;
+ }
+
+ /*
* close any relations selected FOR UPDATE, again keeping locks
*/
foreach(l, estate->es_rowMark)
diff --git a/src/backend/executor/execProcnode.c b/src/backend/executor/execProcnode.c
index 549f612d7eb..bc1b6d0b2f7 100644
--- a/src/backend/executor/execProcnode.c
+++ b/src/backend/executor/execProcnode.c
@@ -12,7 +12,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execProcnode.c,v 1.24 2001/01/24 19:42:54 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execProcnode.c,v 1.25 2001/01/29 00:39:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,6 +21,8 @@
* ExecInitNode - initialize a plan node and its subplans
* ExecProcNode - get a tuple by executing the plan node
* ExecEndNode - shut down a plan node and its subplans
+ * ExecCountSlotsNode - count tuple slots needed by plan tree
+ * ExecGetTupType - get result tuple type of a plan node
*
* NOTES
* This used to be three files. It is now all combined into
@@ -218,7 +220,8 @@ ExecInitNode(Plan *node, EState *estate, Plan *parent)
break;
default:
- elog(ERROR, "ExecInitNode: node %d unsupported", nodeTag(node));
+ elog(ERROR, "ExecInitNode: node type %d unsupported",
+ (int) nodeTag(node));
result = FALSE;
}
@@ -347,7 +350,8 @@ ExecProcNode(Plan *node, Plan *parent)
break;
default:
- elog(ERROR, "ExecProcNode: node %d unsupported", nodeTag(node));
+ elog(ERROR, "ExecProcNode: node type %d unsupported",
+ (int) nodeTag(node));
result = NULL;
}
@@ -430,8 +434,8 @@ ExecCountSlotsNode(Plan *node)
return ExecCountSlotsAgg((Agg *) node);
default:
- elog(ERROR, "ExecCountSlotsNode: node not yet supported: %d",
- nodeTag(node));
+ elog(ERROR, "ExecCountSlotsNode: node type %d unsupported",
+ (int) nodeTag(node));
break;
}
return 0;
@@ -558,7 +562,178 @@ ExecEndNode(Plan *node, Plan *parent)
break;
default:
- elog(ERROR, "ExecEndNode: node %d unsupported", nodeTag(node));
+ elog(ERROR, "ExecEndNode: node type %d unsupported",
+ (int) nodeTag(node));
break;
}
}
+
+
+/* ----------------------------------------------------------------
+ * ExecGetTupType
+ *
+ * this gives you the tuple descriptor for tuples returned
+ * by this node. I really wish I could ditch this routine,
+ * but since not all nodes store their type info in the same
+ * place, we have to do something special for each node type.
+ *
+ * ----------------------------------------------------------------
+ */
+TupleDesc
+ExecGetTupType(Plan *node)
+{
+ TupleTableSlot *slot;
+
+ if (node == NULL)
+ return NULL;
+
+ switch (nodeTag(node))
+ {
+ case T_Result:
+ {
+ ResultState *resstate = ((Result *) node)->resstate;
+
+ slot = resstate->cstate.cs_ResultTupleSlot;
+ }
+ break;
+
+ case T_SeqScan:
+ {
+ CommonScanState *scanstate = ((SeqScan *) node)->scanstate;
+
+ slot = scanstate->cstate.cs_ResultTupleSlot;
+ }
+ break;
+
+ case T_NestLoop:
+ {
+ NestLoopState *nlstate = ((NestLoop *) node)->nlstate;
+
+ slot = nlstate->jstate.cs_ResultTupleSlot;
+ }
+ break;
+
+ case T_Append:
+ {
+ AppendState *appendstate = ((Append *) node)->appendstate;
+
+ slot = appendstate->cstate.cs_ResultTupleSlot;
+ }
+ break;
+
+ case T_IndexScan:
+ {
+ CommonScanState *scanstate = ((IndexScan *) node)->scan.scanstate;
+
+ slot = scanstate->cstate.cs_ResultTupleSlot;
+ }
+ break;
+
+ case T_TidScan:
+ {
+ CommonScanState *scanstate = ((TidScan *) node)->scan.scanstate;
+
+ slot = scanstate->cstate.cs_ResultTupleSlot;
+ }
+ break;
+
+ case T_SubqueryScan:
+ {
+ CommonScanState *scanstate = ((SubqueryScan *) node)->scan.scanstate;
+
+ slot = scanstate->cstate.cs_ResultTupleSlot;
+ }
+ break;
+
+ case T_Material:
+ {
+ MaterialState *matstate = ((Material *) node)->matstate;
+
+ slot = matstate->csstate.css_ScanTupleSlot;
+ }
+ break;
+
+ case T_Sort:
+ {
+ SortState *sortstate = ((Sort *) node)->sortstate;
+
+ slot = sortstate->csstate.css_ScanTupleSlot;
+ }
+ break;
+
+ case T_Agg:
+ {
+ AggState *aggstate = ((Agg *) node)->aggstate;
+
+ slot = aggstate->csstate.cstate.cs_ResultTupleSlot;
+ }
+ break;
+
+ case T_Group:
+ {
+ GroupState *grpstate = ((Group *) node)->grpstate;
+
+ slot = grpstate->csstate.cstate.cs_ResultTupleSlot;
+ }
+ break;
+
+ case T_Hash:
+ {
+ HashState *hashstate = ((Hash *) node)->hashstate;
+
+ slot = hashstate->cstate.cs_ResultTupleSlot;
+ }
+ break;
+
+ case T_Unique:
+ {
+ UniqueState *uniquestate = ((Unique *) node)->uniquestate;
+
+ slot = uniquestate->cstate.cs_ResultTupleSlot;
+ }
+ break;
+
+ case T_SetOp:
+ {
+ SetOpState *setopstate = ((SetOp *) node)->setopstate;
+
+ slot = setopstate->cstate.cs_ResultTupleSlot;
+ }
+ break;
+
+ case T_Limit:
+ {
+ LimitState *limitstate = ((Limit *) node)->limitstate;
+
+ slot = limitstate->cstate.cs_ResultTupleSlot;
+ }
+ break;
+
+ case T_MergeJoin:
+ {
+ MergeJoinState *mergestate = ((MergeJoin *) node)->mergestate;
+
+ slot = mergestate->jstate.cs_ResultTupleSlot;
+ }
+ break;
+
+ case T_HashJoin:
+ {
+ HashJoinState *hashjoinstate = ((HashJoin *) node)->hashjoinstate;
+
+ slot = hashjoinstate->jstate.cs_ResultTupleSlot;
+ }
+ break;
+
+ default:
+ /* ----------------
+ * should never get here
+ * ----------------
+ */
+ elog(ERROR, "ExecGetTupType: node type %d unsupported",
+ (int) nodeTag(node));
+ return NULL;
+ }
+
+ return slot->ttc_tupleDescriptor;
+}
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c
index f0721f57bd5..bab2851df9d 100644
--- a/src/backend/executor/execQual.c
+++ b/src/backend/executor/execQual.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.82 2001/01/24 19:42:54 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.83 2001/01/29 00:39:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -328,25 +328,19 @@ ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull)
/*
* If the attribute number is invalid, then we are supposed to return
* the entire tuple, we give back a whole slot so that callers know
- * what the tuple looks like.
+ * what the tuple looks like. XXX why copy? Couldn't we just give
+ * back the existing slot?
*/
if (attnum == InvalidAttrNumber)
{
- TupleTableSlot *tempSlot;
+ TupleTableSlot *tempSlot = MakeTupleTableSlot();
TupleDesc td;
HeapTuple tup;
- tempSlot = makeNode(TupleTableSlot);
- tempSlot->ttc_shouldFree = false;
- tempSlot->ttc_descIsNew = true;
- tempSlot->ttc_tupleDescriptor = (TupleDesc) NULL;
- tempSlot->ttc_buffer = InvalidBuffer;
-
tup = heap_copytuple(heapTuple);
td = CreateTupleDescCopy(tuple_type);
- ExecSetSlotDescriptor(tempSlot, td);
-
+ ExecSetSlotDescriptor(tempSlot, td, true);
ExecStoreTuple(tup, tempSlot, InvalidBuffer, true);
return PointerGetDatum(tempSlot);
}
diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c
index ecb8ae48b50..e5f1a269d81 100644
--- a/src/backend/executor/execTuples.c
+++ b/src/backend/executor/execTuples.c
@@ -15,7 +15,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.45 2001/01/24 19:42:54 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.46 2001/01/29 00:39:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -24,26 +24,20 @@
*
* TABLE CREATE/DELETE
* ExecCreateTupleTable - create a new tuple table
- * ExecDropTupleTable - destroy a table
+ * ExecDropTupleTable - destroy a table
*
- * SLOT RESERVERATION
+ * SLOT RESERVATION
* ExecAllocTableSlot - find an available slot in the table
*
* SLOT ACCESSORS
* ExecStoreTuple - store a tuple in the table
* ExecFetchTuple - fetch a tuple from the table
* ExecClearTuple - clear contents of a table slot
- * ExecSlotPolicy - return slot's tuple pfree policy
- * ExecSetSlotPolicy - diddle the slot policy
- * ExecSlotDescriptor - type of tuple in a slot
* ExecSetSlotDescriptor - set a slot's tuple descriptor
* ExecSetSlotDescriptorIsNew - diddle the slot-desc-is-new flag
- * ExecSetNewSlotDescriptor - set a desc and the is-new-flag all at once
*
* SLOT STATUS PREDICATES
* TupIsNull - true when slot contains no tuple(Macro)
- * ExecSlotDescriptorIsNew - true if we're now storing a different
- * type of tuple in a slot
*
* CONVENIENCE INITIALIZATION ROUTINES
* ExecInitResultTupleSlot \ convenience routines to initialize
@@ -51,8 +45,7 @@
* ExecInitExtraTupleSlot / which store copies of tuples.
* ExecInitNullTupleSlot /
*
- * old routines:
- * ExecGetTupType - get type of tuple returned by this node
+ * Routines that probably belong somewhere else:
* ExecTypeFromTL - form a TupleDesc from a target list
*
* EXAMPLE OF HOW TABLE ROUTINES WORK
@@ -112,16 +105,11 @@
* and the TupleTableSlot node in execnodes.h.
*
*/
-
#include "postgres.h"
-#include "executor/executor.h"
-
-#undef ExecStoreTuple
-#include "catalog/pg_type.h"
#include "access/heapam.h"
-
-static TupleTableSlot *NodeGetResultTupleSlot(Plan *node);
+#include "catalog/pg_type.h"
+#include "executor/executor.h"
/* ----------------------------------------------------------------
@@ -212,23 +200,17 @@ ExecDropTupleTable(TupleTable table, /* tuple table */
* and drop refcounts of any referenced buffers,
* if that's what the caller wants. (There is probably
* no good reason for the caller ever not to want it!)
- *
- * Note: we do nothing about the Tuple Descriptor's
- * we store in the slots. This may have to change (ex: we should
- * probably worry about pfreeing tuple descs too) -cim 3/14/91
- *
- * Right now, the handling of tuple pointers and buffer refcounts
- * is clean, but the handling of tuple descriptors is NOT; they
- * are copied around with wild abandon. It would take some work
- * to make tuple descs pfree'able. Fortunately, since they're
- * normally only made once per scan, it's probably not worth
- * worrying about... tgl 9/21/99
* ----------------
*/
if (shouldFree)
{
for (i = 0; i < next; i++)
+ {
ExecClearTuple(&array[i]);
+ if (array[i].ttc_shouldFreeDesc &&
+ array[i].ttc_tupleDescriptor != NULL)
+ FreeTupleDesc(array[i].ttc_tupleDescriptor);
+ }
}
/* ----------------
@@ -301,6 +283,32 @@ ExecAllocTableSlot(TupleTable table)
slot->val = (HeapTuple) NULL;
slot->ttc_shouldFree = true;
slot->ttc_descIsNew = true;
+ slot->ttc_shouldFreeDesc = true;
+ slot->ttc_tupleDescriptor = (TupleDesc) NULL;
+ slot->ttc_buffer = InvalidBuffer;
+
+ return slot;
+}
+
+/* --------------------------------
+ * MakeTupleTableSlot
+ *
+ * This routine makes an empty standalone TupleTableSlot.
+ * It really shouldn't exist, but there are a few places
+ * that do this, so we may as well centralize the knowledge
+ * of what's in one ...
+ * --------------------------------
+ */
+TupleTableSlot *
+MakeTupleTableSlot(void)
+{
+ TupleTableSlot *slot = makeNode(TupleTableSlot);
+
+ /* This should match ExecAllocTableSlot() */
+ slot->val = (HeapTuple) NULL;
+ slot->ttc_shouldFree = true;
+ slot->ttc_descIsNew = true;
+ slot->ttc_shouldFreeDesc = true;
slot->ttc_tupleDescriptor = (TupleDesc) NULL;
slot->ttc_buffer = InvalidBuffer;
@@ -384,6 +392,8 @@ ExecStoreTuple(HeapTuple tuple,
* ExecClearTuple
*
* This function is used to clear out a slot in the tuple table.
+ *
+ * NB: only the tuple is cleared, not the tuple descriptor (if any).
* --------------------------------
*/
TupleTableSlot * /* return: slot passed */
@@ -426,57 +436,6 @@ ExecClearTuple(TupleTableSlot *slot) /* slot in which to store tuple */
return slot;
}
-
-/* --------------------------------
- * ExecSlotPolicy
- *
- * This function is used to get the call/don't call pfree
- * setting of a slot. Most executor routines don't need this.
- * It's only when you do tricky things like marking tuples for
- * merge joins that you need to diddle the slot policy.
- * --------------------------------
- */
-#ifdef NOT_USED
-bool /* return: slot policy */
-ExecSlotPolicy(TupleTableSlot *slot) /* slot to inspect */
-{
- return slot->ttc_shouldFree;
-}
-
-
-/* --------------------------------
- * ExecSetSlotPolicy
- *
- * This function is used to change the call/don't call pfree
- * setting of a slot. Most executor routines don't need this.
- * It's only when you do tricky things like marking tuples for
- * merge joins that you need to diddle the slot policy.
- * --------------------------------
- */
-bool /* return: old slot policy */
-ExecSetSlotPolicy(TupleTableSlot *slot, /* slot to change */
- bool shouldFree) /* true if we call pfree() when we
- * gc. */
-{
- bool old_shouldFree = slot->ttc_shouldFree;
-
- slot->ttc_shouldFree = shouldFree;
-
- return old_shouldFree;
-}
-
-#endif
-
-/* --------------------------------
- * ExecSlotDescriptor
- *
- * This function is used to get the tuple descriptor associated
- * with the slot's tuple.
- *
- * Now a macro in tuptable.h -mer 5 March 1992
- * --------------------------------
- */
-
/* --------------------------------
* ExecSetSlotDescriptor
*
@@ -484,14 +443,17 @@ ExecSetSlotPolicy(TupleTableSlot *slot, /* slot to change */
* with the slot's tuple.
* --------------------------------
*/
-TupleDesc /* return: old slot tuple descriptor */
+void
ExecSetSlotDescriptor(TupleTableSlot *slot, /* slot to change */
- TupleDesc tupdesc) /* tuple descriptor */
+ TupleDesc tupdesc, /* new tuple descriptor */
+ bool shouldFree) /* is desc owned by slot? */
{
- TupleDesc old_tupdesc = slot->ttc_tupleDescriptor;
+ if (slot->ttc_shouldFreeDesc &&
+ slot->ttc_tupleDescriptor != NULL)
+ FreeTupleDesc(slot->ttc_tupleDescriptor);
slot->ttc_tupleDescriptor = tupdesc;
- return old_tupdesc;
+ slot->ttc_shouldFreeDesc = shouldFree;
}
/* --------------------------------
@@ -507,52 +469,11 @@ ExecSetSlotDescriptorIsNew(TupleTableSlot *slot, /* slot to change */
slot->ttc_descIsNew = isNew;
}
-/* --------------------------------
- * ExecSetNewSlotDescriptor
- *
- * This function is used to set the tuple descriptor associated
- * with the slot's tuple, and set the "isNew" flag at the same time.
- * --------------------------------
- */
-#ifdef NOT_USED
-TupleDesc /* return: old slot tuple descriptor */
-ExecSetNewSlotDescriptor(TupleTableSlot *slot, /* slot to change */
- TupleDesc tupdesc) /* tuple descriptor */
-{
- TupleDesc old_tupdesc = slot->ttc_tupleDescriptor;
-
- slot->ttc_tupleDescriptor = tupdesc;
- slot->ttc_descIsNew = true;
-
- return old_tupdesc;
-}
-
-#endif
-
/* ----------------------------------------------------------------
* tuple table slot status predicates
* ----------------------------------------------------------------
*/
-/* --------------------------------
- * ExecSlotDescriptorIsNew
- *
- * This function is used to check if the tuple descriptor
- * associated with this slot has just changed. ie: we are
- * now storing a new type of tuple in this slot
- * --------------------------------
- */
-#ifdef NOT_USED
-bool /* return: descriptor "is new" */
-ExecSlotDescriptorIsNew(TupleTableSlot *slot) /* slot to inspect */
-{
-/* bool isNew = SlotTupleDescriptorIsNew((TupleTableSlot*) slot);
- return isNew; */
- return slot->ttc_descIsNew;
-}
-
-#endif
-
/* ----------------------------------------------------------------
* convenience initialization routines
* ----------------------------------------------------------------
@@ -632,228 +553,13 @@ ExecInitNullTupleSlot(EState *estate, TupleDesc tupType)
static struct tupleDesc NullTupleDesc; /* we assume this inits to
* zeroes */
- ExecSetSlotDescriptor(slot, tupType);
+ ExecSetSlotDescriptor(slot, tupType, false);
nullTuple = heap_formtuple(&NullTupleDesc, values, nulls);
return ExecStoreTuple(nullTuple, slot, InvalidBuffer, true);
}
-
-static TupleTableSlot *
-NodeGetResultTupleSlot(Plan *node)
-{
- TupleTableSlot *slot;
-
- switch (nodeTag(node))
- {
-
- case T_Result:
- {
- ResultState *resstate = ((Result *) node)->resstate;
-
- slot = resstate->cstate.cs_ResultTupleSlot;
- }
- break;
-
- case T_SeqScan:
- {
- CommonScanState *scanstate = ((SeqScan *) node)->scanstate;
-
- slot = scanstate->cstate.cs_ResultTupleSlot;
- }
- break;
-
- case T_NestLoop:
- {
- NestLoopState *nlstate = ((NestLoop *) node)->nlstate;
-
- slot = nlstate->jstate.cs_ResultTupleSlot;
- }
- break;
-
- case T_Append:
- {
- AppendState *appendstate = ((Append *) node)->appendstate;
-
- slot = appendstate->cstate.cs_ResultTupleSlot;
- }
- break;
-
- case T_IndexScan:
- {
- CommonScanState *scanstate = ((IndexScan *) node)->scan.scanstate;
-
- slot = scanstate->cstate.cs_ResultTupleSlot;
- }
- break;
-
- case T_TidScan:
- {
- CommonScanState *scanstate = ((TidScan *) node)->scan.scanstate;
-
- slot = scanstate->cstate.cs_ResultTupleSlot;
- }
- break;
-
- case T_SubqueryScan:
- {
- CommonScanState *scanstate = ((SubqueryScan *) node)->scan.scanstate;
-
- slot = scanstate->cstate.cs_ResultTupleSlot;
- }
- break;
-
- case T_Material:
- {
- MaterialState *matstate = ((Material *) node)->matstate;
-
- slot = matstate->csstate.css_ScanTupleSlot;
- }
- break;
-
- case T_Sort:
- {
- SortState *sortstate = ((Sort *) node)->sortstate;
-
- slot = sortstate->csstate.css_ScanTupleSlot;
- }
- break;
-
- case T_Agg:
- {
- AggState *aggstate = ((Agg *) node)->aggstate;
-
- slot = aggstate->csstate.cstate.cs_ResultTupleSlot;
- }
- break;
-
- case T_Group:
- {
- GroupState *grpstate = ((Group *) node)->grpstate;
-
- slot = grpstate->csstate.cstate.cs_ResultTupleSlot;
- }
- break;
-
- case T_Hash:
- {
- HashState *hashstate = ((Hash *) node)->hashstate;
-
- slot = hashstate->cstate.cs_ResultTupleSlot;
- }
- break;
-
- case T_Unique:
- {
- UniqueState *uniquestate = ((Unique *) node)->uniquestate;
-
- slot = uniquestate->cstate.cs_ResultTupleSlot;
- }
- break;
-
- case T_SetOp:
- {
- SetOpState *setopstate = ((SetOp *) node)->setopstate;
-
- slot = setopstate->cstate.cs_ResultTupleSlot;
- }
- break;
-
- case T_Limit:
- {
- LimitState *limitstate = ((Limit *) node)->limitstate;
-
- slot = limitstate->cstate.cs_ResultTupleSlot;
- }
- break;
-
- case T_MergeJoin:
- {
- MergeJoinState *mergestate = ((MergeJoin *) node)->mergestate;
-
- slot = mergestate->jstate.cs_ResultTupleSlot;
- }
- break;
-
- case T_HashJoin:
- {
- HashJoinState *hashjoinstate = ((HashJoin *) node)->hashjoinstate;
-
- slot = hashjoinstate->jstate.cs_ResultTupleSlot;
- }
- break;
-
- default:
- /* ----------------
- * should never get here
- * ----------------
- */
- elog(ERROR, "NodeGetResultTupleSlot: node not yet supported: %d",
- (int) nodeTag(node));
-
- return NULL;
- }
- return slot;
-}
-
-/* ----------------------------------------------------------------
- * ExecGetTupType
- *
- * this gives you the tuple descriptor for tuples returned
- * by this node. I really wish I could ditch this routine,
- * but since not all nodes store their type info in the same
- * place, we have to do something special for each node type.
- *
- * Soon, the system will have to adapt to deal with changing
- * tuple descriptors as we deal with dynamic tuple types
- * being returned from procedure nodes. Perhaps then this
- * routine can be retired. -cim 6/3/91
- *
- * old comments
- * This routine just gets the type information out of the
- * node's state. If you already have a node's state, you
- * can get this information directly, but this is a useful
- * routine if you want to get the type information from
- * the node's inner or outer subplan easily without having
- * to inspect the subplan.. -cim 10/16/89
- *
- * ----------------------------------------------------------------
- */
-
-TupleDesc
-ExecGetTupType(Plan *node)
-{
- TupleTableSlot *slot;
- TupleDesc tupType;
-
- if (node == NULL)
- return NULL;
-
- slot = NodeGetResultTupleSlot(node);
- tupType = slot->ttc_tupleDescriptor;
- return tupType;
-}
-
-#ifdef NOT_USED
-TupleDesc
-ExecCopyTupType(TupleDesc td, int natts)
-{
- TupleDesc newTd;
- int i;
-
- newTd = CreateTemplateTupleDesc(natts);
- i = 0;
- while (i < natts)
- {
- newTd[i] = (Form_pg_attribute)palloc(sizeof(FormData_pg_attribute));
- memmove(newTd[i], td[i], sizeof(FormData_pg_attribute));
- i++;
- }
- return newTd;
-}
-#endif
-
/* ----------------------------------------------------------------
* ExecTypeFromTL
*
diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c
index 703767cb715..6b030b64a0e 100644
--- a/src/backend/executor/execUtils.c
+++ b/src/backend/executor/execUtils.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.72 2001/01/24 19:42:54 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.73 2001/01/29 00:39:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,17 +16,6 @@
* INTERFACE ROUTINES
* ExecAssignExprContext Common code for plan node init routines.
*
- * ExecGetTypeInfo | old execCStructs interface
- * ExecMakeTypeInfo | code from the version 1
- * ExecOrderTypeInfo | lisp system. These should
- * ExecSetTypeInfo | go away or be updated soon.
- * ExecFreeTypeInfo | -cim 11/1/89
- * ExecTupleAttributes /
- *
-
- * QueryDescGetTypeInfo - moved here from main.c
- * am not sure what uses it -cim 10/12/89
- *
* ExecOpenIndices \
* ExecCloseIndices | referenced by InitPlan, EndPlan,
* ExecInsertIndexTuples / ExecAppend, ExecReplace
@@ -261,12 +250,11 @@ MakePerTupleExprContext(EState *estate)
*/
void
ExecAssignResultType(CommonState *commonstate,
- TupleDesc tupDesc)
+ TupleDesc tupDesc, bool shouldFree)
{
- TupleTableSlot *slot;
+ TupleTableSlot *slot = commonstate->cs_ResultTupleSlot;
- slot = commonstate->cs_ResultTupleSlot;
- slot->ttc_tupleDescriptor = tupDesc;
+ ExecSetSlotDescriptor(slot, tupDesc, shouldFree);
}
/* ----------------
@@ -282,7 +270,7 @@ ExecAssignResultTypeFromOuterPlan(Plan *node, CommonState *commonstate)
outerPlan = outerPlan(node);
tupDesc = ExecGetTupType(outerPlan);
- ExecAssignResultType(commonstate, tupDesc);
+ ExecAssignResultType(commonstate, tupDesc, false);
}
/* ----------------
@@ -292,12 +280,10 @@ ExecAssignResultTypeFromOuterPlan(Plan *node, CommonState *commonstate)
void
ExecAssignResultTypeFromTL(Plan *node, CommonState *commonstate)
{
- List *targetList;
TupleDesc tupDesc;
- targetList = node->targetlist;
- tupDesc = ExecTypeFromTL(targetList);
- ExecAssignResultType(commonstate, tupDesc);
+ tupDesc = ExecTypeFromTL(node->targetlist);
+ ExecAssignResultType(commonstate, tupDesc, true);
}
/* ----------------
@@ -313,25 +299,6 @@ ExecGetResultType(CommonState *commonstate)
}
/* ----------------
- * ExecFreeResultType
- * ----------------
- */
-#ifdef NOT_USED
-void
-ExecFreeResultType(CommonState *commonstate)
-{
- TupleTableSlot *slot;
- TupleDesc tupType;
-
- slot = commonstate->cs_ResultTupleSlot;
- tupType = slot->ttc_tupleDescriptor;
-
- ExecFreeTypeInfo(tupType);
-}
-
-#endif
-
-/* ----------------
* ExecAssignProjectionInfo
forms the projection information from the node's targetlist
* ----------------
@@ -413,29 +380,6 @@ ExecFreeExprContext(CommonState *commonstate)
commonstate->cs_ExprContext = NULL;
}
-/* ----------------
- * ExecFreeTypeInfo
- * ----------------
- */
-#ifdef NOT_USED
-void
-ExecFreeTypeInfo(CommonState *commonstate)
-{
- TupleDesc tupDesc;
-
- tupDesc = commonstate->cs_ResultTupleSlot->ttc_tupleDescriptor;
- if (tupDesc == NULL)
- return;
-
- /* ----------------
- * clean up memory used.
- * ----------------
- */
- FreeTupleDesc(tupDesc);
- commonstate->cs_ResultTupleSlot->ttc_tupleDescriptor = NULL;
-}
-#endif
-
/* ----------------------------------------------------------------
* the following scan type support functions are for
* those nodes which are stubborn and return tuples in
@@ -459,36 +403,16 @@ ExecGetScanType(CommonScanState *csstate)
}
/* ----------------
- * ExecFreeScanType
- * ----------------
- */
-#ifdef NOT_USED
-void
-ExecFreeScanType(CommonScanState *csstate)
-{
- TupleTableSlot *slot;
- TupleDesc tupType;
-
- slot = csstate->css_ScanTupleSlot;
- tupType = slot->ttc_tupleDescriptor;
-
- ExecFreeTypeInfo(tupType);
-}
-
-#endif
-
-/* ----------------
* ExecAssignScanType
* ----------------
*/
void
ExecAssignScanType(CommonScanState *csstate,
- TupleDesc tupDesc)
+ TupleDesc tupDesc, bool shouldFree)
{
- TupleTableSlot *slot;
+ TupleTableSlot *slot = csstate->css_ScanTupleSlot;
- slot = (TupleTableSlot *) csstate->css_ScanTupleSlot;
- slot->ttc_tupleDescriptor = tupDesc;
+ ExecSetSlotDescriptor(slot, tupDesc, shouldFree);
}
/* ----------------
@@ -504,155 +428,11 @@ ExecAssignScanTypeFromOuterPlan(Plan *node, CommonScanState *csstate)
outerPlan = outerPlan(node);
tupDesc = ExecGetTupType(outerPlan);
- ExecAssignScanType(csstate, tupDesc);
+ ExecAssignScanType(csstate, tupDesc, false);
}
/* ----------------------------------------------------------------
- * ExecTypeFromTL support routines.
- *
- * these routines are used mainly from ExecTypeFromTL.
- * -cim 6/12/90
- *
- * old comments
- * Routines dealing with the structure 'attribute' which conatains
- * the type information about attributes in a tuple:
- *
- * ExecMakeTypeInfo(noType)
- * returns pointer to array of 'noType' structure 'attribute'.
- * ExecSetTypeInfo(index, typeInfo, attNum, attLen)
- * sets the element indexed by 'index' in typeInfo with
- * the values: attNum, attLen.
- * ExecFreeTypeInfo(typeInfo)
- * frees the structure 'typeInfo'.
- * ----------------------------------------------------------------
- */
-
-/* ----------------
- * ExecSetTypeInfo
- *
- * This initializes fields of a single attribute in a
- * tuple descriptor from the specified parameters.
- *
- * XXX this duplicates much of the functionality of TupleDescInitEntry.
- * the routines should be moved to the same place and be rewritten
- * to share common code.
- * ----------------
- */
-#ifdef NOT_USED
-void
-ExecSetTypeInfo(int index,
- TupleDesc typeInfo,
- Oid typeID,
- int attNum,
- int attLen,
- char *attName,
- bool attbyVal,
- char attalign)
-{
- Form_pg_attribute att;
-
- /* ----------------
- * get attribute pointer and preform a sanity check..
- * ----------------
- */
- att = typeInfo[index];
- if (att == NULL)
- elog(ERROR, "ExecSetTypeInfo: trying to assign through NULL");
-
- /* ----------------
- * assign values to the tuple descriptor, being careful not
- * to copy a null attName..
- *
- * XXX it is unknown exactly what information is needed to
- * initialize the attribute struct correctly so for now
- * we use 0. this should be fixed -- otherwise we run the
- * risk of using garbage data. -cim 5/5/91
- * ----------------
- */
- att->attrelid = 0; /* dummy value */
-
- if (attName != (char *) NULL)
- StrNCpy(NameStr(att->attname), attName, NAMEDATALEN);
- else
- MemSet(NameStr(att->attname), 0, NAMEDATALEN);
-
- att->atttypid = typeID;
- att->attdefrel = 0; /* dummy value */
- att->attdispersion = 0; /* dummy value */
- att->atttyparg = 0; /* dummy value */
- att->attlen = attLen;
- att->attnum = attNum;
- att->attbound = 0; /* dummy value */
- att->attbyval = attbyVal;
- att->attcanindex = 0; /* dummy value */
- att->attproc = 0; /* dummy value */
- att->attnelems = 0; /* dummy value */
- att->attcacheoff = -1;
- att->atttypmod = -1;
- att->attisset = false;
- att->attstorage = 'p';
- att->attalign = attalign;
-}
-
-/* ----------------
- * ExecFreeTypeInfo frees the array of attributes
- * created by ExecMakeTypeInfo and returned by ExecTypeFromTL
- * ----------------
- */
-void
-ExecFreeTypeInfo(TupleDesc typeInfo)
-{
- /* ----------------
- * do nothing if asked to free a null pointer
- * ----------------
- */
- if (typeInfo == NULL)
- return;
-
- /* ----------------
- * the entire array of typeinfo pointers created by
- * ExecMakeTypeInfo was allocated with a single palloc()
- * so we can deallocate the whole array with a single pfree().
- * (we should not try and free all the elements in the array)
- * -cim 6/12/90
- * ----------------
- */
- pfree(typeInfo);
-}
-
-
-/* ----------------------------------------------------------------
- * QueryDescGetTypeInfo
- *
- *| I don't know how this is used, all I know is that it
- *| appeared one day in main.c so I moved it here. -cim 11/1/89
- * ----------------------------------------------------------------
- */
-TupleDesc
-QueryDescGetTypeInfo(QueryDesc *queryDesc)
-{
- Plan *plan;
- TupleDesc tupleType;
- List *targetList;
- AttrInfo *attinfo = (AttrInfo *) palloc(sizeof(AttrInfo));
-
- plan = queryDesc->plantree;
- tupleType = (TupleDesc) ExecGetTupType(plan);
-/*
- targetList = plan->targetlist;
-
- attinfo->numAttr = ExecTargetListLength(targetList);
- attinfo->attrs = tupleType;
-*/
- attinfo->numAttr = tupleType->natts;
- attinfo->attrs = tupleType->attrs;
- return attinfo;
-}
-
-#endif
-
-/* ----------------------------------------------------------------
* ExecInsertIndexTuples support
* ----------------------------------------------------------------
*/
diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c
index 18a0e0cbb3b..575f33d84b6 100644
--- a/src/backend/executor/functions.c
+++ b/src/backend/executor/functions.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.42 2001/01/24 19:42:54 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.43 2001/01/29 00:39:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -24,7 +24,6 @@
#include "tcop/tcopprot.h"
#include "tcop/utility.h"
#include "utils/builtins.h"
-#include "utils/datum.h"
#include "utils/syscache.h"
@@ -73,7 +72,7 @@ typedef SQLFunctionCache *SQLFunctionCachePtr;
static execution_state *init_execution_state(char *src,
Oid *argOidVect, int nargs);
static void init_sql_fcache(FmgrInfo *finfo);
-static TupleDesc postquel_start(execution_state *es);
+static void postquel_start(execution_state *es);
static TupleTableSlot *postquel_getnext(execution_state *es);
static void postquel_end(execution_state *es);
static void postquel_sub_params(execution_state *es, FunctionCallInfo fcinfo);
@@ -82,24 +81,6 @@ static Datum postquel_execute(execution_state *es,
SQLFunctionCachePtr fcache);
-static Datum
-ProjectAttribute(HeapTuple tup,
- AttrNumber attrno,
- TupleDesc TD,
- bool *isnullP)
-{
- Datum val;
-
- val = heap_getattr(tup, attrno, TD, isnullP);
-
- if (*isnullP)
- return val;
-
- return datumCopy(val,
- TD->attrs[attrno - 1]->attbyval,
- TD->attrs[attrno - 1]->attlen);
-}
-
static execution_state *
init_execution_state(char *src, Oid *argOidVect, int nargs)
{
@@ -240,18 +221,7 @@ init_sql_fcache(FmgrInfo *finfo)
* allocated by the executor (i.e. slots and tuples) is freed.
*/
if (!finfo->fn_retset && !fcache->typbyval)
- {
- TupleTableSlot *slot;
-
- slot = makeNode(TupleTableSlot);
- slot->val = (HeapTuple) NULL;
- slot->ttc_shouldFree = true;
- slot->ttc_descIsNew = true;
- slot->ttc_tupleDescriptor = (TupleDesc) NULL;
- slot->ttc_buffer = InvalidBuffer;
-
- fcache->funcSlot = slot;
- }
+ fcache->funcSlot = MakeTupleTableSlot();
else
fcache->funcSlot = NULL;
@@ -289,7 +259,7 @@ init_sql_fcache(FmgrInfo *finfo)
}
-static TupleDesc
+static void
postquel_start(execution_state *es)
{
@@ -298,8 +268,8 @@ postquel_start(execution_state *es)
* 30-8-1996
*/
if (es->qd->operation == CMD_UTILITY)
- return (TupleDesc) NULL;
- return ExecutorStart(es->qd, es->estate);
+ return;
+ ExecutorStart(es->qd, es->estate);
}
static TupleTableSlot *
@@ -379,11 +349,11 @@ copy_function_result(SQLFunctionCachePtr fcache,
* If first time through, we have to initialize the funcSlot's
* tuple descriptor.
*/
- if (TupIsNull(funcSlot))
+ if (funcSlot->ttc_tupleDescriptor == NULL)
{
- resultTd = resultSlot->ttc_tupleDescriptor;
- funcSlot->ttc_tupleDescriptor = CreateTupleDescCopy(resultTd);
- funcSlot->ttc_descIsNew = true;
+ resultTd = CreateTupleDescCopy(resultSlot->ttc_tupleDescriptor);
+ ExecSetSlotDescriptor(funcSlot, resultTd, true);
+ ExecSetSlotDescriptorIsNew(funcSlot, true);
}
newTuple = heap_copytuple(resultTuple);
@@ -460,10 +430,15 @@ postquel_execute(execution_state *es,
}
else
{
- value = ProjectAttribute(resSlot->val,
- 1,
- resSlot->ttc_tupleDescriptor,
- &fcinfo->isnull);
+ value = heap_getattr(resSlot->val,
+ 1,
+ resSlot->ttc_tupleDescriptor,
+ &(fcinfo->isnull));
+ /*
+ * Note: if result type is pass-by-reference then we are
+ * returning a pointer into the tuple copied by
+ * copy_function_result. This is OK.
+ */
}
/*
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index 0c6703fb70c..a3fc2f545cb 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeHashjoin.c,v 1.35 2001/01/24 19:42:54 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeHashjoin.c,v 1.36 2001/01/29 00:39:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -400,7 +400,8 @@ ExecInitHashJoin(HashJoin *node, EState *estate, Plan *parent)
ExecAssignProjectionInfo((Plan *) node, &hjstate->jstate);
ExecSetSlotDescriptor(hjstate->hj_OuterTupleSlot,
- ExecGetTupType(outerNode));
+ ExecGetTupType(outerNode),
+ false);
/* ----------------
* initialize hash-specific info
diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c
index 7ed93de0848..c0369e8f4cd 100644
--- a/src/backend/executor/nodeIndexscan.c
+++ b/src/backend/executor/nodeIndexscan.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.56 2001/01/24 19:42:54 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.57 2001/01/29 00:39:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -121,13 +121,11 @@ IndexNext(IndexScan *node)
if (estate->es_evTupleNull[node->scan.scanrelid - 1])
return slot; /* return empty slot */
- /* probably ought to use ExecStoreTuple here... */
- slot->val = estate->es_evTuple[node->scan.scanrelid - 1];
- slot->ttc_shouldFree = false;
-
- econtext->ecxt_scantuple = slot;
+ ExecStoreTuple(estate->es_evTuple[node->scan.scanrelid - 1],
+ slot, InvalidBuffer, false);
/* Does the tuple meet any of the OR'd indxqual conditions? */
+ econtext->ecxt_scantuple = slot;
ResetExprContext(econtext);
@@ -1043,7 +1041,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
* get the scan type from the relation descriptor.
* ----------------
*/
- ExecAssignScanType(scanstate, RelationGetDescr(currentRelation));
+ ExecAssignScanType(scanstate, RelationGetDescr(currentRelation), false);
ExecAssignResultTypeFromTL((Plan *) node, &scanstate->cstate);
/* ----------------
diff --git a/src/backend/executor/nodeMergejoin.c b/src/backend/executor/nodeMergejoin.c
index 359d0c7bc5d..fd8868a4a54 100644
--- a/src/backend/executor/nodeMergejoin.c
+++ b/src/backend/executor/nodeMergejoin.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeMergejoin.c,v 1.41 2001/01/24 19:42:55 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeMergejoin.c,v 1.42 2001/01/29 00:39:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1505,7 +1505,8 @@ ExecInitMergeJoin(MergeJoin *node, EState *estate, Plan *parent)
mergestate->mj_MarkedTupleSlot = ExecInitExtraTupleSlot(estate);
ExecSetSlotDescriptor(mergestate->mj_MarkedTupleSlot,
- ExecGetTupType(innerPlan((Plan *) node)));
+ ExecGetTupType(innerPlan((Plan *) node)),
+ false);
switch (node->join.jointype)
{
diff --git a/src/backend/executor/nodeSeqscan.c b/src/backend/executor/nodeSeqscan.c
index a10e8d4ed96..a39128ff2f0 100644
--- a/src/backend/executor/nodeSeqscan.c
+++ b/src/backend/executor/nodeSeqscan.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeSeqscan.c,v 1.26 2001/01/24 19:42:55 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeSeqscan.c,v 1.27 2001/01/29 00:39:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -77,9 +77,8 @@ SeqNext(SeqScan *node)
if (estate->es_evTupleNull[node->scanrelid - 1])
return slot; /* return empty slot */
- /* probably ought to use ExecStoreTuple here... */
- slot->val = estate->es_evTuple[node->scanrelid - 1];
- slot->ttc_shouldFree = false;
+ ExecStoreTuple(estate->es_evTuple[node->scanrelid - 1],
+ slot, InvalidBuffer, false);
/*
* Note that unlike IndexScan, SeqScan never use keys in
@@ -181,7 +180,7 @@ InitScanRelation(SeqScan *node, EState *estate,
scanstate->css_currentRelation = currentRelation;
scanstate->css_currentScanDesc = currentScanDesc;
- ExecAssignScanType(scanstate, RelationGetDescr(currentRelation));
+ ExecAssignScanType(scanstate, RelationGetDescr(currentRelation), false);
return reloid;
}
diff --git a/src/backend/executor/nodeSort.c b/src/backend/executor/nodeSort.c
index 99bd3b76437..b8c057c3397 100644
--- a/src/backend/executor/nodeSort.c
+++ b/src/backend/executor/nodeSort.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeSort.c,v 1.30 2001/01/24 19:42:55 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeSort.c,v 1.31 2001/01/29 00:39:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -172,7 +172,6 @@ ExecSort(Sort *node)
break;
tuplesort_puttuple(tuplesortstate, (void *) slot->val);
- ExecClearTuple(slot);
}
/* ----------------
@@ -188,11 +187,10 @@ ExecSort(Sort *node)
estate->es_direction = dir;
/* ----------------
- * make sure the tuple descriptor is up to date
+ * make sure the tuple descriptor is up to date (is this needed?)
* ----------------
*/
- slot = (TupleTableSlot *) sortstate->csstate.cstate.cs_ResultTupleSlot;
- slot->ttc_tupleDescriptor = tupDesc;
+ ExecAssignResultType(&sortstate->csstate.cstate, tupDesc, false);
/* ----------------
* finally set the sorted flag to true
@@ -201,8 +199,6 @@ ExecSort(Sort *node)
sortstate->sort_Done = true;
SO1_printf(stderr, "ExecSort: sorting done.\n");
}
- else
- slot = (TupleTableSlot *) sortstate->csstate.cstate.cs_ResultTupleSlot;
SO1_printf("ExecSort: %s\n",
"retrieving tuple from tuplesort");
@@ -216,6 +212,7 @@ ExecSort(Sort *node)
ScanDirectionIsForward(dir),
&should_free);
+ slot = sortstate->csstate.cstate.cs_ResultTupleSlot;
return ExecStoreTuple(heapTuple, slot, InvalidBuffer, should_free);
}
@@ -347,6 +344,12 @@ ExecEndSort(Sort *node)
tuplesort_end((Tuplesortstate *) sortstate->tuplesortstate);
sortstate->tuplesortstate = NULL;
+ if (sortstate->sort_Keys != NULL)
+ pfree(sortstate->sort_Keys);
+
+ pfree(sortstate);
+ node->sortstate = NULL;
+
SO1_printf("ExecEndSort: %s\n",
"sort node shutdown");
}
diff --git a/src/backend/executor/nodeSubqueryscan.c b/src/backend/executor/nodeSubqueryscan.c
index 617a41d447d..4c9144bc3a8 100644
--- a/src/backend/executor/nodeSubqueryscan.c
+++ b/src/backend/executor/nodeSubqueryscan.c
@@ -12,7 +12,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeSubqueryscan.c,v 1.3 2001/01/24 19:42:55 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeSubqueryscan.c,v 1.4 2001/01/29 00:39:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -77,9 +77,8 @@ SubqueryNext(SubqueryScan *node)
if (estate->es_evTupleNull[node->scan.scanrelid - 1])
return slot; /* return empty slot */
- /* probably ought to use ExecStoreTuple here... */
- slot->val = estate->es_evTuple[node->scan.scanrelid - 1];
- slot->ttc_shouldFree = false;
+ ExecStoreTuple(estate->es_evTuple[node->scan.scanrelid - 1],
+ slot, InvalidBuffer, false);
/* Flag for the next call that no more tuples */
estate->es_evTupleNull[node->scan.scanrelid - 1] = true;
diff --git a/src/backend/executor/nodeTidscan.c b/src/backend/executor/nodeTidscan.c
index 49f7594c6f7..a5c0299d289 100644
--- a/src/backend/executor/nodeTidscan.c
+++ b/src/backend/executor/nodeTidscan.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeTidscan.c,v 1.13 2001/01/24 19:42:55 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeTidscan.c,v 1.14 2001/01/29 00:39:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -110,9 +110,8 @@ TidNext(TidScan *node)
if (estate->es_evTupleNull[node->scan.scanrelid - 1])
return slot; /* return empty slot */
- /* probably ought to use ExecStoreTuple here... */
- slot->val = estate->es_evTuple[node->scan.scanrelid - 1];
- slot->ttc_shouldFree = false;
+ ExecStoreTuple(estate->es_evTuple[node->scan.scanrelid - 1],
+ slot, InvalidBuffer, false);
/* Flag for the next call that no more tuples */
estate->es_evTupleNull[node->scan.scanrelid - 1] = true;
@@ -487,7 +486,7 @@ ExecInitTidScan(TidScan *node, EState *estate, Plan *parent)
* get the scan type from the relation descriptor.
* ----------------
*/
- ExecAssignScanType(scanstate, RelationGetDescr(currentRelation));
+ ExecAssignScanType(scanstate, RelationGetDescr(currentRelation), false);
ExecAssignResultTypeFromTL((Plan *) node, &scanstate->cstate);
/*