61
61
* Portions Copyright (c) 1994, Regents of the University of California
62
62
*
63
63
* IDENTIFICATION
64
- * $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.160 2008/08/25 22:42:32 tgl Exp $
64
+ * $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.161 2008/09/08 00: 22:55 tgl Exp $
65
65
*
66
66
*-------------------------------------------------------------------------
67
67
*/
@@ -805,6 +805,23 @@ ExecAgg(AggState *node)
805
805
if (node -> agg_done )
806
806
return NULL ;
807
807
808
+ /*
809
+ * Check to see if we're still projecting out tuples from a previous agg
810
+ * tuple (because there is a function-returning-set in the projection
811
+ * expressions). If so, try to project another one.
812
+ */
813
+ if (node -> ss .ps .ps_TupFromTlist )
814
+ {
815
+ TupleTableSlot * result ;
816
+ ExprDoneCond isDone ;
817
+
818
+ result = ExecProject (node -> ss .ps .ps_ProjInfo , & isDone );
819
+ if (isDone == ExprMultipleResult )
820
+ return result ;
821
+ /* Done with that source tuple... */
822
+ node -> ss .ps .ps_TupFromTlist = false;
823
+ }
824
+
808
825
if (((Agg * ) node -> ss .ps .plan )-> aggstrategy == AGG_HASHED )
809
826
{
810
827
if (!node -> table_filled )
@@ -825,7 +842,6 @@ agg_retrieve_direct(AggState *aggstate)
825
842
PlanState * outerPlan ;
826
843
ExprContext * econtext ;
827
844
ExprContext * tmpcontext ;
828
- ProjectionInfo * projInfo ;
829
845
Datum * aggvalues ;
830
846
bool * aggnulls ;
831
847
AggStatePerAgg peragg ;
@@ -844,7 +860,6 @@ agg_retrieve_direct(AggState *aggstate)
844
860
aggnulls = econtext -> ecxt_aggnulls ;
845
861
/* tmpcontext is the per-input-tuple expression context */
846
862
tmpcontext = aggstate -> tmpcontext ;
847
- projInfo = aggstate -> ss .ps .ps_ProjInfo ;
848
863
peragg = aggstate -> peragg ;
849
864
pergroup = aggstate -> pergroup ;
850
865
firstSlot = aggstate -> ss .ss_ScanTupleSlot ;
@@ -982,10 +997,19 @@ agg_retrieve_direct(AggState *aggstate)
982
997
{
983
998
/*
984
999
* Form and return a projection tuple using the aggregate results
985
- * and the representative input tuple. Note we do not support
986
- * aggregates returning sets ...
1000
+ * and the representative input tuple.
987
1001
*/
988
- return ExecProject (projInfo , NULL );
1002
+ TupleTableSlot * result ;
1003
+ ExprDoneCond isDone ;
1004
+
1005
+ result = ExecProject (aggstate -> ss .ps .ps_ProjInfo , & isDone );
1006
+
1007
+ if (isDone != ExprEndResult )
1008
+ {
1009
+ aggstate -> ss .ps .ps_TupFromTlist =
1010
+ (isDone == ExprMultipleResult );
1011
+ return result ;
1012
+ }
989
1013
}
990
1014
}
991
1015
@@ -1045,7 +1069,6 @@ static TupleTableSlot *
1045
1069
agg_retrieve_hash_table (AggState * aggstate )
1046
1070
{
1047
1071
ExprContext * econtext ;
1048
- ProjectionInfo * projInfo ;
1049
1072
Datum * aggvalues ;
1050
1073
bool * aggnulls ;
1051
1074
AggStatePerAgg peragg ;
@@ -1061,7 +1084,6 @@ agg_retrieve_hash_table(AggState *aggstate)
1061
1084
econtext = aggstate -> ss .ps .ps_ExprContext ;
1062
1085
aggvalues = econtext -> ecxt_aggvalues ;
1063
1086
aggnulls = econtext -> ecxt_aggnulls ;
1064
- projInfo = aggstate -> ss .ps .ps_ProjInfo ;
1065
1087
peragg = aggstate -> peragg ;
1066
1088
firstSlot = aggstate -> ss .ss_ScanTupleSlot ;
1067
1089
@@ -1125,10 +1147,19 @@ agg_retrieve_hash_table(AggState *aggstate)
1125
1147
{
1126
1148
/*
1127
1149
* Form and return a projection tuple using the aggregate results
1128
- * and the representative input tuple. Note we do not support
1129
- * aggregates returning sets ...
1150
+ * and the representative input tuple.
1130
1151
*/
1131
- return ExecProject (projInfo , NULL );
1152
+ TupleTableSlot * result ;
1153
+ ExprDoneCond isDone ;
1154
+
1155
+ result = ExecProject (aggstate -> ss .ps .ps_ProjInfo , & isDone );
1156
+
1157
+ if (isDone != ExprEndResult )
1158
+ {
1159
+ aggstate -> ss .ps .ps_TupFromTlist =
1160
+ (isDone == ExprMultipleResult );
1161
+ return result ;
1162
+ }
1132
1163
}
1133
1164
}
1134
1165
0 commit comments