diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2004-03-13 00:54:10 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2004-03-13 00:54:10 +0000 |
commit | 642cd0ab13f01c84b789c75024778fe2e6c5d10a (patch) | |
tree | ae4f27caf2f0dd7bb71f05ce0c079cd985617138 | |
parent | 58e351113fc9ca9064766e62547fcc26b4664a9a (diff) | |
download | postgresql-642cd0ab13f01c84b789c75024778fe2e6c5d10a.tar.gz postgresql-642cd0ab13f01c84b789c75024778fe2e6c5d10a.zip |
Repair memory leakage introduced into the non-hashed aggregate case by
7.4 rewrite for hashed aggregate support. If the transition data type
is pass-by-reference, the transValue must be pfreed when starting a new
group boundary, else we have a one-value-per-group leakage. Thanks to
Rae Steining for providing a reproducible test case.
-rw-r--r-- | src/backend/executor/nodeAgg.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c index cb0a64c4277..0a872221276 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 - * $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.118 2004/02/03 17:34:02 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.119 2004/03/13 00:54:10 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -252,6 +252,18 @@ initialize_aggregates(AggState *aggstate, } /* + * If we are reinitializing after a group boundary, we have to free + * any prior transValue to avoid memory leakage. We must check not + * only the isnull flag but whether the pointer is NULL; since + * pergroupstate is initialized with palloc0, the initial condition + * has isnull = 0 and null pointer. + */ + if (!peraggstate->transtypeByVal && + !pergroupstate->transValueIsNull && + DatumGetPointer(pergroupstate->transValue) != NULL) + pfree(DatumGetPointer(pergroupstate->transValue)); + + /* * (Re)set transValue to the initial value. * * Note that when the initial value is pass-by-ref, we must copy it @@ -1472,6 +1484,12 @@ ExecReScanAgg(AggState *node, ExprContext *exprCtxt) build_hash_table(node); node->table_filled = false; } + else + { + /* Reset the per-group state (in particular, mark transvalues null) */ + MemSet(node->pergroup, 0, + sizeof(AggStatePerGroupData) * node->numaggs); + } /* * if chgParam of subnode is not null then plan will be re-scanned by |