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.
This commit is contained in:
Tom Lane 2004-03-13 00:54:10 +00:00
parent 58e351113f
commit 642cd0ab13
1 changed files with 19 additions and 1 deletions

View File

@ -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 $
*
*-------------------------------------------------------------------------
*/
@ -251,6 +251,18 @@ initialize_aggregates(AggState *aggstate,
work_mem, false);
}
/*
* 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.
*
@ -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