From c556b29a1199babc672b81065fe74fb50657c451 Mon Sep 17 00:00:00 2001
From: Neil Conway <neilc@samurai.com>
Date: Wed, 8 Aug 2007 18:07:05 +0000
Subject: [PATCH] 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.
---
 src/backend/executor/nodeAgg.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index d9e26d1d196..644268b6350 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -61,7 +61,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.152 2007/04/02 03:49:38 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.153 2007/08/08 18:07:05 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1646,8 +1646,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)
 	{
-- 
GitLab