aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeNestloop.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/nodeNestloop.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/nodeNestloop.c')
-rw-r--r--src/backend/executor/nodeNestloop.c61
1 files changed, 29 insertions, 32 deletions
diff --git a/src/backend/executor/nodeNestloop.c b/src/backend/executor/nodeNestloop.c
index ec71ad7ac71..0186e394367 100644
--- a/src/backend/executor/nodeNestloop.c
+++ b/src/backend/executor/nodeNestloop.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeNestloop.c,v 1.16 2000/06/15 04:09:52 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeNestloop.c,v 1.17 2000/07/12 02:37:03 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -32,18 +32,18 @@
*
* It scans the inner relation to join with current outer tuple.
*
- * If none is found, next tuple form the outer relation is retrieved
+ * If none is found, next tuple from the outer relation is retrieved
* and the inner relation is scanned from the beginning again to join
* with the outer tuple.
*
- * Nil is returned if all the remaining outer tuples are tried and
+ * NULL is returned if all the remaining outer tuples are tried and
* all fail to join with the inner tuples.
*
- * Nil is also returned if there is no tuple from inner realtion.
+ * NULL is also returned if there is no tuple from inner relation.
*
* Conditions:
* -- outerTuple contains current tuple from outer relation and
- * the right son(inner realtion) maintains "cursor" at the tuple
+ * the right son(inner relation) maintains "cursor" at the tuple
* returned previously.
* This is achieved by maintaining a scan position on the outer
* relation.
@@ -60,10 +60,8 @@ ExecNestLoop(NestLoop *node, Plan *parent)
Plan *innerPlan;
Plan *outerPlan;
bool needNewOuterTuple;
-
TupleTableSlot *outerTupleSlot;
TupleTableSlot *innerTupleSlot;
-
List *qual;
ExprContext *econtext;
@@ -77,11 +75,6 @@ ExecNestLoop(NestLoop *node, Plan *parent)
qual = node->join.qual;
outerPlan = outerPlan(&node->join);
innerPlan = innerPlan(&node->join);
-
- /* ----------------
- * initialize expression context
- * ----------------
- */
econtext = nlstate->jstate.cs_ExprContext;
/* ----------------
@@ -92,11 +85,18 @@ ExecNestLoop(NestLoop *node, Plan *parent)
econtext->ecxt_outertuple = outerTupleSlot;
/* ----------------
- * Ok, everything is setup for the join so now loop until
- * we return a qualifying join tuple..
+ * 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 (nlstate->jstate.cs_TupFromTlist)
{
TupleTableSlot *result;
@@ -105,9 +105,17 @@ ExecNestLoop(NestLoop *node, Plan *parent)
result = ExecProject(nlstate->jstate.cs_ProjInfo, &isDone);
if (!isDone)
return result;
+ /* Done with that source tuple... */
+ nlstate->jstate.cs_TupFromTlist = false;
}
+ /* ----------------
+ * Ok, everything is setup for the join so now loop until
+ * we return a qualifying join tuple..
+ * ----------------
+ */
ENL1_printf("entering main loop");
+
for (;;)
{
/* ----------------
@@ -115,15 +123,7 @@ ExecNestLoop(NestLoop *node, Plan *parent)
* and join it with the current outer tuple.
* ----------------
*/
- needNewOuterTuple = false;
-
- if (!TupIsNull(outerTupleSlot))
- ENL1_printf("have outer tuple, deal with it");
- else
- {
- ENL1_printf("outer tuple is nil, need new outer tuple");
- needNewOuterTuple = true;
- }
+ needNewOuterTuple = TupIsNull(outerTupleSlot);
/* ----------------
* if we have an outerTuple, try to get the next inner tuple.
@@ -229,9 +229,11 @@ ExecNestLoop(NestLoop *node, Plan *parent)
}
/* ----------------
- * qualification failed so we have to try again..
+ * Tuple fails qual, so free per-tuple memory and try again.
* ----------------
*/
+ ResetExprContext(econtext);
+
ENL1_printf("qualification failed, looping");
}
}
@@ -263,18 +265,14 @@ ExecInitNestLoop(NestLoop *node, EState *estate, Plan *parent)
* ----------------
*/
nlstate = makeNode(NestLoopState);
- nlstate->nl_PortalFlag = false;
node->nlstate = nlstate;
/* ----------------
- * Miscellanious initialization
+ * Miscellaneous initialization
*
- * + assign node's base_id
- * + assign debugging hooks and
* + create expression context for node
* ----------------
*/
- ExecAssignNodeBaseInfo(estate, &nlstate->jstate, parent);
ExecAssignExprContext(estate, &nlstate->jstate);
#define NESTLOOP_NSLOTS 1
@@ -348,6 +346,7 @@ ExecEndNestLoop(NestLoop *node)
* ----------------
*/
ExecFreeProjectionInfo(&nlstate->jstate);
+ ExecFreeExprContext(&nlstate->jstate);
/* ----------------
* close down subplans
@@ -386,9 +385,7 @@ ExecReScanNestLoop(NestLoop *node, ExprContext *exprCtxt, Plan *parent)
if (outerPlan->chgParam == NULL)
ExecReScan(outerPlan, exprCtxt, (Plan *) node);
- /* let outerPlan to free its result typle ... */
+ /* let outerPlan to free its result tuple ... */
nlstate->jstate.cs_OuterTupleSlot = NULL;
nlstate->jstate.cs_TupFromTlist = false;
-
- return;
}