1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-13 07:41:39 +03:00

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.
This commit is contained in:
Tom Lane
2000-07-12 02:37:39 +00:00
parent 46fb9c29e2
commit badce86a2c
53 changed files with 1536 additions and 1584 deletions

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeMergejoin.c,v 1.35 2000/06/15 04:09:52 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/nodeMergejoin.c,v 1.36 2000/07/12 02:37:03 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -202,45 +202,53 @@ MJFormSkipQual(List *qualList, char *replaceopname)
static bool
MergeCompare(List *eqQual, List *compareQual, ExprContext *econtext)
{
bool result;
MemoryContext oldContext;
List *clause;
List *eqclause;
Datum const_value;
bool isNull;
bool isDone;
/* ----------------
* if we have no compare qualification, return nil
* ----------------
/*
* Do expression eval in short-lived context.
*/
if (compareQual == NIL)
return false;
oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
/* ----------------
* for each pair of clauses, test them until
* our compare conditions are satisfied
* our compare conditions are satisfied.
* if we reach the end of the list, none of our key greater-than
* conditions were satisfied so we return false.
* ----------------
*/
result = false; /* assume 'false' result */
eqclause = eqQual;
foreach(clause, compareQual)
{
Datum const_value;
bool isNull;
bool isDone;
/* ----------------
* first test if our compare clause is satisfied.
* if so then return true. ignore isDone, don't iterate in
* quals.
* if so then return true.
*
* A NULL result is considered false.
* ignore isDone, don't iterate in quals.
* ----------------
*/
const_value = (Datum)
ExecEvalExpr((Node *) lfirst(clause), econtext, &isNull, &isDone);
const_value = ExecEvalExpr((Node *) lfirst(clause), econtext,
&isNull, &isDone);
if (DatumGetInt32(const_value) != 0)
return true;
if (DatumGetBool(const_value) && !isNull)
{
result = true;
break;
}
/* ----------------
* ok, the compare clause failed so we test if the keys
* are equal... if key1 != key2, we return false.
* otherwise key1 = key2 so we move on to the next pair of keys.
*
* ignore isDone, don't iterate in quals.
* ----------------
*/
const_value = ExecEvalExpr((Node *) lfirst(eqclause),
@ -248,17 +256,15 @@ MergeCompare(List *eqQual, List *compareQual, ExprContext *econtext)
&isNull,
&isDone);
if (DatumGetInt32(const_value) == 0)
return false;
if (! DatumGetBool(const_value) || isNull)
break; /* return false */
eqclause = lnext(eqclause);
}
/* ----------------
* if we get here then it means none of our key greater-than
* conditions were satisfied so we return false.
* ----------------
*/
return false;
MemoryContextSwitchTo(oldContext);
return result;
}
/* ----------------------------------------------------------------
@ -403,24 +409,18 @@ ExecMergeJoin(MergeJoin *node)
List *qual;
bool qualResult;
bool compareResult;
Plan *innerPlan;
TupleTableSlot *innerTupleSlot;
Plan *outerPlan;
TupleTableSlot *outerTupleSlot;
ExprContext *econtext;
#ifdef ENABLE_OUTER_JOINS
/*
* These should be set from the expression context! - thomas
* 1999-02-20
*/
static bool isLeftJoin = true;
static bool isRightJoin = false;
#endif
/* ----------------
@ -448,20 +448,34 @@ ExecMergeJoin(MergeJoin *node)
}
/* ----------------
* ok, everything is setup.. let's go to work
* Reset per-tuple memory context to free any expression evaluation
* storage allocated in the previous tuple cycle.
* ----------------
*/
ResetExprContext(econtext);
/* ----------------
* Check to see if we're still projecting out tuples from a previous
* join tuple (because there is a function-returning-set in the
* projection expressions). If so, try to project another one.
* ----------------
*/
if (mergestate->jstate.cs_TupFromTlist)
{
TupleTableSlot *result;
ProjectionInfo *projInfo;
bool isDone;
projInfo = mergestate->jstate.cs_ProjInfo;
result = ExecProject(projInfo, &isDone);
result = ExecProject(mergestate->jstate.cs_ProjInfo, &isDone);
if (!isDone)
return result;
/* Done with that source tuple... */
mergestate->jstate.cs_TupFromTlist = false;
}
/* ----------------
* ok, everything is setup.. let's go to work
* ----------------
*/
for (;;)
{
/* ----------------
@ -547,6 +561,8 @@ ExecMergeJoin(MergeJoin *node)
case EXEC_MJ_JOINTEST:
MJ_printf("ExecMergeJoin: EXEC_MJ_JOINTEST\n");
ResetExprContext(econtext);
qualResult = ExecQual((List *) mergeclauses, econtext, false);
MJ_DEBUG_QUAL(mergeclauses, qualResult);
@ -565,6 +581,14 @@ ExecMergeJoin(MergeJoin *node)
MJ_printf("ExecMergeJoin: EXEC_MJ_JOINTUPLES\n");
mergestate->mj_JoinState = EXEC_MJ_NEXTINNER;
/*
* Check the qpqual to see if we actually want to return
* this join tuple. If not, can proceed with merge.
*
* (We don't bother with a ResetExprContext here, on the
* assumption that we just did one before checking the merge
* qual. One per tuple should be sufficient.)
*/
qualResult = ExecQual((List *) qual, econtext, false);
MJ_DEBUG_QUAL(qual, qualResult);
@ -693,6 +717,8 @@ ExecMergeJoin(MergeJoin *node)
innerTupleSlot = econtext->ecxt_innertuple;
econtext->ecxt_innertuple = mergestate->mj_MarkedTupleSlot;
ResetExprContext(econtext);
qualResult = ExecQual((List *) mergeclauses, econtext, false);
MJ_DEBUG_QUAL(mergeclauses, qualResult);
@ -709,11 +735,7 @@ ExecMergeJoin(MergeJoin *node)
*/
ExecRestrPos(innerPlan);
#if 0
mergestate->mj_JoinState = EXEC_MJ_JOINTEST;
#endif
mergestate->mj_JoinState = EXEC_MJ_JOINTUPLES;
}
else
{
@ -777,6 +799,8 @@ ExecMergeJoin(MergeJoin *node)
* we update the marked tuple and go join them.
* ----------------
*/
ResetExprContext(econtext);
qualResult = ExecQual((List *) mergeclauses, econtext, false);
MJ_DEBUG_QUAL(mergeclauses, qualResult);
@ -886,6 +910,8 @@ ExecMergeJoin(MergeJoin *node)
* we update the marked tuple and go join them.
* ----------------
*/
ResetExprContext(econtext);
qualResult = ExecQual((List *) mergeclauses, econtext, false);
MJ_DEBUG_QUAL(mergeclauses, qualResult);
@ -1142,12 +1168,9 @@ ExecInitMergeJoin(MergeJoin *node, EState *estate, Plan *parent)
/* ----------------
* Miscellaneous initialization
*
* + assign node's base_id
* + assign debugging hooks and
* + create expression context for node
* ----------------
*/
ExecAssignNodeBaseInfo(estate, &mergestate->jstate, parent);
ExecAssignExprContext(estate, &mergestate->jstate);
#define MERGEJOIN_NSLOTS 2
@ -1251,6 +1274,7 @@ ExecEndMergeJoin(MergeJoin *node)
* ----------------
*/
ExecFreeProjectionInfo(&mergestate->jstate);
ExecFreeExprContext(&mergestate->jstate);
/* ----------------
* shut down the subplans