diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2000-04-07 00:59:17 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2000-04-07 00:59:17 +0000 |
commit | e4d8d43c52927960c4f0741c7183dc7b9259a4e1 (patch) | |
tree | 73dd2c231f1c7ca22aaf244dab077284166c7b52 /src/backend/executor/execMain.c | |
parent | 891039c15f0d0a0a7adba71a7ceb77fa74bb3b9c (diff) | |
download | postgresql-e4d8d43c52927960c4f0741c7183dc7b9259a4e1.tar.gz postgresql-e4d8d43c52927960c4f0741c7183dc7b9259a4e1.zip |
Fix (I hope) resource leakage in EvalPlanQual: open subplans must be
properly shut down in EndPlan, else we fail to free buffers and so forth
that they hold.
Diffstat (limited to 'src/backend/executor/execMain.c')
-rw-r--r-- | src/backend/executor/execMain.c | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index 3dad4500169..d19baaa84dc 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -27,7 +27,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.110 2000/03/09 05:15:33 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.111 2000/04/07 00:59:17 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -73,6 +73,7 @@ static void ExecDelete(TupleTableSlot *slot, ItemPointer tupleid, static void ExecReplace(TupleTableSlot *slot, ItemPointer tupleid, EState *estate); static TupleTableSlot *EvalPlanQualNext(EState *estate); +static void EndEvalPlanQual(EState *estate); static void ExecCheckQueryPerms(CmdType operation, Query *parseTree, Plan *plan); static void ExecCheckPlanPerms(Plan *plan, CmdType operation, @@ -926,6 +927,12 @@ EndPlan(Plan *plan, EState *estate) intoRelationDesc = estate->es_into_relation_descriptor; /* + * shut down any PlanQual processing we were doing + */ + if (estate->es_evalPlanQual != NULL) + EndEvalPlanQual(estate); + + /* * shut down the query */ ExecEndNode(plan, plan); @@ -2007,3 +2014,36 @@ lpqnext:; return (slot); } + +static void +EndEvalPlanQual(EState *estate) +{ + evalPlanQual *epq = (evalPlanQual *) estate->es_evalPlanQual; + EState *epqstate = &(epq->estate); + evalPlanQual *oldepq; + + if (epq->rti == 0) /* still live? */ + return; + + for (;;) + { + ExecEndNode(epq->plan, epq->plan); + epqstate->es_tupleTable->next = 0; + heap_freetuple(epqstate->es_evTuple[epq->rti - 1]); + epqstate->es_evTuple[epq->rti - 1] = NULL; + /* pop old PQ from the stack */ + oldepq = (evalPlanQual *) epqstate->es_evalPlanQual; + if (oldepq == (evalPlanQual *) NULL) + { + epq->rti = 0; /* this is the first (oldest) */ + estate->es_useEvalPlan = false; /* PQ - mark as free */ + break; + } + Assert(oldepq->rti != 0); + /* push current PQ to freePQ stack */ + oldepq->free = epq; + epq = oldepq; + epqstate = &(epq->estate); + estate->es_evalPlanQual = (Pointer) epq; + } +} |