Fix (I hope) resource leakage in EvalPlanQual: open subplans must be
authorTom Lane
Fri, 7 Apr 2000 00:59:17 +0000 (00:59 +0000)
committerTom Lane
Fri, 7 Apr 2000 00:59:17 +0000 (00:59 +0000)
properly shut down in EndPlan, else we fail to free buffers and so forth
that they hold.

src/backend/executor/execMain.c

index 3dad4500169e0c0e9f1bbbec8d42420ccf6a123a..d19baaa84dc93814f4ccff87398eaad3de6afdff 100644 (file)
@@ -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,
@@ -925,6 +926,12 @@ EndPlan(Plan *plan, EState *estate)
    resultRelationInfo = estate->es_result_relation_info;
    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
     */
@@ -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;
+   }
+}