]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Fix a gradual memory leak in ExecReScanAgg(). Because the aggregation
authorNeil Conway <neilc@samurai.com>
Wed, 8 Aug 2007 18:07:02 +0000 (18:07 +0000)
committerNeil Conway <neilc@samurai.com>
Wed, 8 Aug 2007 18:07:02 +0000 (18:07 +0000)
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

index c5c9aed7e78472057470ccefc427660cae5fba66..8fab15a5aa1428d0475af1b9a09d876c0ebe79ff 100644 (file)
@@ -61,7 +61,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.135.2.2 2007/02/02 00:07:44 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.135.2.3 2007/08/08 18:07:02 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1498,8 +1498,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)
        {