@@ -268,7 +268,12 @@ typedef struct AggStatePerTransData
268268 */
269269int numInputs ;
270270
271- /* offset of input columns in AggState->evalslot */
271+ /*
272+ * At each input row, we evaluate all argument expressions needed for all
273+ * the aggregates in this Agg node in a single ExecProject call. inputoff
274+ * is the starting index of this aggregate's argument expressions in the
275+ * resulting tuple (in AggState->evalslot).
276+ */
272277int inputoff ;
273278
274279/*
@@ -2809,10 +2814,11 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
28092814/*
28102815 * initialize child expressions
28112816 *
2812- * We rely on the parser to have checked that no aggs contain other agg
2813- * calls in their arguments. This would make no sense under SQL semantics
2814- * (and it's forbidden by the spec). Because it is true, we don't need to
2815- * worry about evaluating the aggs in any particular order.
2817+ * We expect the parser to have checked that no aggs contain other agg
2818+ * calls in their arguments (and just to be sure, we verify it again while
2819+ * initializing the plan node). This would make no sense under SQL
2820+ * semantics, and it's forbidden by the spec. Because it is true, we
2821+ * don't need to worry about evaluating the aggs in any particular order.
28162822 *
28172823 * Note: execExpr.c finds Aggrefs for us, and adds their AggrefExprState
28182824 * nodes to aggstate->aggs. Aggrefs in the qual are found here; Aggrefs
@@ -2851,17 +2857,6 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
28512857 */
28522858numaggs = aggstate -> numaggs ;
28532859Assert (numaggs == list_length (aggstate -> aggs ));
2854- if (numaggs <=0 )
2855- {
2856- /*
2857- * This is not an error condition: we might be using the Agg node just
2858- * to do hash-based grouping. Even in the regular case,
2859- * constant-expression simplification could optimize away all of the
2860- * Aggrefs in the targetlist and qual. So keep going, but force local
2861- * copy of numaggs positive so that palloc()s below don't choke.
2862- */
2863- numaggs = 1 ;
2864- }
28652860
28662861/*
28672862 * For each phase, prepare grouping set data and fmgr lookup data for
@@ -3364,19 +3359,19 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
33643359}
33653360
33663361/*
3367- * Update numaggs tomatch the number of unique aggregates found. Also set
3368- * numstates to the number of uniqueaggregate states found.
3362+ * Updateaggstate-> numaggs tobe the number of unique aggregates found.
3363+ *Also set numstates to the number of uniquetransition states found.
33693364 */
33703365aggstate -> numaggs = aggno + 1 ;
33713366aggstate -> numtrans = transno + 1 ;
33723367
33733368/*
33743369 * Build a single projection computing the aggregate arguments for all
3375- * aggregates at once, that 'sconsiderably faster thandoing it separately
3376- * for each.
3370+ * aggregates at once; if there 'smore thanone, that's considerably
3371+ *faster than doing it separately for each.
33773372 *
3378- * First create a targetlist combining thetargetlist of all the
3379- *transitions .
3373+ * First create a targetlist combining thetargetlists of all the
3374+ *per-trans states .
33803375 */
33813376combined_inputeval = NIL ;
33823377column_offset = 0 ;
@@ -3385,10 +3380,14 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
33853380AggStatePerTrans pertrans = & pertransstates [transno ];
33863381ListCell * arg ;
33873382
3383+ /*
3384+ * Mark this per-trans state with its starting column in the combined
3385+ * slot.
3386+ */
33883387pertrans -> inputoff = column_offset ;
33893388
33903389/*
3391- * Adjustresno ina copied target entries, topoint into the combined
3390+ * Adjustresnos inthe copied target entries tomatch the combined
33923391 * slot.
33933392 */
33943393foreach (arg ,pertrans -> aggref -> args )
@@ -3405,7 +3404,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
34053404column_offset += list_length (pertrans -> aggref -> args );
34063405}
34073406
3408- /*and then create a projection forthat targetlist */
3407+ /*Now create a projection forthe combined targetlist */
34093408aggstate -> evaldesc = ExecTypeFromTL (combined_inputeval , false);
34103409aggstate -> evalslot = ExecInitExtraTupleSlot (estate );
34113410aggstate -> evalproj = ExecBuildProjectionInfo (combined_inputeval ,
@@ -3415,6 +3414,21 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
34153414NULL );
34163415ExecSetSlotDescriptor (aggstate -> evalslot ,aggstate -> evaldesc );
34173416
3417+ /*
3418+ * Last, check whether any more aggregates got added onto the node while
3419+ * we processed the expressions for the aggregate arguments (including not
3420+ * only the regular arguments handled immediately above, but any FILTER
3421+ * expressions and direct arguments we might've handled earlier). If so,
3422+ * we have nested aggregate functions, which is semantically nonsensical,
3423+ * so complain. (This should have been caught by the parser, so we don't
3424+ * need to work hard on a helpful error message; but we defend against it
3425+ * here anyway, just to be sure.)
3426+ */
3427+ if (numaggs != list_length (aggstate -> aggs ))
3428+ ereport (ERROR ,
3429+ (errcode (ERRCODE_GROUPING_ERROR ),
3430+ errmsg ("aggregate function calls cannot be nested" )));
3431+
34183432return aggstate ;
34193433}
34203434
@@ -3444,7 +3458,6 @@ build_pertrans_for_aggref(AggStatePerTrans pertrans,
34443458List * sortlist ;
34453459int numSortCols ;
34463460int numDistinctCols ;
3447- int naggs ;
34483461int i ;
34493462
34503463/* Begin filling in the pertrans data */
@@ -3586,22 +3599,11 @@ build_pertrans_for_aggref(AggStatePerTrans pertrans,
35863599}
35873600
35883601/* Initialize the input and FILTER expressions */
3589- naggs = aggstate -> numaggs ;
35903602pertrans -> aggfilter = ExecInitExpr (aggref -> aggfilter ,
35913603 (PlanState * )aggstate );
35923604pertrans -> aggdirectargs = ExecInitExprList (aggref -> aggdirectargs ,
35933605 (PlanState * )aggstate );
35943606
3595- /*
3596- * Complain if the aggregate's arguments contain any aggregates; nested
3597- * agg functions are semantically nonsensical. (This should have been
3598- * caught earlier, but we defend against it here anyway.)
3599- */
3600- if (naggs != aggstate -> numaggs )
3601- ereport (ERROR ,
3602- (errcode (ERRCODE_GROUPING_ERROR ),
3603- errmsg ("aggregate function calls cannot be nested" )));
3604-
36053607/*
36063608 * If we're doing either DISTINCT or ORDER BY for a plain agg, then we
36073609 * have a list of SortGroupClause nodes; fish out the data in them and