4545 * Portions Copyright (c) 1994, Regents of the University of California
4646 *
4747 * IDENTIFICATION
48- * $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.122 2004/06/06 00:41:26 tgl Exp $
48+ * $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.123 2004/07/10 18:39:23 tgl Exp $
4949 *
5050 *-------------------------------------------------------------------------
5151 */
@@ -674,7 +674,6 @@ agg_retrieve_direct(AggState *aggstate)
674674AggStatePerGroup pergroup ;
675675TupleTableSlot * outerslot ;
676676TupleTableSlot * firstSlot ;
677- TupleTableSlot * resultSlot ;
678677int aggno ;
679678
680679/*
@@ -696,11 +695,8 @@ agg_retrieve_direct(AggState *aggstate)
696695 * We loop retrieving groups until we find one matching
697696 * aggstate->ss.ps.qual
698697 */
699- do
698+ while (! aggstate -> agg_done )
700699{
701- if (aggstate -> agg_done )
702- return NULL ;
703-
704700/*
705701 * If we don't already have the first tuple of the new group,
706702 * fetch it from the outer plan.
@@ -815,7 +811,7 @@ agg_retrieve_direct(AggState *aggstate)
815811/*
816812 * If we have no first tuple (ie, the outerPlan didn't return
817813 * anything), create a dummy all-nulls input tuple for use by
818- * ExecProject. 99.44% of the time this is a waste of cycles,
814+ *ExecQual/ ExecProject. 99.44% of the time this is a waste of cycles,
819815 * because ordinarily the projected output tuple's targetlist
820816 * cannot contain any direct (non-aggregated) references to input
821817 * columns, so the dummy tuple will not be referenced. However
@@ -857,22 +853,28 @@ agg_retrieve_direct(AggState *aggstate)
857853}
858854
859855/*
860- * Form a projection tuple using the aggregate results and the
861- * representative input tuple.Store it in the result tuple slot.
862- * Note we do not support aggregates returning sets ...
856+ * Use the representative input tuple for any references to
857+ * non-aggregated input columns in the qual and tlist.
863858 */
864859econtext -> ecxt_scantuple = firstSlot ;
865- resultSlot = ExecProject (projInfo ,NULL );
866860
867861/*
868- * If the completed tuple does not match the qualifications, it is
869- * ignored and we loop back to try to process another group.
870- * Otherwise, return the tuple.
862+ * Check the qual (HAVING clause); if the group does not match,
863+ * ignore it and loop back to try to process another group.
871864 */
865+ if (ExecQual (aggstate -> ss .ps .qual ,econtext , false))
866+ {
867+ /*
868+ * Form and return a projection tuple using the aggregate results
869+ * and the representative input tuple. Note we do not support
870+ * aggregates returning sets ...
871+ */
872+ return ExecProject (projInfo ,NULL );
873+ }
872874}
873- while (!ExecQual (aggstate -> ss .ps .qual ,econtext , false));
874875
875- return resultSlot ;
876+ /* No more groups */
877+ return NULL ;
876878}
877879
878880/*
@@ -934,7 +936,6 @@ agg_retrieve_hash_table(AggState *aggstate)
934936AggStatePerGroup pergroup ;
935937AggHashEntry entry ;
936938TupleTableSlot * firstSlot ;
937- TupleTableSlot * resultSlot ;
938939int aggno ;
939940
940941/*
@@ -952,11 +953,8 @@ agg_retrieve_hash_table(AggState *aggstate)
952953 * We loop retrieving groups until we find one satisfying
953954 * aggstate->ss.ps.qual
954955 */
955- do
956+ while (! aggstate -> agg_done )
956957{
957- if (aggstate -> agg_done )
958- return NULL ;
959-
960958/*
961959 * Find the next entry in the hash table
962960 */
@@ -999,22 +997,28 @@ agg_retrieve_hash_table(AggState *aggstate)
999997}
1000998
1001999/*
1002- * Form a projection tuple using the aggregate results and the
1003- * representative input tuple.Store it in the result tuple slot.
1004- * Note we do not support aggregates returning sets ...
1000+ * Use the representative input tuple for any references to
1001+ * non-aggregated input columns in the qual and tlist.
10051002 */
10061003econtext -> ecxt_scantuple = firstSlot ;
1007- resultSlot = ExecProject (projInfo ,NULL );
10081004
10091005/*
1010- * If the completed tuple does not match the qualifications, it is
1011- * ignored and we loop back to try to process another group.
1012- * Otherwise, return the tuple.
1006+ * Check the qual (HAVING clause); if the group does not match,
1007+ * ignore it and loop back to try to process another group.
10131008 */
1009+ if (ExecQual (aggstate -> ss .ps .qual ,econtext , false))
1010+ {
1011+ /*
1012+ * Form and return a projection tuple using the aggregate results
1013+ * and the representative input tuple. Note we do not support
1014+ * aggregates returning sets ...
1015+ */
1016+ return ExecProject (projInfo ,NULL );
1017+ }
10141018}
1015- while (!ExecQual (aggstate -> ss .ps .qual ,econtext , false));
10161019
1017- return resultSlot ;
1020+ /* No more groups */
1021+ return NULL ;
10181022}
10191023
10201024/* -----------------