6161 * Portions Copyright (c) 1994, Regents of the University of California
6262 *
6363 * 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 $
6565 *
6666 *-------------------------------------------------------------------------
6767 */
@@ -805,6 +805,23 @@ ExecAgg(AggState *node)
805805 if (node -> agg_done )
806806 return NULL ;
807807
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+
808825 if (((Agg * ) node -> ss .ps .plan )-> aggstrategy == AGG_HASHED )
809826 {
810827 if (!node -> table_filled )
@@ -825,7 +842,6 @@ agg_retrieve_direct(AggState *aggstate)
825842 PlanState * outerPlan ;
826843 ExprContext * econtext ;
827844 ExprContext * tmpcontext ;
828- ProjectionInfo * projInfo ;
829845 Datum * aggvalues ;
830846 bool * aggnulls ;
831847 AggStatePerAgg peragg ;
@@ -844,7 +860,6 @@ agg_retrieve_direct(AggState *aggstate)
844860 aggnulls = econtext -> ecxt_aggnulls ;
845861 /* tmpcontext is the per-input-tuple expression context */
846862 tmpcontext = aggstate -> tmpcontext ;
847- projInfo = aggstate -> ss .ps .ps_ProjInfo ;
848863 peragg = aggstate -> peragg ;
849864 pergroup = aggstate -> pergroup ;
850865 firstSlot = aggstate -> ss .ss_ScanTupleSlot ;
@@ -982,10 +997,19 @@ agg_retrieve_direct(AggState *aggstate)
982997 {
983998 /*
984999 * 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.
9871001 */
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+ }
9891013 }
9901014 }
9911015
@@ -1045,7 +1069,6 @@ static TupleTableSlot *
10451069agg_retrieve_hash_table (AggState * aggstate )
10461070{
10471071 ExprContext * econtext ;
1048- ProjectionInfo * projInfo ;
10491072 Datum * aggvalues ;
10501073 bool * aggnulls ;
10511074 AggStatePerAgg peragg ;
@@ -1061,7 +1084,6 @@ agg_retrieve_hash_table(AggState *aggstate)
10611084 econtext = aggstate -> ss .ps .ps_ExprContext ;
10621085 aggvalues = econtext -> ecxt_aggvalues ;
10631086 aggnulls = econtext -> ecxt_aggnulls ;
1064- projInfo = aggstate -> ss .ps .ps_ProjInfo ;
10651087 peragg = aggstate -> peragg ;
10661088 firstSlot = aggstate -> ss .ss_ScanTupleSlot ;
10671089
@@ -1125,10 +1147,19 @@ agg_retrieve_hash_table(AggState *aggstate)
11251147 {
11261148 /*
11271149 * 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.
11301151 */
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+ }
11321163 }
11331164 }
11341165
0 commit comments