diff options
author | Neil Conway <neilc@samurai.com> | 2007-08-08 18:07:03 +0000 |
---|---|---|
committer | Neil Conway <neilc@samurai.com> | 2007-08-08 18:07:03 +0000 |
commit | 7dd8d4673f21ca63d754f2015f8b075e0dc79b91 (patch) | |
tree | f45e587c410d4ed89b004d9c170bfa2dfb212837 /src/backend/executor/nodeAgg.c | |
parent | f614a2b50842c5ced90cd5c5af802684028510a9 (diff) | |
download | postgresql-7dd8d4673f21ca63d754f2015f8b075e0dc79b91.tar.gz postgresql-7dd8d4673f21ca63d754f2015f8b075e0dc79b91.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.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c index 2c276b33c96..28e6d34917e 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.146.2.1 2007/02/02 00:07:28 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.146.2.2 2007/08/08 18:07:03 neilc Exp $ * *------------------------------------------------------------------------- */ @@ -1641,8 +1641,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) { |