aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeMergejoin.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/nodeMergejoin.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/nodeMergejoin.c')
-rw-r--r--src/backend/executor/nodeMergejoin.c110
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