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