6161 * Portions Copyright (c) 1994, Regents of the University of California
6262 *
6363 * IDENTIFICATION
64- * $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.161 2008/09/08 00:22 :55tgl Exp $
64+ * $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.162 2008/10/16 19:25 :55neilc Exp $
6565 *
6666 *-------------------------------------------------------------------------
6767 */
@@ -665,9 +665,6 @@ build_hash_table(AggState *aggstate)
665665Agg * node = (Agg * )aggstate -> ss .ps .plan ;
666666MemoryContext tmpmem = aggstate -> tmpcontext -> ecxt_per_tuple_memory ;
667667Size entrysize ;
668- Bitmapset * colnos ;
669- List * collist ;
670- int i ;
671668
672669Assert (node -> aggstrategy == AGG_HASHED );
673670Assert (node -> numGroups > 0 );
@@ -683,30 +680,40 @@ build_hash_table(AggState *aggstate)
683680entrysize ,
684681aggstate -> aggcontext ,
685682tmpmem );
683+ }
686684
687- /*
688- * Create a list of the tuple columns that actually need to be stored in
689- * hashtable entries. The incoming tuples from the child plan node will
690- * contain grouping columns, other columns referenced in our targetlist
691- * and qual, columns used to compute the aggregate functions, and perhaps
692- * just junk columns we don't use at all. Only columns of the first two
693- * types need to be stored in the hashtable, and getting rid of the others
694- * can make the table entries significantly smaller. To avoid messing up
695- * Var numbering, we keep the same tuple descriptor for hashtable entries
696- * as the incoming tuples have, but set unwanted columns to NULL in the
697- * tuples that go into the table.
698- *
699- * To eliminate duplicates, we build a bitmapset of the needed columns,
700- * then convert it to an integer list (cheaper to scan at runtime). The
701- * list is in decreasing order so that the first entry is the largest;
702- * lookup_hash_entry depends on this to use slot_getsomeattrs correctly.
703- *
704- * Note: at present, searching the tlist/qual is not really necessary
705- * since the parser should disallow any unaggregated references to
706- * ungrouped columns. However, the search will be needed when we add
707- * support for SQL99 semantics that allow use of "functionally dependent"
708- * columns that haven't been explicitly grouped by.
709- */
685+ /*
686+ * Create a list of the tuple columns that actually need to be stored in
687+ * hashtable entries. The incoming tuples from the child plan node will
688+ * contain grouping columns, other columns referenced in our targetlist and
689+ * qual, columns used to compute the aggregate functions, and perhaps just
690+ * junk columns we don't use at all. Only columns of the first two types
691+ * need to be stored in the hashtable, and getting rid of the others can
692+ * make the table entries significantly smaller. To avoid messing up Var
693+ * numbering, we keep the same tuple descriptor for hashtable entries as the
694+ * incoming tuples have, but set unwanted columns to NULL in the tuples that
695+ * go into the table.
696+ *
697+ * To eliminate duplicates, we build a bitmapset of the needed columns, then
698+ * convert it to an integer list (cheaper to scan at runtime). The list is
699+ * in decreasing order so that the first entry is the largest;
700+ * lookup_hash_entry depends on this to use slot_getsomeattrs correctly.
701+ * Note that the list is preserved over ExecReScanAgg, so we allocate it in
702+ * the per-query context (unlike the hash table itself).
703+ *
704+ * Note: at present, searching the tlist/qual is not really necessary since
705+ * the parser should disallow any unaggregated references to ungrouped
706+ * columns. However, the search will be needed when we add support for
707+ * SQL99 semantics that allow use of "functionally dependent" columns that
708+ * haven't been explicitly grouped by.
709+ */
710+ static List *
711+ find_hash_columns (AggState * aggstate )
712+ {
713+ Agg * node = (Agg * )aggstate -> ss .ps .plan ;
714+ Bitmapset * colnos ;
715+ List * collist ;
716+ int i ;
710717
711718/* Find Vars that will be needed in tlist and qual */
712719colnos = find_unaggregated_cols (aggstate );
@@ -717,7 +724,9 @@ build_hash_table(AggState *aggstate)
717724collist = NIL ;
718725while ((i = bms_first_member (colnos )) >=0 )
719726collist = lcons_int (i ,collist );
720- aggstate -> hash_needed = collist ;
727+ bms_free (colnos );
728+
729+ return collist ;
721730}
722731
723732/*
@@ -1325,6 +1334,8 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
13251334{
13261335build_hash_table (aggstate );
13271336aggstate -> table_filled = false;
1337+ /* Compute the columns we actually need to hash on */
1338+ aggstate -> hash_needed = find_hash_columns (aggstate );
13281339}
13291340else
13301341{