aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeAgg.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2004-03-13 00:54:35 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2004-03-13 00:54:35 +0000
commit695c241e5a0c9c3b29fec80faf890c28e73ac5e7 (patch)
tree2222bbe930b523cdfe977c642371253c13361e9c /src/backend/executor/nodeAgg.c
parentef41d22e558d4521cebba200cfd170d0e51a44a5 (diff)
downloadpostgresql-695c241e5a0c9c3b29fec80faf890c28e73ac5e7.tar.gz
postgresql-695c241e5a0c9c3b29fec80faf890c28e73ac5e7.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.
Diffstat (limited to 'src/backend/executor/nodeAgg.c')
-rw-r--r--src/backend/executor/nodeAgg.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index d9adb09dafb..c1ba93fa931 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
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.116 2003/08/19 01:13:40 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.116.2.1 2004/03/13 00:54:35 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