From 7d0ab659acf5d6d410f6587f01f73cb842da2847 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Sat, 20 Mar 1999 01:13:22 +0000 Subject: [PATCH] Fix for aggregate memory leaks from Erik Riedel. --- src/backend/executor/execMain.c | 22 ++++++++++++-- src/backend/executor/execUtils.c | 50 ++++++++++++++++++++++++++++++- src/backend/executor/nodeAgg.c | 3 ++ src/backend/executor/nodeResult.c | 5 +++- 4 files changed, 76 insertions(+), 4 deletions(-) diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index 962c235818..793d8d3c36 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -26,7 +26,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.80 1999/03/19 18:56:36 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.81 1999/03/20 01:13:21 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -394,8 +394,26 @@ ExecutorEnd(QueryDesc *queryDesc, EState *estate) EndPlan(queryDesc->plantree, estate); + /* XXX - clean up some more from ExecutorStart() - er1p */ + if (NULL == estate->es_snapshot) { + /* nothing to free */ + } else { + if (estate->es_snapshot->xcnt > 0) { + pfree(estate->es_snapshot->xip); + } + pfree(estate->es_snapshot); + } + + if (NULL == estate->es_param_exec_vals) { + /* nothing to free */ + } else { + pfree(estate->es_param_exec_vals); + estate->es_param_exec_vals = NULL; + } + /* restore saved refcounts. */ BufferRefCountRestore(estate->es_refcount); + } void @@ -580,7 +598,7 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate) /* * initialize result relation stuff */ - + if (resultRelation != 0 && operation != CMD_SELECT) { /* diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c index 3a29a9f262..b6906e0a3d 100644 --- a/src/backend/executor/execUtils.c +++ b/src/backend/executor/execUtils.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.43 1999/02/13 23:15:20 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.44 1999/03/20 01:13:22 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -272,6 +272,7 @@ ExecAssignResultTypeFromTL(Plan *node, CommonState *commonstate) #endif i++; } + if (len > 0) { ExecAssignResultType(commonstate, @@ -368,6 +369,53 @@ ExecFreeProjectionInfo(CommonState *commonstate) commonstate->cs_ProjInfo = NULL; } +/* ---------------- + * ExecFreeExprContext + * ---------------- + */ +void +ExecFreeExprContext(CommonState *commonstate) +{ + ExprContext *econtext; + + /* ---------------- + * get expression context. if NULL then this node has + * none so we just return. + * ---------------- + */ + econtext = commonstate->cs_ExprContext; + if (econtext == NULL) + return; + + /* ---------------- + * clean up memory used. + * ---------------- + */ + pfree(econtext); + commonstate->cs_ExprContext = NULL; +} + +/* ---------------- + * ExecFreeTypeInfo + * ---------------- + */ +void +ExecFreeTypeInfo(CommonState *commonstate) +{ + TupleDesc tupDesc; + + tupDesc = commonstate->cs_ResultTupleSlot->ttc_tupleDescriptor; + if (tupDesc == NULL) + return; + + /* ---------------- + * clean up memory used. + * ---------------- + */ + FreeTupleDesc(tupDesc); + commonstate->cs_ResultTupleSlot->ttc_tupleDescriptor = NULL; +} + /* ---------------------------------------------------------------- * the following scan type support functions are for * those nodes which are stubborn and return tuples in diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c index d379077af5..288e16555e 100644 --- a/src/backend/executor/nodeAgg.c +++ b/src/backend/executor/nodeAgg.c @@ -110,6 +110,7 @@ ExecAgg(Agg *node) isNull2 = FALSE; bool qual_result; + Datum oldVal = (Datum) NULL; /* XXX - so that we can save and free on each iteration - er1p */ /* --------------------- * get state info from node @@ -372,8 +373,10 @@ ExecAgg(Agg *node) */ args[0] = value1[aggno]; args[1] = newVal; + oldVal = value1[aggno]; /* XXX - save so we can free later - er1p */ value1[aggno] = (Datum) fmgr_c(&aggfns->xfn1, (FmgrValues *) args, &isNull1); + pfree(oldVal); /* XXX - new, let's free the old datum - er1p */ Assert(!isNull1); } } diff --git a/src/backend/executor/nodeResult.c b/src/backend/executor/nodeResult.c index 718a612573..8b0d9e7ec9 100644 --- a/src/backend/executor/nodeResult.c +++ b/src/backend/executor/nodeResult.c @@ -27,7 +27,7 @@ * SeqScan (emp.all) * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/nodeResult.c,v 1.9 1999/02/13 23:15:26 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/nodeResult.c,v 1.10 1999/03/20 01:13:22 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -263,6 +263,8 @@ ExecEndResult(Result *node) * is freed at end-transaction time. -cim 6/2/91 * ---------------- */ + ExecFreeExprContext(&resstate->cstate); /* XXX - new for us - er1p */ + ExecFreeTypeInfo(&resstate->cstate); /* XXX - new for us - er1p */ ExecFreeProjectionInfo(&resstate->cstate); /* ---------------- @@ -276,6 +278,7 @@ ExecEndResult(Result *node) * ---------------- */ ExecClearTuple(resstate->cstate.cs_ResultTupleSlot); + pfree(resstate); node->resstate = NULL; /* XXX - new for us - er1p */ } void