aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeGroup.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2000-07-12 02:37:39 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2000-07-12 02:37:39 +0000
commitbadce86a2c327b40c6146242526d1523455d64a6 (patch)
tree6e0cb658889a2688e76d9ac19a56555c5eb0e738 /src/backend/executor/nodeGroup.c
parent46fb9c29e2990ba470bb741ff6dd60f2ae218e64 (diff)
downloadpostgresql-badce86a2c327b40c6146242526d1523455d64a6.tar.gz
postgresql-badce86a2c327b40c6146242526d1523455d64a6.zip
First stage of reclaiming memory in executor by resetting short-term
memory contexts. Currently, only leaks in expressions executed as quals or projections are handled. Clean up some old dead cruft in executor while at it --- unused fields in state nodes, that sort of thing.
Diffstat (limited to 'src/backend/executor/nodeGroup.c')
-rw-r--r--src/backend/executor/nodeGroup.c63
1 files changed, 42 insertions, 21 deletions
diff --git a/src/backend/executor/nodeGroup.c b/src/backend/executor/nodeGroup.c
index d1ae02616c1..8a445b53d41 100644
--- a/src/backend/executor/nodeGroup.c
+++ b/src/backend/executor/nodeGroup.c
@@ -15,7 +15,7 @@
* locate group boundaries.
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeGroup.c,v 1.36 2000/05/30 04:24:45 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeGroup.c,v 1.37 2000/07/12 02:37:03 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -68,13 +68,11 @@ ExecGroupEveryTuple(Group *node)
EState *estate;
ExprContext *econtext;
TupleDesc tupdesc;
-
HeapTuple outerTuple = NULL;
HeapTuple firsttuple;
TupleTableSlot *outerslot;
ProjectionInfo *projInfo;
TupleTableSlot *resultSlot;
-
bool isDone;
/* ---------------------
@@ -84,14 +82,16 @@ ExecGroupEveryTuple(Group *node)
grpstate = node->grpstate;
if (grpstate->grp_done)
return NULL;
-
estate = node->plan.state;
-
econtext = grpstate->csstate.cstate.cs_ExprContext;
-
tupdesc = ExecGetScanType(&grpstate->csstate);
- /* if we haven't returned first tuple of new group yet ... */
+ /*
+ * We need not call ResetExprContext here because execTuplesMatch
+ * will reset the per-tuple memory context once per input tuple.
+ */
+
+ /* if we haven't returned first tuple of a new group yet ... */
if (grpstate->grp_useFirstTuple)
{
grpstate->grp_useFirstTuple = FALSE;
@@ -130,7 +130,8 @@ ExecGroupEveryTuple(Group *node)
if (!execTuplesMatch(firsttuple, outerTuple,
tupdesc,
node->numCols, node->grpColIdx,
- grpstate->eqfunctions))
+ grpstate->eqfunctions,
+ econtext->ecxt_per_tuple_memory))
{
/*
@@ -179,13 +180,11 @@ ExecGroupOneTuple(Group *node)
EState *estate;
ExprContext *econtext;
TupleDesc tupdesc;
-
HeapTuple outerTuple = NULL;
HeapTuple firsttuple;
TupleTableSlot *outerslot;
ProjectionInfo *projInfo;
TupleTableSlot *resultSlot;
-
bool isDone;
/* ---------------------
@@ -195,13 +194,15 @@ ExecGroupOneTuple(Group *node)
grpstate = node->grpstate;
if (grpstate->grp_done)
return NULL;
-
estate = node->plan.state;
-
econtext = node->grpstate->csstate.cstate.cs_ExprContext;
-
tupdesc = ExecGetScanType(&grpstate->csstate);
+ /*
+ * We need not call ResetExprContext here because execTuplesMatch
+ * will reset the per-tuple memory context once per input tuple.
+ */
+
firsttuple = grpstate->grp_firstTuple;
if (firsttuple == NULL)
{
@@ -237,7 +238,8 @@ ExecGroupOneTuple(Group *node)
if (!execTuplesMatch(firsttuple, outerTuple,
tupdesc,
node->numCols, node->grpColIdx,
- grpstate->eqfunctions))
+ grpstate->eqfunctions,
+ econtext->ecxt_per_tuple_memory))
break;
}
@@ -296,10 +298,8 @@ ExecInitGroup(Group *node, EState *estate, Plan *parent)
grpstate->grp_firstTuple = NULL;
/*
- * assign node's base id and create expression context
+ * create expression context
*/
- ExecAssignNodeBaseInfo(estate, &grpstate->csstate.cstate,
- (Plan *) parent);
ExecAssignExprContext(estate, &grpstate->csstate.cstate);
#define GROUP_NSLOTS 2
@@ -360,6 +360,7 @@ ExecEndGroup(Group *node)
grpstate = node->grpstate;
ExecFreeProjectionInfo(&grpstate->csstate.cstate);
+ ExecFreeExprContext(&grpstate->csstate.cstate);
outerPlan = outerPlan(node);
ExecEndNode(outerPlan, (Plan *) node);
@@ -406,6 +407,9 @@ ExecReScanGroup(Group *node, ExprContext *exprCtxt, Plan *parent)
* numCols: the number of attributes to be examined
* matchColIdx: array of attribute column numbers
* eqFunctions: array of fmgr lookup info for the equality functions to use
+ * evalContext: short-term memory context for executing the functions
+ *
+ * NB: evalContext is reset each time!
*/
bool
execTuplesMatch(HeapTuple tuple1,
@@ -413,16 +417,25 @@ execTuplesMatch(HeapTuple tuple1,
TupleDesc tupdesc,
int numCols,
AttrNumber *matchColIdx,
- FmgrInfo *eqfunctions)
+ FmgrInfo *eqfunctions,
+ MemoryContext evalContext)
{
+ MemoryContext oldContext;
+ bool result;
int i;
+ /* Reset and switch into the temp context. */
+ MemoryContextReset(evalContext);
+ oldContext = MemoryContextSwitchTo(evalContext);
+
/*
* We cannot report a match without checking all the fields, but we
* can report a non-match as soon as we find unequal fields. So,
* start comparing at the last field (least significant sort key).
* That's the most likely to be different...
*/
+ result = true;
+
for (i = numCols; --i >= 0;)
{
AttrNumber att = matchColIdx[i];
@@ -442,7 +455,10 @@ execTuplesMatch(HeapTuple tuple1,
&isNull2);
if (isNull1 != isNull2)
- return FALSE; /* one null and one not; they aren't equal */
+ {
+ result = false; /* one null and one not; they aren't equal */
+ break;
+ }
if (isNull1)
continue; /* both are null, treat as equal */
@@ -451,10 +467,15 @@ execTuplesMatch(HeapTuple tuple1,
if (! DatumGetBool(FunctionCall2(&eqfunctions[i],
attr1, attr2)))
- return FALSE;
+ {
+ result = false; /* they aren't equal */
+ break;
+ }
}
- return TRUE;
+ MemoryContextSwitchTo(oldContext);
+
+ return result;
}
/*