@@ -400,7 +400,8 @@ static int hash_choose_num_partitions(uint64 input_groups,
400
400
double hashentrysize ,
401
401
int used_bits ,
402
402
int * log2_npartittions );
403
- static AggStatePerGroup lookup_hash_entry (AggState * aggstate , uint32 hash );
403
+ static AggStatePerGroup lookup_hash_entry (AggState * aggstate , uint32 hash ,
404
+ bool * in_hash_table );
404
405
static void lookup_hash_entries (AggState * aggstate );
405
406
static TupleTableSlot * agg_retrieve_direct (AggState * aggstate );
406
407
static void agg_fill_hash_table (AggState * aggstate );
@@ -1968,10 +1969,11 @@ hash_choose_num_partitions(uint64 input_groups, double hashentrysize,
1968
1969
*
1969
1970
* If in "spill mode", then only find existing hashtable entries; don't create
1970
1971
* new ones. If a tuple's group is not already present in the hash table for
1971
- * the current grouping set, return NULL and the caller will spill it to disk.
1972
+ * the current grouping set, assign *in_hash_table=false and the caller will
1973
+ * spill it to disk.
1972
1974
*/
1973
1975
static AggStatePerGroup
1974
- lookup_hash_entry (AggState * aggstate , uint32 hash )
1976
+ lookup_hash_entry (AggState * aggstate , uint32 hash , bool * in_hash_table )
1975
1977
{
1976
1978
AggStatePerHash perhash = & aggstate -> perhash [aggstate -> current_set ];
1977
1979
TupleTableSlot * hashslot = perhash -> hashslot ;
@@ -1987,7 +1989,12 @@ lookup_hash_entry(AggState *aggstate, uint32 hash)
1987
1989
hash );
1988
1990
1989
1991
if (entry == NULL )
1992
+ {
1993
+ * in_hash_table = false;
1990
1994
return NULL ;
1995
+ }
1996
+ else
1997
+ * in_hash_table = true;
1991
1998
1992
1999
if (isnew )
1993
2000
{
@@ -1997,9 +2004,14 @@ lookup_hash_entry(AggState *aggstate, uint32 hash)
1997
2004
aggstate -> hash_ngroups_current ++ ;
1998
2005
hash_agg_check_limits (aggstate );
1999
2006
2007
+ /* no need to allocate or initialize per-group state */
2008
+ if (aggstate -> numtrans == 0 )
2009
+ return NULL ;
2010
+
2000
2011
pergroup = (AggStatePerGroup )
2001
2012
MemoryContextAlloc (perhash -> hashtable -> tablecxt ,
2002
2013
sizeof (AggStatePerGroupData ) * aggstate -> numtrans );
2014
+
2003
2015
entry -> additional = pergroup ;
2004
2016
2005
2017
/*
@@ -2046,14 +2058,15 @@ lookup_hash_entries(AggState *aggstate)
2046
2058
{
2047
2059
AggStatePerHash perhash = & aggstate -> perhash [setno ];
2048
2060
uint32 hash ;
2061
+ bool in_hash_table ;
2049
2062
2050
2063
select_current_set (aggstate , setno , true);
2051
2064
prepare_hash_slot (aggstate );
2052
2065
hash = TupleHashTableHash (perhash -> hashtable , perhash -> hashslot );
2053
- pergroup [setno ] = lookup_hash_entry (aggstate , hash );
2066
+ pergroup [setno ] = lookup_hash_entry (aggstate , hash , & in_hash_table );
2054
2067
2055
2068
/* check to see if we need to spill the tuple for this grouping set */
2056
- if (pergroup [ setno ] == NULL )
2069
+ if (! in_hash_table )
2057
2070
{
2058
2071
HashAggSpill * spill = & aggstate -> hash_spills [setno ];
2059
2072
TupleTableSlot * slot = aggstate -> tmpcontext -> ecxt_outertuple ;
@@ -2587,6 +2600,7 @@ agg_refill_hash_table(AggState *aggstate)
2587
2600
TupleTableSlot * slot = aggstate -> hash_spill_slot ;
2588
2601
MinimalTuple tuple ;
2589
2602
uint32 hash ;
2603
+ bool in_hash_table ;
2590
2604
2591
2605
CHECK_FOR_INTERRUPTS ();
2592
2606
@@ -2598,9 +2612,10 @@ agg_refill_hash_table(AggState *aggstate)
2598
2612
aggstate -> tmpcontext -> ecxt_outertuple = slot ;
2599
2613
2600
2614
prepare_hash_slot (aggstate );
2601
- aggstate -> hash_pergroup [batch -> setno ] = lookup_hash_entry (aggstate , hash );
2615
+ aggstate -> hash_pergroup [batch -> setno ] = lookup_hash_entry (
2616
+ aggstate , hash , & in_hash_table );
2602
2617
2603
- if (aggstate -> hash_pergroup [ batch -> setno ] != NULL )
2618
+ if (in_hash_table )
2604
2619
{
2605
2620
/* Advance the aggregates (or combine functions) */
2606
2621
advance_aggregates (aggstate );
0 commit comments