diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c index 4c8c5cfc07..4e100e5755 100644 --- a/src/backend/executor/nodeAgg.c +++ b/src/backend/executor/nodeAgg.c @@ -297,6 +297,12 @@ /* minimum number of initial hash table buckets */ #define HASHAGG_MIN_BUCKETS 256 +/* + * Estimate chunk overhead as a constant 16 bytes. XXX: should this be + * improved? + */ +#define CHUNKHDRSZ 16 + /* * Track all tapes needed for a HashAgg that spills. We don't know the maximum * number of tapes needed at the start of the algorithm (because it can @@ -1639,14 +1645,32 @@ find_hash_columns(AggState *aggstate) * Estimate per-hash-table-entry overhead. */ Size -hash_agg_entry_size(int numAggs, Size tupleWidth, Size transitionSpace) +hash_agg_entry_size(int numTrans, Size tupleWidth, Size transitionSpace) { + Size tupleChunkSize; + Size pergroupChunkSize; + Size transitionChunkSize; + Size tupleSize = (MAXALIGN(SizeofMinimalTupleHeader) + + tupleWidth); + Size pergroupSize = numTrans * sizeof(AggStatePerGroupData); + + tupleChunkSize = CHUNKHDRSZ + tupleSize; + + if (pergroupSize > 0) + pergroupChunkSize = CHUNKHDRSZ + pergroupSize; + else + pergroupChunkSize = 0; + + if (transitionSpace > 0) + transitionChunkSize = CHUNKHDRSZ + transitionSpace; + else + transitionChunkSize = 0; + return - MAXALIGN(SizeofMinimalTupleHeader) + - MAXALIGN(tupleWidth) + - MAXALIGN(sizeof(TupleHashEntryData) + - numAggs * sizeof(AggStatePerGroupData)) + - transitionSpace; + sizeof(TupleHashEntryData) + + tupleChunkSize + + pergroupChunkSize + + transitionChunkSize; } /* diff --git a/src/include/executor/nodeAgg.h b/src/include/executor/nodeAgg.h index a5b8a004d1..c2b55728bf 100644 --- a/src/include/executor/nodeAgg.h +++ b/src/include/executor/nodeAgg.h @@ -314,7 +314,7 @@ extern AggState *ExecInitAgg(Agg *node, EState *estate, int eflags); extern void ExecEndAgg(AggState *node); extern void ExecReScanAgg(AggState *node); -extern Size hash_agg_entry_size(int numAggs, Size tupleWidth, +extern Size hash_agg_entry_size(int numTrans, Size tupleWidth, Size transitionSpace); extern void hash_agg_set_limits(double hashentrysize, uint64 input_groups, int used_bits, Size *mem_limit,