*** a/src/backend/executor/nodeAgg.c --- b/src/backend/executor/nodeAgg.c *************** *** 665,673 **** build_hash_table(AggState *aggstate) Agg *node = (Agg *) aggstate->ss.ps.plan; MemoryContext tmpmem = aggstate->tmpcontext->ecxt_per_tuple_memory; Size entrysize; - Bitmapset *colnos; - List *collist; - int i; Assert(node->aggstrategy == AGG_HASHED); Assert(node->numGroups > 0); --- 665,670 ---- *************** *** 700,705 **** build_hash_table(AggState *aggstate) --- 697,705 ---- * then convert it to an integer list (cheaper to scan at runtime). The * list is in decreasing order so that the first entry is the largest; * lookup_hash_entry depends on this to use slot_getsomeattrs correctly. + * Since build_hash_table() is invoked for every re-scan but we allocate + * the column list in the per-query context, we need only do this the + * first time through. * * Note: at present, searching the tlist/qual is not really necessary * since the parser should disallow any unaggregated references to *************** *** 707,723 **** build_hash_table(AggState *aggstate) * support for SQL99 semantics that allow use of "functionally dependent" * columns that haven't been explicitly grouped by. */ ! /* Find Vars that will be needed in tlist and qual */ ! colnos = find_unaggregated_cols(aggstate); ! /* Add in all the grouping columns */ ! for (i = 0; i < node->numCols; i++) ! colnos = bms_add_member(colnos, node->grpColIdx[i]); ! /* Convert to list, using lcons so largest element ends up first */ ! collist = NIL; ! while ((i = bms_first_member(colnos)) >= 0) ! collist = lcons_int(i, collist); ! aggstate->hash_needed = collist; } /* --- 707,730 ---- * support for SQL99 semantics that allow use of "functionally dependent" * columns that haven't been explicitly grouped by. */ + if (!aggstate->hash_needed) + { + Bitmapset *colnos; + List *collist; + int i; ! /* Find Vars that will be needed in tlist and qual */ ! colnos = find_unaggregated_cols(aggstate); ! /* Add in all the grouping columns */ ! for (i = 0; i < node->numCols; i++) ! colnos = bms_add_member(colnos, node->grpColIdx[i]); ! /* Convert to list, using lcons so largest element ends up first */ ! collist = NIL; ! while ((i = bms_first_member(colnos)) >= 0) ! collist = lcons_int(i, collist); ! aggstate->hash_needed = collist; ! bms_free(colnos); ! } } /*