aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeAgg.c
diff options
context:
space:
mode:
authorNeil Conway <neilc@samurai.com>2007-08-08 18:06:55 +0000
committerNeil Conway <neilc@samurai.com>2007-08-08 18:06:55 +0000
commit7824c695ac3168c8d0ea622b9e4c76bc88c71362 (patch)
treeb41b8786146386b81c20abe0f5c767fcdadfc779 /src/backend/executor/nodeAgg.c
parentb58230005b881626bf133c56e1f4d218e9037d36 (diff)
downloadpostgresql-7824c695ac3168c8d0ea622b9e4c76bc88c71362.tar.gz
postgresql-7824c695ac3168c8d0ea622b9e4c76bc88c71362.zip
Fix a gradual memory leak in ExecReScanAgg(). Because the aggregation
hash table is allocated in a child context of the agg node's memory context, MemoryContextReset() will reset but *not* delete the child context. Since ExecReScanAgg() proceeds to build a new hash table from scratch (in a new sub-context), this results in leaking the header for the previous memory context. Therefore, use MemoryContextResetAndDeleteChildren() instead. Credit: My colleague Sailesh Krishnamurthy at Truviso for isolating the cause of the leak.
Diffstat (limited to 'src/backend/executor/nodeAgg.c')
-rw-r--r--src/backend/executor/nodeAgg.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index b18ec2fee82..82226665874 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -45,7 +45,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.116.2.3 2005/01/27 23:43:16 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.116.2.4 2007/08/08 18:06:55 neilc Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1509,8 +1509,14 @@ ExecReScanAgg(AggState *node, ExprContext *exprCtxt)
MemSet(econtext->ecxt_aggvalues, 0, sizeof(Datum) * node->numaggs);
MemSet(econtext->ecxt_aggnulls, 0, sizeof(bool) * node->numaggs);
- /* Release all temp storage */
- MemoryContextReset(node->aggcontext);
+ /*
+ * Release all temp storage. Note that with AGG_HASHED, the hash table
+ * is allocated in a sub-context of the aggcontext. We're going to
+ * rebuild the hash table from scratch, so we need to use
+ * MemoryContextResetAndDeleteChildren() to avoid leaking the old hash
+ * table's memory context header.
+ */
+ MemoryContextResetAndDeleteChildren(node->aggcontext);
if (((Agg *) node->ss.ps.plan)->aggstrategy == AGG_HASHED)
{