From: Neil Conway Date: Wed, 8 Aug 2007 18:06:55 +0000 (+0000) Subject: Fix a gradual memory leak in ExecReScanAgg(). Because the aggregation X-Git-Url: http://git.postgresql.org/gitweb/static/gitweb.js?a=commitdiff_plain;h=8a4b4bdf6905b32b0fffab00d0c1c84d3786d9d4;p=users%2Fbernd%2Fpostgres.git 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. --- diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c index 8023f268f4..a61c885b9e 100644 --- a/src/backend/executor/nodeAgg.c +++ b/src/backend/executor/nodeAgg.c @@ -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) {