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/nodeMergejoin.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/nodeMergejoin.c')
-rw-r--r-- | src/backend/executor/nodeMergejoin.c | 110 |
1 files changed, 67 insertions, 43 deletions
diff --git a/src/backend/executor/nodeMergejoin.c b/src/backend/executor/nodeMergejoin.c index 0d522f0d515..a3f92b06901 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.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 |