45
45
* Portions Copyright (c) 1994, Regents of the University of California
46
46
*
47
47
* 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 $
49
49
*
50
50
*-------------------------------------------------------------------------
51
51
*/
@@ -674,7 +674,6 @@ agg_retrieve_direct(AggState *aggstate)
674
674
AggStatePerGroup pergroup ;
675
675
TupleTableSlot * outerslot ;
676
676
TupleTableSlot * firstSlot ;
677
- TupleTableSlot * resultSlot ;
678
677
int aggno ;
679
678
680
679
/*
@@ -696,11 +695,8 @@ agg_retrieve_direct(AggState *aggstate)
696
695
* We loop retrieving groups until we find one matching
697
696
* aggstate->ss.ps.qual
698
697
*/
699
- do
698
+ while (! aggstate -> agg_done )
700
699
{
701
- if (aggstate -> agg_done )
702
- return NULL ;
703
-
704
700
/*
705
701
* If we don't already have the first tuple of the new group,
706
702
* fetch it from the outer plan.
@@ -815,7 +811,7 @@ agg_retrieve_direct(AggState *aggstate)
815
811
/*
816
812
* If we have no first tuple (ie, the outerPlan didn't return
817
813
* 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,
819
815
* because ordinarily the projected output tuple's targetlist
820
816
* cannot contain any direct (non-aggregated) references to input
821
817
* columns, so the dummy tuple will not be referenced. However
@@ -857,22 +853,28 @@ agg_retrieve_direct(AggState *aggstate)
857
853
}
858
854
859
855
/*
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.
863
858
*/
864
859
econtext -> ecxt_scantuple = firstSlot ;
865
- resultSlot = ExecProject (projInfo , NULL );
866
860
867
861
/*
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.
871
864
*/
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
+ }
872
874
}
873
- while (!ExecQual (aggstate -> ss .ps .qual , econtext , false));
874
875
875
- return resultSlot ;
876
+ /* No more groups */
877
+ return NULL ;
876
878
}
877
879
878
880
/*
@@ -934,7 +936,6 @@ agg_retrieve_hash_table(AggState *aggstate)
934
936
AggStatePerGroup pergroup ;
935
937
AggHashEntry entry ;
936
938
TupleTableSlot * firstSlot ;
937
- TupleTableSlot * resultSlot ;
938
939
int aggno ;
939
940
940
941
/*
@@ -952,11 +953,8 @@ agg_retrieve_hash_table(AggState *aggstate)
952
953
* We loop retrieving groups until we find one satisfying
953
954
* aggstate->ss.ps.qual
954
955
*/
955
- do
956
+ while (! aggstate -> agg_done )
956
957
{
957
- if (aggstate -> agg_done )
958
- return NULL ;
959
-
960
958
/*
961
959
* Find the next entry in the hash table
962
960
*/
@@ -999,22 +997,28 @@ agg_retrieve_hash_table(AggState *aggstate)
999
997
}
1000
998
1001
999
/*
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.
1005
1002
*/
1006
1003
econtext -> ecxt_scantuple = firstSlot ;
1007
- resultSlot = ExecProject (projInfo , NULL );
1008
1004
1009
1005
/*
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.
1013
1008
*/
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
+ }
1014
1018
}
1015
- while (!ExecQual (aggstate -> ss .ps .qual , econtext , false));
1016
1019
1017
- return resultSlot ;
1020
+ /* No more groups */
1021
+ return NULL ;
1018
1022
}
1019
1023
1020
1024
/* -----------------
0 commit comments