diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2000-07-12 02:37:39 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2000-07-12 02:37:39 +0000 |
commit | badce86a2c327b40c6146242526d1523455d64a6 (patch) | |
tree | 6e0cb658889a2688e76d9ac19a56555c5eb0e738 /src/backend/executor/nodeGroup.c | |
parent | 46fb9c29e2990ba470bb741ff6dd60f2ae218e64 (diff) | |
download | postgresql-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.c | 63 |
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; } /* |