]> granicus.if.org Git - postgresql/blob - src/backend/executor/nodeAgg.c
pgindent run for 8.3.
[postgresql] / src / backend / executor / nodeAgg.c
1 /*-------------------------------------------------------------------------
2  *
3  * nodeAgg.c
4  *        Routines to handle aggregate nodes.
5  *
6  *        ExecAgg evaluates each aggregate in the following steps:
7  *
8  *               transvalue = initcond
9  *               foreach input_tuple do
10  *                      transvalue = transfunc(transvalue, input_value(s))
11  *               result = finalfunc(transvalue)
12  *
13  *        If a finalfunc is not supplied then the result is just the ending
14  *        value of transvalue.
15  *
16  *        If transfunc is marked "strict" in pg_proc and initcond is NULL,
17  *        then the first non-NULL input_value is assigned directly to transvalue,
18  *        and transfunc isn't applied until the second non-NULL input_value.
19  *        The agg's first input type and transtype must be the same in this case!
20  *
21  *        If transfunc is marked "strict" then NULL input_values are skipped,
22  *        keeping the previous transvalue.      If transfunc is not strict then it
23  *        is called for every input tuple and must deal with NULL initcond
24  *        or NULL input_values for itself.
25  *
26  *        If finalfunc is marked "strict" then it is not called when the
27  *        ending transvalue is NULL, instead a NULL result is created
28  *        automatically (this is just the usual handling of strict functions,
29  *        of course).  A non-strict finalfunc can make its own choice of
30  *        what to return for a NULL ending transvalue.
31  *
32  *        We compute aggregate input expressions and run the transition functions
33  *        in a temporary econtext (aggstate->tmpcontext).  This is reset at
34  *        least once per input tuple, so when the transvalue datatype is
35  *        pass-by-reference, we have to be careful to copy it into a longer-lived
36  *        memory context, and free the prior value to avoid memory leakage.
37  *        We store transvalues in the memory context aggstate->aggcontext,
38  *        which is also used for the hashtable structures in AGG_HASHED mode.
39  *        The node's regular econtext (aggstate->csstate.cstate.cs_ExprContext)
40  *        is used to run finalize functions and compute the output tuple;
41  *        this context can be reset once per output tuple.
42  *
43  *        Beginning in PostgreSQL 8.1, the executor's AggState node is passed as
44  *        the fmgr "context" value in all transfunc and finalfunc calls.  It is
45  *        not really intended that the transition functions will look into the
46  *        AggState node, but they can use code like
47  *                      if (fcinfo->context && IsA(fcinfo->context, AggState))
48  *        to verify that they are being called by nodeAgg.c and not as ordinary
49  *        SQL functions.  The main reason a transition function might want to know
50  *        that is that it can avoid palloc'ing a fixed-size pass-by-ref transition
51  *        value on every call: it can instead just scribble on and return its left
52  *        input.  Ordinarily it is completely forbidden for functions to modify
53  *        pass-by-ref inputs, but in the aggregate case we know the left input is
54  *        either the initial transition value or a previous function result, and
55  *        in either case its value need not be preserved.  See int8inc() for an
56  *        example.      Notice that advance_transition_function() is coded to avoid a
57  *        data copy step when the previous transition value pointer is returned.
58  *
59  *
60  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
61  * Portions Copyright (c) 1994, Regents of the University of California
62  *
63  * IDENTIFICATION
64  *        $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.154 2007/11/15 21:14:34 momjian Exp $
65  *
66  *-------------------------------------------------------------------------
67  */
68
69 #include "postgres.h"
70
71 #include "access/heapam.h"
72 #include "catalog/pg_aggregate.h"
73 #include "catalog/pg_proc.h"
74 #include "catalog/pg_type.h"
75 #include "executor/executor.h"
76 #include "executor/nodeAgg.h"
77 #include "miscadmin.h"
78 #include "optimizer/clauses.h"
79 #include "parser/parse_agg.h"
80 #include "parser/parse_coerce.h"
81 #include "parser/parse_expr.h"
82 #include "parser/parse_oper.h"
83 #include "utils/acl.h"
84 #include "utils/builtins.h"
85 #include "utils/lsyscache.h"
86 #include "utils/memutils.h"
87 #include "utils/syscache.h"
88 #include "utils/tuplesort.h"
89 #include "utils/datum.h"
90
91
92 /*
93  * AggStatePerAggData - per-aggregate working state for the Agg scan
94  */
95 typedef struct AggStatePerAggData
96 {
97         /*
98          * These values are set up during ExecInitAgg() and do not change
99          * thereafter:
100          */
101
102         /* Links to Aggref expr and state nodes this working state is for */
103         AggrefExprState *aggrefstate;
104         Aggref     *aggref;
105
106         /* number of input arguments for aggregate */
107         int                     numArguments;
108
109         /* Oids of transfer functions */
110         Oid                     transfn_oid;
111         Oid                     finalfn_oid;    /* may be InvalidOid */
112
113         /*
114          * fmgr lookup data for transfer functions --- only valid when
115          * corresponding oid is not InvalidOid.  Note in particular that fn_strict
116          * flags are kept here.
117          */
118         FmgrInfo        transfn;
119         FmgrInfo        finalfn;
120
121         /*
122          * Type of input data and Oid of sort operator to use for it; only
123          * set/used when aggregate has DISTINCT flag.  (These are not used
124          * directly by nodeAgg, but must be passed to the Tuplesort object.)
125          */
126         Oid                     inputType;
127         Oid                     sortOperator;
128
129         /*
130          * fmgr lookup data for input type's equality operator --- only set/used
131          * when aggregate has DISTINCT flag.
132          */
133         FmgrInfo        equalfn;
134
135         /*
136          * initial value from pg_aggregate entry
137          */
138         Datum           initValue;
139         bool            initValueIsNull;
140
141         /*
142          * We need the len and byval info for the agg's input, result, and
143          * transition data types in order to know how to copy/delete values.
144          */
145         int16           inputtypeLen,
146                                 resulttypeLen,
147                                 transtypeLen;
148         bool            inputtypeByVal,
149                                 resulttypeByVal,
150                                 transtypeByVal;
151
152         /*
153          * These values are working state that is initialized at the start of an
154          * input tuple group and updated for each input tuple.
155          *
156          * For a simple (non DISTINCT) aggregate, we just feed the input values
157          * straight to the transition function.  If it's DISTINCT, we pass the
158          * input values into a Tuplesort object; then at completion of the input
159          * tuple group, we scan the sorted values, eliminate duplicates, and run
160          * the transition function on the rest.
161          */
162
163         Tuplesortstate *sortstate;      /* sort object, if a DISTINCT agg */
164 } AggStatePerAggData;
165
166 /*
167  * AggStatePerGroupData - per-aggregate-per-group working state
168  *
169  * These values are working state that is initialized at the start of
170  * an input tuple group and updated for each input tuple.
171  *
172  * In AGG_PLAIN and AGG_SORTED modes, we have a single array of these
173  * structs (pointed to by aggstate->pergroup); we re-use the array for
174  * each input group, if it's AGG_SORTED mode.  In AGG_HASHED mode, the
175  * hash table contains an array of these structs for each tuple group.
176  *
177  * Logically, the sortstate field belongs in this struct, but we do not
178  * keep it here for space reasons: we don't support DISTINCT aggregates
179  * in AGG_HASHED mode, so there's no reason to use up a pointer field
180  * in every entry of the hashtable.
181  */
182 typedef struct AggStatePerGroupData
183 {
184         Datum           transValue;             /* current transition value */
185         bool            transValueIsNull;
186
187         bool            noTransValue;   /* true if transValue not set yet */
188
189         /*
190          * Note: noTransValue initially has the same value as transValueIsNull,
191          * and if true both are cleared to false at the same time.      They are not
192          * the same though: if transfn later returns a NULL, we want to keep that
193          * NULL and not auto-replace it with a later input value. Only the first
194          * non-NULL input will be auto-substituted.
195          */
196 } AggStatePerGroupData;
197
198 /*
199  * To implement hashed aggregation, we need a hashtable that stores a
200  * representative tuple and an array of AggStatePerGroup structs for each
201  * distinct set of GROUP BY column values.      We compute the hash key from
202  * the GROUP BY columns.
203  */
204 typedef struct AggHashEntryData *AggHashEntry;
205
206 typedef struct AggHashEntryData
207 {
208         TupleHashEntryData shared;      /* common header for hash table entries */
209         /* per-aggregate transition status array - must be last! */
210         AggStatePerGroupData pergroup[1];       /* VARIABLE LENGTH ARRAY */
211 } AggHashEntryData;                             /* VARIABLE LENGTH STRUCT */
212
213
214 static void initialize_aggregates(AggState *aggstate,
215                                           AggStatePerAgg peragg,
216                                           AggStatePerGroup pergroup);
217 static void advance_transition_function(AggState *aggstate,
218                                                         AggStatePerAgg peraggstate,
219                                                         AggStatePerGroup pergroupstate,
220                                                         FunctionCallInfoData *fcinfo);
221 static void advance_aggregates(AggState *aggstate, AggStatePerGroup pergroup);
222 static void process_sorted_aggregate(AggState *aggstate,
223                                                  AggStatePerAgg peraggstate,
224                                                  AggStatePerGroup pergroupstate);
225 static void finalize_aggregate(AggState *aggstate,
226                                    AggStatePerAgg peraggstate,
227                                    AggStatePerGroup pergroupstate,
228                                    Datum *resultVal, bool *resultIsNull);
229 static Bitmapset *find_unaggregated_cols(AggState *aggstate);
230 static bool find_unaggregated_cols_walker(Node *node, Bitmapset **colnos);
231 static void build_hash_table(AggState *aggstate);
232 static AggHashEntry lookup_hash_entry(AggState *aggstate,
233                                   TupleTableSlot *inputslot);
234 static TupleTableSlot *agg_retrieve_direct(AggState *aggstate);
235 static void agg_fill_hash_table(AggState *aggstate);
236 static TupleTableSlot *agg_retrieve_hash_table(AggState *aggstate);
237 static Datum GetAggInitVal(Datum textInitVal, Oid transtype);
238
239
240 /*
241  * Initialize all aggregates for a new group of input values.
242  *
243  * When called, CurrentMemoryContext should be the per-query context.
244  */
245 static void
246 initialize_aggregates(AggState *aggstate,
247                                           AggStatePerAgg peragg,
248                                           AggStatePerGroup pergroup)
249 {
250         int                     aggno;
251
252         for (aggno = 0; aggno < aggstate->numaggs; aggno++)
253         {
254                 AggStatePerAgg peraggstate = &peragg[aggno];
255                 AggStatePerGroup pergroupstate = &pergroup[aggno];
256                 Aggref     *aggref = peraggstate->aggref;
257
258                 /*
259                  * Start a fresh sort operation for each DISTINCT aggregate.
260                  */
261                 if (aggref->aggdistinct)
262                 {
263                         /*
264                          * In case of rescan, maybe there could be an uncompleted sort
265                          * operation?  Clean it up if so.
266                          */
267                         if (peraggstate->sortstate)
268                                 tuplesort_end(peraggstate->sortstate);
269
270                         peraggstate->sortstate =
271                                 tuplesort_begin_datum(peraggstate->inputType,
272                                                                           peraggstate->sortOperator, false,
273                                                                           work_mem, false);
274                 }
275
276                 /*
277                  * If we are reinitializing after a group boundary, we have to free
278                  * any prior transValue to avoid memory leakage.  We must check not
279                  * only the isnull flag but whether the pointer is NULL; since
280                  * pergroupstate is initialized with palloc0, the initial condition
281                  * has isnull = 0 and null pointer.
282                  */
283                 if (!peraggstate->transtypeByVal &&
284                         !pergroupstate->transValueIsNull &&
285                         DatumGetPointer(pergroupstate->transValue) != NULL)
286                         pfree(DatumGetPointer(pergroupstate->transValue));
287
288                 /*
289                  * (Re)set transValue to the initial value.
290                  *
291                  * Note that when the initial value is pass-by-ref, we must copy it
292                  * (into the aggcontext) since we will pfree the transValue later.
293                  */
294                 if (peraggstate->initValueIsNull)
295                         pergroupstate->transValue = peraggstate->initValue;
296                 else
297                 {
298                         MemoryContext oldContext;
299
300                         oldContext = MemoryContextSwitchTo(aggstate->aggcontext);
301                         pergroupstate->transValue = datumCopy(peraggstate->initValue,
302                                                                                                   peraggstate->transtypeByVal,
303                                                                                                   peraggstate->transtypeLen);
304                         MemoryContextSwitchTo(oldContext);
305                 }
306                 pergroupstate->transValueIsNull = peraggstate->initValueIsNull;
307
308                 /*
309                  * If the initial value for the transition state doesn't exist in the
310                  * pg_aggregate table then we will let the first non-NULL value
311                  * returned from the outer procNode become the initial value. (This is
312                  * useful for aggregates like max() and min().) The noTransValue flag
313                  * signals that we still need to do this.
314                  */
315                 pergroupstate->noTransValue = peraggstate->initValueIsNull;
316         }
317 }
318
319 /*
320  * Given new input value(s), advance the transition function of an aggregate.
321  *
322  * The new values (and null flags) have been preloaded into argument positions
323  * 1 and up in fcinfo, so that we needn't copy them again to pass to the
324  * transition function.  No other fields of fcinfo are assumed valid.
325  *
326  * It doesn't matter which memory context this is called in.
327  */
328 static void
329 advance_transition_function(AggState *aggstate,
330                                                         AggStatePerAgg peraggstate,
331                                                         AggStatePerGroup pergroupstate,
332                                                         FunctionCallInfoData *fcinfo)
333 {
334         int                     numArguments = peraggstate->numArguments;
335         MemoryContext oldContext;
336         Datum           newVal;
337         int                     i;
338
339         if (peraggstate->transfn.fn_strict)
340         {
341                 /*
342                  * For a strict transfn, nothing happens when there's a NULL input; we
343                  * just keep the prior transValue.
344                  */
345                 for (i = 1; i <= numArguments; i++)
346                 {
347                         if (fcinfo->argnull[i])
348                                 return;
349                 }
350                 if (pergroupstate->noTransValue)
351                 {
352                         /*
353                          * transValue has not been initialized. This is the first non-NULL
354                          * input value. We use it as the initial value for transValue. (We
355                          * already checked that the agg's input type is binary-compatible
356                          * with its transtype, so straight copy here is OK.)
357                          *
358                          * We must copy the datum into aggcontext if it is pass-by-ref. We
359                          * do not need to pfree the old transValue, since it's NULL.
360                          */
361                         oldContext = MemoryContextSwitchTo(aggstate->aggcontext);
362                         pergroupstate->transValue = datumCopy(fcinfo->arg[1],
363                                                                                                   peraggstate->transtypeByVal,
364                                                                                                   peraggstate->transtypeLen);
365                         pergroupstate->transValueIsNull = false;
366                         pergroupstate->noTransValue = false;
367                         MemoryContextSwitchTo(oldContext);
368                         return;
369                 }
370                 if (pergroupstate->transValueIsNull)
371                 {
372                         /*
373                          * Don't call a strict function with NULL inputs.  Note it is
374                          * possible to get here despite the above tests, if the transfn is
375                          * strict *and* returned a NULL on a prior cycle. If that happens
376                          * we will propagate the NULL all the way to the end.
377                          */
378                         return;
379                 }
380         }
381
382         /* We run the transition functions in per-input-tuple memory context */
383         oldContext = MemoryContextSwitchTo(aggstate->tmpcontext->ecxt_per_tuple_memory);
384
385         /*
386          * OK to call the transition function
387          */
388         InitFunctionCallInfoData(*fcinfo, &(peraggstate->transfn),
389                                                          numArguments + 1,
390                                                          (void *) aggstate, NULL);
391         fcinfo->arg[0] = pergroupstate->transValue;
392         fcinfo->argnull[0] = pergroupstate->transValueIsNull;
393
394         newVal = FunctionCallInvoke(fcinfo);
395
396         /*
397          * If pass-by-ref datatype, must copy the new value into aggcontext and
398          * pfree the prior transValue.  But if transfn returned a pointer to its
399          * first input, we don't need to do anything.
400          */
401         if (!peraggstate->transtypeByVal &&
402                 DatumGetPointer(newVal) != DatumGetPointer(pergroupstate->transValue))
403         {
404                 if (!fcinfo->isnull)
405                 {
406                         MemoryContextSwitchTo(aggstate->aggcontext);
407                         newVal = datumCopy(newVal,
408                                                            peraggstate->transtypeByVal,
409                                                            peraggstate->transtypeLen);
410                 }
411                 if (!pergroupstate->transValueIsNull)
412                         pfree(DatumGetPointer(pergroupstate->transValue));
413         }
414
415         pergroupstate->transValue = newVal;
416         pergroupstate->transValueIsNull = fcinfo->isnull;
417
418         MemoryContextSwitchTo(oldContext);
419 }
420
421 /*
422  * Advance all the aggregates for one input tuple.      The input tuple
423  * has been stored in tmpcontext->ecxt_outertuple, so that it is accessible
424  * to ExecEvalExpr.  pergroup is the array of per-group structs to use
425  * (this might be in a hashtable entry).
426  *
427  * When called, CurrentMemoryContext should be the per-query context.
428  */
429 static void
430 advance_aggregates(AggState *aggstate, AggStatePerGroup pergroup)
431 {
432         ExprContext *econtext = aggstate->tmpcontext;
433         int                     aggno;
434
435         for (aggno = 0; aggno < aggstate->numaggs; aggno++)
436         {
437                 AggStatePerAgg peraggstate = &aggstate->peragg[aggno];
438                 AggStatePerGroup pergroupstate = &pergroup[aggno];
439                 AggrefExprState *aggrefstate = peraggstate->aggrefstate;
440                 Aggref     *aggref = peraggstate->aggref;
441                 FunctionCallInfoData fcinfo;
442                 int                     i;
443                 ListCell   *arg;
444                 MemoryContext oldContext;
445
446                 /* Switch memory context just once for all args */
447                 oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
448
449                 /* Evaluate inputs and save in fcinfo */
450                 /* We start from 1, since the 0th arg will be the transition value */
451                 i = 1;
452                 foreach(arg, aggrefstate->args)
453                 {
454                         ExprState  *argstate = (ExprState *) lfirst(arg);
455
456                         fcinfo.arg[i] = ExecEvalExpr(argstate, econtext,
457                                                                                  fcinfo.argnull + i, NULL);
458                         i++;
459                 }
460
461                 /* Switch back */
462                 MemoryContextSwitchTo(oldContext);
463
464                 if (aggref->aggdistinct)
465                 {
466                         /* in DISTINCT mode, we may ignore nulls */
467                         /* XXX we assume there is only one input column */
468                         if (fcinfo.argnull[1])
469                                 continue;
470                         tuplesort_putdatum(peraggstate->sortstate, fcinfo.arg[1],
471                                                            fcinfo.argnull[1]);
472                 }
473                 else
474                 {
475                         advance_transition_function(aggstate, peraggstate, pergroupstate,
476                                                                                 &fcinfo);
477                 }
478         }
479 }
480
481 /*
482  * Run the transition function for a DISTINCT aggregate.  This is called
483  * after we have completed entering all the input values into the sort
484  * object.      We complete the sort, read out the values in sorted order,
485  * and run the transition function on each non-duplicate value.
486  *
487  * When called, CurrentMemoryContext should be the per-query context.
488  */
489 static void
490 process_sorted_aggregate(AggState *aggstate,
491                                                  AggStatePerAgg peraggstate,
492                                                  AggStatePerGroup pergroupstate)
493 {
494         Datum           oldVal = (Datum) 0;
495         bool            haveOldVal = false;
496         MemoryContext workcontext = aggstate->tmpcontext->ecxt_per_tuple_memory;
497         MemoryContext oldContext;
498         Datum      *newVal;
499         bool       *isNull;
500         FunctionCallInfoData fcinfo;
501
502         tuplesort_performsort(peraggstate->sortstate);
503
504         newVal = fcinfo.arg + 1;
505         isNull = fcinfo.argnull + 1;
506
507         /*
508          * Note: if input type is pass-by-ref, the datums returned by the sort are
509          * freshly palloc'd in the per-query context, so we must be careful to
510          * pfree them when they are no longer needed.
511          */
512
513         while (tuplesort_getdatum(peraggstate->sortstate, true,
514                                                           newVal, isNull))
515         {
516                 /*
517                  * DISTINCT always suppresses nulls, per SQL spec, regardless of the
518                  * transition function's strictness.
519                  */
520                 if (*isNull)
521                         continue;
522
523                 /*
524                  * Clear and select the working context for evaluation of the equality
525                  * function and transition function.
526                  */
527                 MemoryContextReset(workcontext);
528                 oldContext = MemoryContextSwitchTo(workcontext);
529
530                 if (haveOldVal &&
531                         DatumGetBool(FunctionCall2(&peraggstate->equalfn,
532                                                                            oldVal, *newVal)))
533                 {
534                         /* equal to prior, so forget this one */
535                         if (!peraggstate->inputtypeByVal)
536                                 pfree(DatumGetPointer(*newVal));
537                 }
538                 else
539                 {
540                         advance_transition_function(aggstate, peraggstate, pergroupstate,
541                                                                                 &fcinfo);
542                         /* forget the old value, if any */
543                         if (haveOldVal && !peraggstate->inputtypeByVal)
544                                 pfree(DatumGetPointer(oldVal));
545                         /* and remember the new one for subsequent equality checks */
546                         oldVal = *newVal;
547                         haveOldVal = true;
548                 }
549
550                 MemoryContextSwitchTo(oldContext);
551         }
552
553         if (haveOldVal && !peraggstate->inputtypeByVal)
554                 pfree(DatumGetPointer(oldVal));
555
556         tuplesort_end(peraggstate->sortstate);
557         peraggstate->sortstate = NULL;
558 }
559
560 /*
561  * Compute the final value of one aggregate.
562  *
563  * The finalfunction will be run, and the result delivered, in the
564  * output-tuple context; caller's CurrentMemoryContext does not matter.
565  */
566 static void
567 finalize_aggregate(AggState *aggstate,
568                                    AggStatePerAgg peraggstate,
569                                    AggStatePerGroup pergroupstate,
570                                    Datum *resultVal, bool *resultIsNull)
571 {
572         MemoryContext oldContext;
573
574         oldContext = MemoryContextSwitchTo(aggstate->ss.ps.ps_ExprContext->ecxt_per_tuple_memory);
575
576         /*
577          * Apply the agg's finalfn if one is provided, else return transValue.
578          */
579         if (OidIsValid(peraggstate->finalfn_oid))
580         {
581                 FunctionCallInfoData fcinfo;
582
583                 InitFunctionCallInfoData(fcinfo, &(peraggstate->finalfn), 1,
584                                                                  (void *) aggstate, NULL);
585                 fcinfo.arg[0] = pergroupstate->transValue;
586                 fcinfo.argnull[0] = pergroupstate->transValueIsNull;
587                 if (fcinfo.flinfo->fn_strict && pergroupstate->transValueIsNull)
588                 {
589                         /* don't call a strict function with NULL inputs */
590                         *resultVal = (Datum) 0;
591                         *resultIsNull = true;
592                 }
593                 else
594                 {
595                         *resultVal = FunctionCallInvoke(&fcinfo);
596                         *resultIsNull = fcinfo.isnull;
597                 }
598         }
599         else
600         {
601                 *resultVal = pergroupstate->transValue;
602                 *resultIsNull = pergroupstate->transValueIsNull;
603         }
604
605         /*
606          * If result is pass-by-ref, make sure it is in the right context.
607          */
608         if (!peraggstate->resulttypeByVal && !*resultIsNull &&
609                 !MemoryContextContains(CurrentMemoryContext,
610                                                            DatumGetPointer(*resultVal)))
611                 *resultVal = datumCopy(*resultVal,
612                                                            peraggstate->resulttypeByVal,
613                                                            peraggstate->resulttypeLen);
614
615         MemoryContextSwitchTo(oldContext);
616 }
617
618 /*
619  * find_unaggregated_cols
620  *        Construct a bitmapset of the column numbers of un-aggregated Vars
621  *        appearing in our targetlist and qual (HAVING clause)
622  */
623 static Bitmapset *
624 find_unaggregated_cols(AggState *aggstate)
625 {
626         Agg                *node = (Agg *) aggstate->ss.ps.plan;
627         Bitmapset  *colnos;
628
629         colnos = NULL;
630         (void) find_unaggregated_cols_walker((Node *) node->plan.targetlist,
631                                                                                  &colnos);
632         (void) find_unaggregated_cols_walker((Node *) node->plan.qual,
633                                                                                  &colnos);
634         return colnos;
635 }
636
637 static bool
638 find_unaggregated_cols_walker(Node *node, Bitmapset **colnos)
639 {
640         if (node == NULL)
641                 return false;
642         if (IsA(node, Var))
643         {
644                 Var                *var = (Var *) node;
645
646                 /* setrefs.c should have set the varno to OUTER */
647                 Assert(var->varno == OUTER);
648                 Assert(var->varlevelsup == 0);
649                 *colnos = bms_add_member(*colnos, var->varattno);
650                 return false;
651         }
652         if (IsA(node, Aggref))          /* do not descend into aggregate exprs */
653                 return false;
654         return expression_tree_walker(node, find_unaggregated_cols_walker,
655                                                                   (void *) colnos);
656 }
657
658 /*
659  * Initialize the hash table to empty.
660  *
661  * The hash table always lives in the aggcontext memory context.
662  */
663 static void
664 build_hash_table(AggState *aggstate)
665 {
666         Agg                *node = (Agg *) aggstate->ss.ps.plan;
667         MemoryContext tmpmem = aggstate->tmpcontext->ecxt_per_tuple_memory;
668         Size            entrysize;
669         Bitmapset  *colnos;
670         List       *collist;
671         int                     i;
672
673         Assert(node->aggstrategy == AGG_HASHED);
674         Assert(node->numGroups > 0);
675
676         entrysize = sizeof(AggHashEntryData) +
677                 (aggstate->numaggs - 1) *sizeof(AggStatePerGroupData);
678
679         aggstate->hashtable = BuildTupleHashTable(node->numCols,
680                                                                                           node->grpColIdx,
681                                                                                           aggstate->eqfunctions,
682                                                                                           aggstate->hashfunctions,
683                                                                                           node->numGroups,
684                                                                                           entrysize,
685                                                                                           aggstate->aggcontext,
686                                                                                           tmpmem);
687
688         /*
689          * Create a list of the tuple columns that actually need to be stored in
690          * hashtable entries.  The incoming tuples from the child plan node will
691          * contain grouping columns, other columns referenced in our targetlist
692          * and qual, columns used to compute the aggregate functions, and perhaps
693          * just junk columns we don't use at all.  Only columns of the first two
694          * types need to be stored in the hashtable, and getting rid of the others
695          * can make the table entries significantly smaller.  To avoid messing up
696          * Var numbering, we keep the same tuple descriptor for hashtable entries
697          * as the incoming tuples have, but set unwanted columns to NULL in the
698          * tuples that go into the table.
699          *
700          * To eliminate duplicates, we build a bitmapset of the needed columns,
701          * then convert it to an integer list (cheaper to scan at runtime). The
702          * list is in decreasing order so that the first entry is the largest;
703          * lookup_hash_entry depends on this to use slot_getsomeattrs correctly.
704          *
705          * Note: at present, searching the tlist/qual is not really necessary
706          * since the parser should disallow any unaggregated references to
707          * ungrouped columns.  However, the search will be needed when we add
708          * support for SQL99 semantics that allow use of "functionally dependent"
709          * columns that haven't been explicitly grouped by.
710          */
711
712         /* Find Vars that will be needed in tlist and qual */
713         colnos = find_unaggregated_cols(aggstate);
714         /* Add in all the grouping columns */
715         for (i = 0; i < node->numCols; i++)
716                 colnos = bms_add_member(colnos, node->grpColIdx[i]);
717         /* Convert to list, using lcons so largest element ends up first */
718         collist = NIL;
719         while ((i = bms_first_member(colnos)) >= 0)
720                 collist = lcons_int(i, collist);
721         aggstate->hash_needed = collist;
722 }
723
724 /*
725  * Estimate per-hash-table-entry overhead for the planner.
726  *
727  * Note that the estimate does not include space for pass-by-reference
728  * transition data values, nor for the representative tuple of each group.
729  */
730 Size
731 hash_agg_entry_size(int numAggs)
732 {
733         Size            entrysize;
734
735         /* This must match build_hash_table */
736         entrysize = sizeof(AggHashEntryData) +
737                 (numAggs - 1) *sizeof(AggStatePerGroupData);
738         entrysize = MAXALIGN(entrysize);
739         /* Account for hashtable overhead (assuming fill factor = 1) */
740         entrysize += 3 * sizeof(void *);
741         return entrysize;
742 }
743
744 /*
745  * Find or create a hashtable entry for the tuple group containing the
746  * given tuple.
747  *
748  * When called, CurrentMemoryContext should be the per-query context.
749  */
750 static AggHashEntry
751 lookup_hash_entry(AggState *aggstate, TupleTableSlot *inputslot)
752 {
753         TupleTableSlot *hashslot = aggstate->hashslot;
754         ListCell   *l;
755         AggHashEntry entry;
756         bool            isnew;
757
758         /* if first time through, initialize hashslot by cloning input slot */
759         if (hashslot->tts_tupleDescriptor == NULL)
760         {
761                 ExecSetSlotDescriptor(hashslot, inputslot->tts_tupleDescriptor);
762                 /* Make sure all unused columns are NULLs */
763                 ExecStoreAllNullTuple(hashslot);
764         }
765
766         /* transfer just the needed columns into hashslot */
767         slot_getsomeattrs(inputslot, linitial_int(aggstate->hash_needed));
768         foreach(l, aggstate->hash_needed)
769         {
770                 int                     varNumber = lfirst_int(l) - 1;
771
772                 hashslot->tts_values[varNumber] = inputslot->tts_values[varNumber];
773                 hashslot->tts_isnull[varNumber] = inputslot->tts_isnull[varNumber];
774         }
775
776         /* find or create the hashtable entry using the filtered tuple */
777         entry = (AggHashEntry) LookupTupleHashEntry(aggstate->hashtable,
778                                                                                                 hashslot,
779                                                                                                 &isnew);
780
781         if (isnew)
782         {
783                 /* initialize aggregates for new tuple group */
784                 initialize_aggregates(aggstate, aggstate->peragg, entry->pergroup);
785         }
786
787         return entry;
788 }
789
790 /*
791  * ExecAgg -
792  *
793  *        ExecAgg receives tuples from its outer subplan and aggregates over
794  *        the appropriate attribute for each aggregate function use (Aggref
795  *        node) appearing in the targetlist or qual of the node.  The number
796  *        of tuples to aggregate over depends on whether grouped or plain
797  *        aggregation is selected.      In grouped aggregation, we produce a result
798  *        row for each group; in plain aggregation there's a single result row
799  *        for the whole query.  In either case, the value of each aggregate is
800  *        stored in the expression context to be used when ExecProject evaluates
801  *        the result tuple.
802  */
803 TupleTableSlot *
804 ExecAgg(AggState *node)
805 {
806         if (node->agg_done)
807                 return NULL;
808
809         if (((Agg *) node->ss.ps.plan)->aggstrategy == AGG_HASHED)
810         {
811                 if (!node->table_filled)
812                         agg_fill_hash_table(node);
813                 return agg_retrieve_hash_table(node);
814         }
815         else
816                 return agg_retrieve_direct(node);
817 }
818
819 /*
820  * ExecAgg for non-hashed case
821  */
822 static TupleTableSlot *
823 agg_retrieve_direct(AggState *aggstate)
824 {
825         Agg                *node = (Agg *) aggstate->ss.ps.plan;
826         PlanState  *outerPlan;
827         ExprContext *econtext;
828         ExprContext *tmpcontext;
829         ProjectionInfo *projInfo;
830         Datum      *aggvalues;
831         bool       *aggnulls;
832         AggStatePerAgg peragg;
833         AggStatePerGroup pergroup;
834         TupleTableSlot *outerslot;
835         TupleTableSlot *firstSlot;
836         int                     aggno;
837
838         /*
839          * get state info from node
840          */
841         outerPlan = outerPlanState(aggstate);
842         /* econtext is the per-output-tuple expression context */
843         econtext = aggstate->ss.ps.ps_ExprContext;
844         aggvalues = econtext->ecxt_aggvalues;
845         aggnulls = econtext->ecxt_aggnulls;
846         /* tmpcontext is the per-input-tuple expression context */
847         tmpcontext = aggstate->tmpcontext;
848         projInfo = aggstate->ss.ps.ps_ProjInfo;
849         peragg = aggstate->peragg;
850         pergroup = aggstate->pergroup;
851         firstSlot = aggstate->ss.ss_ScanTupleSlot;
852
853         /*
854          * We loop retrieving groups until we find one matching
855          * aggstate->ss.ps.qual
856          */
857         while (!aggstate->agg_done)
858         {
859                 /*
860                  * If we don't already have the first tuple of the new group, fetch it
861                  * from the outer plan.
862                  */
863                 if (aggstate->grp_firstTuple == NULL)
864                 {
865                         outerslot = ExecProcNode(outerPlan);
866                         if (!TupIsNull(outerslot))
867                         {
868                                 /*
869                                  * Make a copy of the first input tuple; we will use this for
870                                  * comparisons (in group mode) and for projection.
871                                  */
872                                 aggstate->grp_firstTuple = ExecCopySlotTuple(outerslot);
873                         }
874                         else
875                         {
876                                 /* outer plan produced no tuples at all */
877                                 aggstate->agg_done = true;
878                                 /* If we are grouping, we should produce no tuples too */
879                                 if (node->aggstrategy != AGG_PLAIN)
880                                         return NULL;
881                         }
882                 }
883
884                 /*
885                  * Clear the per-output-tuple context for each group
886                  */
887                 ResetExprContext(econtext);
888
889                 /*
890                  * Initialize working state for a new input tuple group
891                  */
892                 initialize_aggregates(aggstate, peragg, pergroup);
893
894                 if (aggstate->grp_firstTuple != NULL)
895                 {
896                         /*
897                          * Store the copied first input tuple in the tuple table slot
898                          * reserved for it.  The tuple will be deleted when it is cleared
899                          * from the slot.
900                          */
901                         ExecStoreTuple(aggstate->grp_firstTuple,
902                                                    firstSlot,
903                                                    InvalidBuffer,
904                                                    true);
905                         aggstate->grp_firstTuple = NULL;        /* don't keep two pointers */
906
907                         /* set up for first advance_aggregates call */
908                         tmpcontext->ecxt_outertuple = firstSlot;
909
910                         /*
911                          * Process each outer-plan tuple, and then fetch the next one,
912                          * until we exhaust the outer plan or cross a group boundary.
913                          */
914                         for (;;)
915                         {
916                                 advance_aggregates(aggstate, pergroup);
917
918                                 /* Reset per-input-tuple context after each tuple */
919                                 ResetExprContext(tmpcontext);
920
921                                 outerslot = ExecProcNode(outerPlan);
922                                 if (TupIsNull(outerslot))
923                                 {
924                                         /* no more outer-plan tuples available */
925                                         aggstate->agg_done = true;
926                                         break;
927                                 }
928                                 /* set up for next advance_aggregates call */
929                                 tmpcontext->ecxt_outertuple = outerslot;
930
931                                 /*
932                                  * If we are grouping, check whether we've crossed a group
933                                  * boundary.
934                                  */
935                                 if (node->aggstrategy == AGG_SORTED)
936                                 {
937                                         if (!execTuplesMatch(firstSlot,
938                                                                                  outerslot,
939                                                                                  node->numCols, node->grpColIdx,
940                                                                                  aggstate->eqfunctions,
941                                                                                  tmpcontext->ecxt_per_tuple_memory))
942                                         {
943                                                 /*
944                                                  * Save the first input tuple of the next group.
945                                                  */
946                                                 aggstate->grp_firstTuple = ExecCopySlotTuple(outerslot);
947                                                 break;
948                                         }
949                                 }
950                         }
951                 }
952
953                 /*
954                  * Done scanning input tuple group. Finalize each aggregate
955                  * calculation, and stash results in the per-output-tuple context.
956                  */
957                 for (aggno = 0; aggno < aggstate->numaggs; aggno++)
958                 {
959                         AggStatePerAgg peraggstate = &peragg[aggno];
960                         AggStatePerGroup pergroupstate = &pergroup[aggno];
961
962                         if (peraggstate->aggref->aggdistinct)
963                                 process_sorted_aggregate(aggstate, peraggstate, pergroupstate);
964
965                         finalize_aggregate(aggstate, peraggstate, pergroupstate,
966                                                            &aggvalues[aggno], &aggnulls[aggno]);
967                 }
968
969                 /*
970                  * Use the representative input tuple for any references to
971                  * non-aggregated input columns in the qual and tlist.  (If we are not
972                  * grouping, and there are no input rows at all, we will come here
973                  * with an empty firstSlot ... but if not grouping, there can't be any
974                  * references to non-aggregated input columns, so no problem.)
975                  */
976                 econtext->ecxt_outertuple = firstSlot;
977
978                 /*
979                  * Check the qual (HAVING clause); if the group does not match, ignore
980                  * it and loop back to try to process another group.
981                  */
982                 if (ExecQual(aggstate->ss.ps.qual, econtext, false))
983                 {
984                         /*
985                          * Form and return a projection tuple using the aggregate results
986                          * and the representative input tuple.  Note we do not support
987                          * aggregates returning sets ...
988                          */
989                         return ExecProject(projInfo, NULL);
990                 }
991         }
992
993         /* No more groups */
994         return NULL;
995 }
996
997 /*
998  * ExecAgg for hashed case: phase 1, read input and build hash table
999  */
1000 static void
1001 agg_fill_hash_table(AggState *aggstate)
1002 {
1003         PlanState  *outerPlan;
1004         ExprContext *tmpcontext;
1005         AggHashEntry entry;
1006         TupleTableSlot *outerslot;
1007
1008         /*
1009          * get state info from node
1010          */
1011         outerPlan = outerPlanState(aggstate);
1012         /* tmpcontext is the per-input-tuple expression context */
1013         tmpcontext = aggstate->tmpcontext;
1014
1015         /*
1016          * Process each outer-plan tuple, and then fetch the next one, until we
1017          * exhaust the outer plan.
1018          */
1019         for (;;)
1020         {
1021                 outerslot = ExecProcNode(outerPlan);
1022                 if (TupIsNull(outerslot))
1023                         break;
1024                 /* set up for advance_aggregates call */
1025                 tmpcontext->ecxt_outertuple = outerslot;
1026
1027                 /* Find or build hashtable entry for this tuple's group */
1028                 entry = lookup_hash_entry(aggstate, outerslot);
1029
1030                 /* Advance the aggregates */
1031                 advance_aggregates(aggstate, entry->pergroup);
1032
1033                 /* Reset per-input-tuple context after each tuple */
1034                 ResetExprContext(tmpcontext);
1035         }
1036
1037         aggstate->table_filled = true;
1038         /* Initialize to walk the hash table */
1039         ResetTupleHashIterator(aggstate->hashtable, &aggstate->hashiter);
1040 }
1041
1042 /*
1043  * ExecAgg for hashed case: phase 2, retrieving groups from hash table
1044  */
1045 static TupleTableSlot *
1046 agg_retrieve_hash_table(AggState *aggstate)
1047 {
1048         ExprContext *econtext;
1049         ProjectionInfo *projInfo;
1050         Datum      *aggvalues;
1051         bool       *aggnulls;
1052         AggStatePerAgg peragg;
1053         AggStatePerGroup pergroup;
1054         AggHashEntry entry;
1055         TupleTableSlot *firstSlot;
1056         int                     aggno;
1057
1058         /*
1059          * get state info from node
1060          */
1061         /* econtext is the per-output-tuple expression context */
1062         econtext = aggstate->ss.ps.ps_ExprContext;
1063         aggvalues = econtext->ecxt_aggvalues;
1064         aggnulls = econtext->ecxt_aggnulls;
1065         projInfo = aggstate->ss.ps.ps_ProjInfo;
1066         peragg = aggstate->peragg;
1067         firstSlot = aggstate->ss.ss_ScanTupleSlot;
1068
1069         /*
1070          * We loop retrieving groups until we find one satisfying
1071          * aggstate->ss.ps.qual
1072          */
1073         while (!aggstate->agg_done)
1074         {
1075                 /*
1076                  * Find the next entry in the hash table
1077                  */
1078                 entry = (AggHashEntry) ScanTupleHashTable(&aggstate->hashiter);
1079                 if (entry == NULL)
1080                 {
1081                         /* No more entries in hashtable, so done */
1082                         aggstate->agg_done = TRUE;
1083                         return NULL;
1084                 }
1085
1086                 /*
1087                  * Clear the per-output-tuple context for each group
1088                  */
1089                 ResetExprContext(econtext);
1090
1091                 /*
1092                  * Store the copied first input tuple in the tuple table slot reserved
1093                  * for it, so that it can be used in ExecProject.
1094                  */
1095                 ExecStoreMinimalTuple(entry->shared.firstTuple,
1096                                                           firstSlot,
1097                                                           false);
1098
1099                 pergroup = entry->pergroup;
1100
1101                 /*
1102                  * Finalize each aggregate calculation, and stash results in the
1103                  * per-output-tuple context.
1104                  */
1105                 for (aggno = 0; aggno < aggstate->numaggs; aggno++)
1106                 {
1107                         AggStatePerAgg peraggstate = &peragg[aggno];
1108                         AggStatePerGroup pergroupstate = &pergroup[aggno];
1109
1110                         Assert(!peraggstate->aggref->aggdistinct);
1111                         finalize_aggregate(aggstate, peraggstate, pergroupstate,
1112                                                            &aggvalues[aggno], &aggnulls[aggno]);
1113                 }
1114
1115                 /*
1116                  * Use the representative input tuple for any references to
1117                  * non-aggregated input columns in the qual and tlist.
1118                  */
1119                 econtext->ecxt_outertuple = firstSlot;
1120
1121                 /*
1122                  * Check the qual (HAVING clause); if the group does not match, ignore
1123                  * it and loop back to try to process another group.
1124                  */
1125                 if (ExecQual(aggstate->ss.ps.qual, econtext, false))
1126                 {
1127                         /*
1128                          * Form and return a projection tuple using the aggregate results
1129                          * and the representative input tuple.  Note we do not support
1130                          * aggregates returning sets ...
1131                          */
1132                         return ExecProject(projInfo, NULL);
1133                 }
1134         }
1135
1136         /* No more groups */
1137         return NULL;
1138 }
1139
1140 /* -----------------
1141  * ExecInitAgg
1142  *
1143  *      Creates the run-time information for the agg node produced by the
1144  *      planner and initializes its outer subtree
1145  * -----------------
1146  */
1147 AggState *
1148 ExecInitAgg(Agg *node, EState *estate, int eflags)
1149 {
1150         AggState   *aggstate;
1151         AggStatePerAgg peragg;
1152         Plan       *outerPlan;
1153         ExprContext *econtext;
1154         int                     numaggs,
1155                                 aggno;
1156         ListCell   *l;
1157
1158         /* check for unsupported flags */
1159         Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
1160
1161         /*
1162          * create state structure
1163          */
1164         aggstate = makeNode(AggState);
1165         aggstate->ss.ps.plan = (Plan *) node;
1166         aggstate->ss.ps.state = estate;
1167
1168         aggstate->aggs = NIL;
1169         aggstate->numaggs = 0;
1170         aggstate->eqfunctions = NULL;
1171         aggstate->hashfunctions = NULL;
1172         aggstate->peragg = NULL;
1173         aggstate->agg_done = false;
1174         aggstate->pergroup = NULL;
1175         aggstate->grp_firstTuple = NULL;
1176         aggstate->hashtable = NULL;
1177
1178         /*
1179          * Create expression contexts.  We need two, one for per-input-tuple
1180          * processing and one for per-output-tuple processing.  We cheat a little
1181          * by using ExecAssignExprContext() to build both.
1182          */
1183         ExecAssignExprContext(estate, &aggstate->ss.ps);
1184         aggstate->tmpcontext = aggstate->ss.ps.ps_ExprContext;
1185         ExecAssignExprContext(estate, &aggstate->ss.ps);
1186
1187         /*
1188          * We also need a long-lived memory context for holding hashtable data
1189          * structures and transition values.  NOTE: the details of what is stored
1190          * in aggcontext and what is stored in the regular per-query memory
1191          * context are driven by a simple decision: we want to reset the
1192          * aggcontext in ExecReScanAgg to recover no-longer-wanted space.
1193          */
1194         aggstate->aggcontext =
1195                 AllocSetContextCreate(CurrentMemoryContext,
1196                                                           "AggContext",
1197                                                           ALLOCSET_DEFAULT_MINSIZE,
1198                                                           ALLOCSET_DEFAULT_INITSIZE,
1199                                                           ALLOCSET_DEFAULT_MAXSIZE);
1200
1201 #define AGG_NSLOTS 3
1202
1203         /*
1204          * tuple table initialization
1205          */
1206         ExecInitScanTupleSlot(estate, &aggstate->ss);
1207         ExecInitResultTupleSlot(estate, &aggstate->ss.ps);
1208         aggstate->hashslot = ExecInitExtraTupleSlot(estate);
1209
1210         /*
1211          * initialize child expressions
1212          *
1213          * Note: ExecInitExpr finds Aggrefs for us, and also checks that no aggs
1214          * contain other agg calls in their arguments.  This would make no sense
1215          * under SQL semantics anyway (and it's forbidden by the spec). Because
1216          * that is true, we don't need to worry about evaluating the aggs in any
1217          * particular order.
1218          */
1219         aggstate->ss.ps.targetlist = (List *)
1220                 ExecInitExpr((Expr *) node->plan.targetlist,
1221                                          (PlanState *) aggstate);
1222         aggstate->ss.ps.qual = (List *)
1223                 ExecInitExpr((Expr *) node->plan.qual,
1224                                          (PlanState *) aggstate);
1225
1226         /*
1227          * initialize child nodes
1228          *
1229          * If we are doing a hashed aggregation then the child plan does not need
1230          * to handle REWIND efficiently; see ExecReScanAgg.
1231          */
1232         if (node->aggstrategy == AGG_HASHED)
1233                 eflags &= ~EXEC_FLAG_REWIND;
1234         outerPlan = outerPlan(node);
1235         outerPlanState(aggstate) = ExecInitNode(outerPlan, estate, eflags);
1236
1237         /*
1238          * initialize source tuple type.
1239          */
1240         ExecAssignScanTypeFromOuterPlan(&aggstate->ss);
1241
1242         /*
1243          * Initialize result tuple type and projection info.
1244          */
1245         ExecAssignResultTypeFromTL(&aggstate->ss.ps);
1246         ExecAssignProjectionInfo(&aggstate->ss.ps, NULL);
1247
1248         /*
1249          * get the count of aggregates in targetlist and quals
1250          */
1251         numaggs = aggstate->numaggs;
1252         Assert(numaggs == list_length(aggstate->aggs));
1253         if (numaggs <= 0)
1254         {
1255                 /*
1256                  * This is not an error condition: we might be using the Agg node just
1257                  * to do hash-based grouping.  Even in the regular case,
1258                  * constant-expression simplification could optimize away all of the
1259                  * Aggrefs in the targetlist and qual.  So keep going, but force local
1260                  * copy of numaggs positive so that palloc()s below don't choke.
1261                  */
1262                 numaggs = 1;
1263         }
1264
1265         /*
1266          * If we are grouping, precompute fmgr lookup data for inner loop. We need
1267          * both equality and hashing functions to do it by hashing, but only
1268          * equality if not hashing.
1269          */
1270         if (node->numCols > 0)
1271         {
1272                 if (node->aggstrategy == AGG_HASHED)
1273                         execTuplesHashPrepare(node->numCols,
1274                                                                   node->grpOperators,
1275                                                                   &aggstate->eqfunctions,
1276                                                                   &aggstate->hashfunctions);
1277                 else
1278                         aggstate->eqfunctions =
1279                                 execTuplesMatchPrepare(node->numCols,
1280                                                                            node->grpOperators);
1281         }
1282
1283         /*
1284          * Set up aggregate-result storage in the output expr context, and also
1285          * allocate my private per-agg working storage
1286          */
1287         econtext = aggstate->ss.ps.ps_ExprContext;
1288         econtext->ecxt_aggvalues = (Datum *) palloc0(sizeof(Datum) * numaggs);
1289         econtext->ecxt_aggnulls = (bool *) palloc0(sizeof(bool) * numaggs);
1290
1291         peragg = (AggStatePerAgg) palloc0(sizeof(AggStatePerAggData) * numaggs);
1292         aggstate->peragg = peragg;
1293
1294         if (node->aggstrategy == AGG_HASHED)
1295         {
1296                 build_hash_table(aggstate);
1297                 aggstate->table_filled = false;
1298         }
1299         else
1300         {
1301                 AggStatePerGroup pergroup;
1302
1303                 pergroup = (AggStatePerGroup) palloc0(sizeof(AggStatePerGroupData) * numaggs);
1304                 aggstate->pergroup = pergroup;
1305         }
1306
1307         /*
1308          * Perform lookups of aggregate function info, and initialize the
1309          * unchanging fields of the per-agg data.  We also detect duplicate
1310          * aggregates (for example, "SELECT sum(x) ... HAVING sum(x) > 0"). When
1311          * duplicates are detected, we only make an AggStatePerAgg struct for the
1312          * first one.  The clones are simply pointed at the same result entry by
1313          * giving them duplicate aggno values.
1314          */
1315         aggno = -1;
1316         foreach(l, aggstate->aggs)
1317         {
1318                 AggrefExprState *aggrefstate = (AggrefExprState *) lfirst(l);
1319                 Aggref     *aggref = (Aggref *) aggrefstate->xprstate.expr;
1320                 AggStatePerAgg peraggstate;
1321                 Oid                     inputTypes[FUNC_MAX_ARGS];
1322                 int                     numArguments;
1323                 HeapTuple       aggTuple;
1324                 Form_pg_aggregate aggform;
1325                 Oid                     aggtranstype;
1326                 AclResult       aclresult;
1327                 Oid                     transfn_oid,
1328                                         finalfn_oid;
1329                 Expr       *transfnexpr,
1330                                    *finalfnexpr;
1331                 Datum           textInitVal;
1332                 int                     i;
1333                 ListCell   *lc;
1334
1335                 /* Planner should have assigned aggregate to correct level */
1336                 Assert(aggref->agglevelsup == 0);
1337
1338                 /* Look for a previous duplicate aggregate */
1339                 for (i = 0; i <= aggno; i++)
1340                 {
1341                         if (equal(aggref, peragg[i].aggref) &&
1342                                 !contain_volatile_functions((Node *) aggref))
1343                                 break;
1344                 }
1345                 if (i <= aggno)
1346                 {
1347                         /* Found a match to an existing entry, so just mark it */
1348                         aggrefstate->aggno = i;
1349                         continue;
1350                 }
1351
1352                 /* Nope, so assign a new PerAgg record */
1353                 peraggstate = &peragg[++aggno];
1354
1355                 /* Mark Aggref state node with assigned index in the result array */
1356                 aggrefstate->aggno = aggno;
1357
1358                 /* Fill in the peraggstate data */
1359                 peraggstate->aggrefstate = aggrefstate;
1360                 peraggstate->aggref = aggref;
1361                 numArguments = list_length(aggref->args);
1362                 peraggstate->numArguments = numArguments;
1363
1364                 /*
1365                  * Get actual datatypes of the inputs.  These could be different from
1366                  * the agg's declared input types, when the agg accepts ANY or a
1367                  * polymorphic type.
1368                  */
1369                 i = 0;
1370                 foreach(lc, aggref->args)
1371                 {
1372                         inputTypes[i++] = exprType((Node *) lfirst(lc));
1373                 }
1374
1375                 aggTuple = SearchSysCache(AGGFNOID,
1376                                                                   ObjectIdGetDatum(aggref->aggfnoid),
1377                                                                   0, 0, 0);
1378                 if (!HeapTupleIsValid(aggTuple))
1379                         elog(ERROR, "cache lookup failed for aggregate %u",
1380                                  aggref->aggfnoid);
1381                 aggform = (Form_pg_aggregate) GETSTRUCT(aggTuple);
1382
1383                 /* Check permission to call aggregate function */
1384                 aclresult = pg_proc_aclcheck(aggref->aggfnoid, GetUserId(),
1385                                                                          ACL_EXECUTE);
1386                 if (aclresult != ACLCHECK_OK)
1387                         aclcheck_error(aclresult, ACL_KIND_PROC,
1388                                                    get_func_name(aggref->aggfnoid));
1389
1390                 peraggstate->transfn_oid = transfn_oid = aggform->aggtransfn;
1391                 peraggstate->finalfn_oid = finalfn_oid = aggform->aggfinalfn;
1392
1393                 /* Check that aggregate owner has permission to call component fns */
1394                 {
1395                         HeapTuple       procTuple;
1396                         Oid                     aggOwner;
1397
1398                         procTuple = SearchSysCache(PROCOID,
1399                                                                            ObjectIdGetDatum(aggref->aggfnoid),
1400                                                                            0, 0, 0);
1401                         if (!HeapTupleIsValid(procTuple))
1402                                 elog(ERROR, "cache lookup failed for function %u",
1403                                          aggref->aggfnoid);
1404                         aggOwner = ((Form_pg_proc) GETSTRUCT(procTuple))->proowner;
1405                         ReleaseSysCache(procTuple);
1406
1407                         aclresult = pg_proc_aclcheck(transfn_oid, aggOwner,
1408                                                                                  ACL_EXECUTE);
1409                         if (aclresult != ACLCHECK_OK)
1410                                 aclcheck_error(aclresult, ACL_KIND_PROC,
1411                                                            get_func_name(transfn_oid));
1412                         if (OidIsValid(finalfn_oid))
1413                         {
1414                                 aclresult = pg_proc_aclcheck(finalfn_oid, aggOwner,
1415                                                                                          ACL_EXECUTE);
1416                                 if (aclresult != ACLCHECK_OK)
1417                                         aclcheck_error(aclresult, ACL_KIND_PROC,
1418                                                                    get_func_name(finalfn_oid));
1419                         }
1420                 }
1421
1422                 /* resolve actual type of transition state, if polymorphic */
1423                 aggtranstype = aggform->aggtranstype;
1424                 if (IsPolymorphicType(aggtranstype))
1425                 {
1426                         /* have to fetch the agg's declared input types... */
1427                         Oid                *declaredArgTypes;
1428                         int                     agg_nargs;
1429
1430                         (void) get_func_signature(aggref->aggfnoid,
1431                                                                           &declaredArgTypes, &agg_nargs);
1432                         Assert(agg_nargs == numArguments);
1433                         aggtranstype = enforce_generic_type_consistency(inputTypes,
1434                                                                                                                         declaredArgTypes,
1435                                                                                                                         agg_nargs,
1436                                                                                                                         aggtranstype);
1437                         pfree(declaredArgTypes);
1438                 }
1439
1440                 /* build expression trees using actual argument & result types */
1441                 build_aggregate_fnexprs(inputTypes,
1442                                                                 numArguments,
1443                                                                 aggtranstype,
1444                                                                 aggref->aggtype,
1445                                                                 transfn_oid,
1446                                                                 finalfn_oid,
1447                                                                 &transfnexpr,
1448                                                                 &finalfnexpr);
1449
1450                 fmgr_info(transfn_oid, &peraggstate->transfn);
1451                 peraggstate->transfn.fn_expr = (Node *) transfnexpr;
1452
1453                 if (OidIsValid(finalfn_oid))
1454                 {
1455                         fmgr_info(finalfn_oid, &peraggstate->finalfn);
1456                         peraggstate->finalfn.fn_expr = (Node *) finalfnexpr;
1457                 }
1458
1459                 get_typlenbyval(aggref->aggtype,
1460                                                 &peraggstate->resulttypeLen,
1461                                                 &peraggstate->resulttypeByVal);
1462                 get_typlenbyval(aggtranstype,
1463                                                 &peraggstate->transtypeLen,
1464                                                 &peraggstate->transtypeByVal);
1465
1466                 /*
1467                  * initval is potentially null, so don't try to access it as a struct
1468                  * field. Must do it the hard way with SysCacheGetAttr.
1469                  */
1470                 textInitVal = SysCacheGetAttr(AGGFNOID, aggTuple,
1471                                                                           Anum_pg_aggregate_agginitval,
1472                                                                           &peraggstate->initValueIsNull);
1473
1474                 if (peraggstate->initValueIsNull)
1475                         peraggstate->initValue = (Datum) 0;
1476                 else
1477                         peraggstate->initValue = GetAggInitVal(textInitVal,
1478                                                                                                    aggtranstype);
1479
1480                 /*
1481                  * If the transfn is strict and the initval is NULL, make sure input
1482                  * type and transtype are the same (or at least binary-compatible), so
1483                  * that it's OK to use the first input value as the initial
1484                  * transValue.  This should have been checked at agg definition time,
1485                  * but just in case...
1486                  */
1487                 if (peraggstate->transfn.fn_strict && peraggstate->initValueIsNull)
1488                 {
1489                         if (numArguments < 1 ||
1490                                 !IsBinaryCoercible(inputTypes[0], aggtranstype))
1491                                 ereport(ERROR,
1492                                                 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1493                                                  errmsg("aggregate %u needs to have compatible input type and transition type",
1494                                                                 aggref->aggfnoid)));
1495                 }
1496
1497                 if (aggref->aggdistinct)
1498                 {
1499                         Oid                     eq_function;
1500
1501                         /* We don't implement DISTINCT aggs in the HASHED case */
1502                         Assert(node->aggstrategy != AGG_HASHED);
1503
1504                         /*
1505                          * We don't currently implement DISTINCT aggs for aggs having more
1506                          * than one argument.  This isn't required for anything in the SQL
1507                          * spec, but really it ought to be implemented for
1508                          * feature-completeness.  FIXME someday.
1509                          */
1510                         if (numArguments != 1)
1511                                 ereport(ERROR,
1512                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1513                                                  errmsg("DISTINCT is supported only for single-argument aggregates")));
1514
1515                         peraggstate->inputType = inputTypes[0];
1516                         get_typlenbyval(inputTypes[0],
1517                                                         &peraggstate->inputtypeLen,
1518                                                         &peraggstate->inputtypeByVal);
1519
1520                         /*
1521                          * Look up the sorting and comparison operators to use.  XXX it's
1522                          * pretty bletcherous to be making this sort of semantic decision
1523                          * in the executor.  Probably the parser should decide this and
1524                          * record it in the Aggref node ... or at latest, do it in the
1525                          * planner.
1526                          */
1527                         eq_function = equality_oper_funcid(inputTypes[0]);
1528                         fmgr_info(eq_function, &(peraggstate->equalfn));
1529                         peraggstate->sortOperator = ordering_oper_opid(inputTypes[0]);
1530                         peraggstate->sortstate = NULL;
1531                 }
1532
1533                 ReleaseSysCache(aggTuple);
1534         }
1535
1536         /* Update numaggs to match number of unique aggregates found */
1537         aggstate->numaggs = aggno + 1;
1538
1539         return aggstate;
1540 }
1541
1542 static Datum
1543 GetAggInitVal(Datum textInitVal, Oid transtype)
1544 {
1545         Oid                     typinput,
1546                                 typioparam;
1547         char       *strInitVal;
1548         Datum           initVal;
1549
1550         getTypeInputInfo(transtype, &typinput, &typioparam);
1551         strInitVal = DatumGetCString(DirectFunctionCall1(textout, textInitVal));
1552         initVal = OidInputFunctionCall(typinput, strInitVal,
1553                                                                    typioparam, -1);
1554         pfree(strInitVal);
1555         return initVal;
1556 }
1557
1558 int
1559 ExecCountSlotsAgg(Agg *node)
1560 {
1561         return ExecCountSlotsNode(outerPlan(node)) +
1562                 ExecCountSlotsNode(innerPlan(node)) +
1563                 AGG_NSLOTS;
1564 }
1565
1566 void
1567 ExecEndAgg(AggState *node)
1568 {
1569         PlanState  *outerPlan;
1570         int                     aggno;
1571
1572         /* Make sure we have closed any open tuplesorts */
1573         for (aggno = 0; aggno < node->numaggs; aggno++)
1574         {
1575                 AggStatePerAgg peraggstate = &node->peragg[aggno];
1576
1577                 if (peraggstate->sortstate)
1578                         tuplesort_end(peraggstate->sortstate);
1579         }
1580
1581         /*
1582          * Free both the expr contexts.
1583          */
1584         ExecFreeExprContext(&node->ss.ps);
1585         node->ss.ps.ps_ExprContext = node->tmpcontext;
1586         ExecFreeExprContext(&node->ss.ps);
1587
1588         /* clean up tuple table */
1589         ExecClearTuple(node->ss.ss_ScanTupleSlot);
1590
1591         MemoryContextDelete(node->aggcontext);
1592
1593         outerPlan = outerPlanState(node);
1594         ExecEndNode(outerPlan);
1595 }
1596
1597 void
1598 ExecReScanAgg(AggState *node, ExprContext *exprCtxt)
1599 {
1600         ExprContext *econtext = node->ss.ps.ps_ExprContext;
1601         int                     aggno;
1602
1603         node->agg_done = false;
1604
1605         if (((Agg *) node->ss.ps.plan)->aggstrategy == AGG_HASHED)
1606         {
1607                 /*
1608                  * In the hashed case, if we haven't yet built the hash table then we
1609                  * can just return; nothing done yet, so nothing to undo. If subnode's
1610                  * chgParam is not NULL then it will be re-scanned by ExecProcNode,
1611                  * else no reason to re-scan it at all.
1612                  */
1613                 if (!node->table_filled)
1614                         return;
1615
1616                 /*
1617                  * If we do have the hash table and the subplan does not have any
1618                  * parameter changes, then we can just rescan the existing hash table;
1619                  * no need to build it again.
1620                  */
1621                 if (((PlanState *) node)->lefttree->chgParam == NULL)
1622                 {
1623                         ResetTupleHashIterator(node->hashtable, &node->hashiter);
1624                         return;
1625                 }
1626         }
1627
1628         /* Make sure we have closed any open tuplesorts */
1629         for (aggno = 0; aggno < node->numaggs; aggno++)
1630         {
1631                 AggStatePerAgg peraggstate = &node->peragg[aggno];
1632
1633                 if (peraggstate->sortstate)
1634                         tuplesort_end(peraggstate->sortstate);
1635                 peraggstate->sortstate = NULL;
1636         }
1637
1638         /* Release first tuple of group, if we have made a copy */
1639         if (node->grp_firstTuple != NULL)
1640         {
1641                 heap_freetuple(node->grp_firstTuple);
1642                 node->grp_firstTuple = NULL;
1643         }
1644
1645         /* Forget current agg values */
1646         MemSet(econtext->ecxt_aggvalues, 0, sizeof(Datum) * node->numaggs);
1647         MemSet(econtext->ecxt_aggnulls, 0, sizeof(bool) * node->numaggs);
1648
1649         /*
1650          * Release all temp storage. Note that with AGG_HASHED, the hash table is
1651          * allocated in a sub-context of the aggcontext. We're going to rebuild
1652          * the hash table from scratch, so we need to use
1653          * MemoryContextResetAndDeleteChildren() to avoid leaking the old hash
1654          * table's memory context header.
1655          */
1656         MemoryContextResetAndDeleteChildren(node->aggcontext);
1657
1658         if (((Agg *) node->ss.ps.plan)->aggstrategy == AGG_HASHED)
1659         {
1660                 /* Rebuild an empty hash table */
1661                 build_hash_table(node);
1662                 node->table_filled = false;
1663         }
1664         else
1665         {
1666                 /*
1667                  * Reset the per-group state (in particular, mark transvalues null)
1668                  */
1669                 MemSet(node->pergroup, 0,
1670                            sizeof(AggStatePerGroupData) * node->numaggs);
1671         }
1672
1673         /*
1674          * if chgParam of subnode is not null then plan will be re-scanned by
1675          * first ExecProcNode.
1676          */
1677         if (((PlanState *) node)->lefttree->chgParam == NULL)
1678                 ExecReScan(((PlanState *) node)->lefttree, exprCtxt);
1679 }
1680
1681 /*
1682  * aggregate_dummy - dummy execution routine for aggregate functions
1683  *
1684  * This function is listed as the implementation (prosrc field) of pg_proc
1685  * entries for aggregate functions.  Its only purpose is to throw an error
1686  * if someone mistakenly executes such a function in the normal way.
1687  *
1688  * Perhaps someday we could assign real meaning to the prosrc field of
1689  * an aggregate?
1690  */
1691 Datum
1692 aggregate_dummy(PG_FUNCTION_ARGS)
1693 {
1694         elog(ERROR, "aggregate function %u called as normal function",
1695                  fcinfo->flinfo->fn_oid);
1696         return (Datum) 0;                       /* keep compiler quiet */
1697 }