]> granicus.if.org Git - postgresql/blob - src/backend/executor/nodeAgg.c
First phase of implementing hash-based grouping/aggregation. An AGG plan
[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  *        When the transvalue datatype is pass-by-reference, we have to be
33  *        careful to ensure that the values survive across tuple cycles yet
34  *        are not allowed to accumulate until end of query.  We do this by
35  *        "ping-ponging" between two memory contexts; successive calls to the
36  *        transfunc are executed in alternate contexts, passing the previous
37  *        transvalue that is in the other context.      At the beginning of each
38  *        tuple cycle we can reset the current output context to avoid memory
39  *        usage growth.  Note: we must use MemoryContextContains() to check
40  *        whether the transfunc has perhaps handed us back one of its input
41  *        values rather than a freshly palloc'd value; if so, we copy the value
42  *        to the context we want it in.
43  *
44  *
45  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
46  * Portions Copyright (c) 1994, Regents of the University of California
47  *
48  * IDENTIFICATION
49  *        $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.91 2002/11/06 00:00:43 tgl Exp $
50  *
51  *-------------------------------------------------------------------------
52  */
53
54 #include "postgres.h"
55
56 #include "access/heapam.h"
57 #include "catalog/pg_aggregate.h"
58 #include "catalog/pg_operator.h"
59 #include "executor/executor.h"
60 #include "executor/nodeAgg.h"
61 #include "executor/nodeGroup.h"
62 #include "miscadmin.h"
63 #include "optimizer/clauses.h"
64 #include "parser/parse_coerce.h"
65 #include "parser/parse_expr.h"
66 #include "parser/parse_oper.h"
67 #include "utils/acl.h"
68 #include "utils/builtins.h"
69 #include "utils/lsyscache.h"
70 #include "utils/syscache.h"
71 #include "utils/tuplesort.h"
72 #include "utils/datum.h"
73
74
75 /*
76  * AggStatePerAggData - per-aggregate working state for the Agg scan
77  */
78 typedef struct AggStatePerAggData
79 {
80         /*
81          * These values are set up during ExecInitAgg() and do not change
82          * thereafter:
83          */
84
85         /* Link to Aggref node this working state is for */
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
144         Datum           transValue;
145         bool            transValueIsNull;
146
147         bool            noTransValue;   /* true if transValue not set yet */
148
149         /*
150          * Note: noTransValue initially has the same value as
151          * transValueIsNull, and if true both are cleared to false at the same
152          * time.  They are not the same though: if transfn later returns a
153          * NULL, we want to keep that NULL and not auto-replace it with a
154          * later input value. Only the first non-NULL input will be
155          * auto-substituted.
156          */
157 } AggStatePerAggData;
158
159
160 static void initialize_aggregate(AggStatePerAgg peraggstate);
161 static void advance_transition_function(AggStatePerAgg peraggstate,
162                                                         Datum newVal, bool isNull);
163 static void advance_aggregates(AggState *aggstate, ExprContext *econtext);
164 static void process_sorted_aggregate(AggState *aggstate,
165                                                  AggStatePerAgg peraggstate);
166 static void finalize_aggregate(AggStatePerAgg peraggstate,
167                                    Datum *resultVal, bool *resultIsNull);
168 static Datum GetAggInitVal(Datum textInitVal, Oid transtype);
169
170
171 /*
172  * Initialize one aggregate for a new set of input values.
173  *
174  * When called, CurrentMemoryContext should be the per-query context.
175  */
176 static void
177 initialize_aggregate(AggStatePerAgg peraggstate)
178 {
179         Aggref     *aggref = peraggstate->aggref;
180
181         /*
182          * Start a fresh sort operation for each DISTINCT aggregate.
183          */
184         if (aggref->aggdistinct)
185         {
186                 /*
187                  * In case of rescan, maybe there could be an uncompleted sort
188                  * operation?  Clean it up if so.
189                  */
190                 if (peraggstate->sortstate)
191                         tuplesort_end(peraggstate->sortstate);
192
193                 peraggstate->sortstate =
194                         tuplesort_begin_datum(peraggstate->inputType,
195                                                                   peraggstate->sortOperator,
196                                                                   false);
197         }
198
199         /*
200          * (Re)set transValue to the initial value.
201          *
202          * Note that when the initial value is pass-by-ref, we just reuse it
203          * without copying for each group.      Hence, transition function had
204          * better not scribble on its input, or it will fail for GROUP BY!
205          */
206         peraggstate->transValue = peraggstate->initValue;
207         peraggstate->transValueIsNull = peraggstate->initValueIsNull;
208
209         /*
210          * If the initial value for the transition state doesn't exist in the
211          * pg_aggregate table then we will let the first non-NULL value
212          * returned from the outer procNode become the initial value. (This is
213          * useful for aggregates like max() and min().)  The noTransValue flag
214          * signals that we still need to do this.
215          */
216         peraggstate->noTransValue = peraggstate->initValueIsNull;
217 }
218
219 /*
220  * Given a new input value, advance the transition function of an aggregate.
221  *
222  * When called, CurrentMemoryContext should be the context we want the
223  * transition function result to be delivered into on this cycle.
224  */
225 static void
226 advance_transition_function(AggStatePerAgg peraggstate,
227                                                         Datum newVal, bool isNull)
228 {
229         FunctionCallInfoData fcinfo;
230
231         if (peraggstate->transfn.fn_strict)
232         {
233                 if (isNull)
234                 {
235                         /*
236                          * For a strict transfn, nothing happens at a NULL input
237                          * tuple; we just keep the prior transValue.  However, if the
238                          * transtype is pass-by-ref, we have to copy it into the new
239                          * context because the old one is going to get reset.
240                          */
241                         if (!peraggstate->transValueIsNull)
242                                 peraggstate->transValue = datumCopy(peraggstate->transValue,
243                                                                                          peraggstate->transtypeByVal,
244                                                                                           peraggstate->transtypeLen);
245                         return;
246                 }
247                 if (peraggstate->noTransValue)
248                 {
249                         /*
250                          * transValue has not been initialized. This is the first
251                          * non-NULL input value. We use it as the initial value for
252                          * transValue. (We already checked that the agg's input type
253                          * is binary-compatible with its transtype, so straight copy
254                          * here is OK.)
255                          *
256                          * We had better copy the datum if it is pass-by-ref, since the
257                          * given pointer may be pointing into a scan tuple that will
258                          * be freed on the next iteration of the scan.
259                          */
260                         peraggstate->transValue = datumCopy(newVal,
261                                                                                          peraggstate->transtypeByVal,
262                                                                                           peraggstate->transtypeLen);
263                         peraggstate->transValueIsNull = false;
264                         peraggstate->noTransValue = false;
265                         return;
266                 }
267                 if (peraggstate->transValueIsNull)
268                 {
269                         /*
270                          * Don't call a strict function with NULL inputs.  Note it is
271                          * possible to get here despite the above tests, if the
272                          * transfn is strict *and* returned a NULL on a prior cycle.
273                          * If that happens we will propagate the NULL all the way to
274                          * the end.
275                          */
276                         return;
277                 }
278         }
279
280         /*
281          * OK to call the transition function
282          *
283          * This is heavily-used code, so manually zero just the necessary fields
284          * instead of using MemSet().  Compare FunctionCall2().
285          */
286
287         /* MemSet(&fcinfo, 0, sizeof(fcinfo)); */
288         fcinfo.context = NULL;
289         fcinfo.resultinfo = NULL;
290         fcinfo.isnull = false;
291
292         fcinfo.flinfo = &peraggstate->transfn;
293         fcinfo.nargs = 2;
294         fcinfo.arg[0] = peraggstate->transValue;
295         fcinfo.argnull[0] = peraggstate->transValueIsNull;
296         fcinfo.arg[1] = newVal;
297         fcinfo.argnull[1] = isNull;
298
299         newVal = FunctionCallInvoke(&fcinfo);
300
301         /*
302          * If the transition function was uncooperative, it may have given us
303          * a pass-by-ref result that points at the scan tuple or the
304          * prior-cycle working memory.  Copy it into the active context if it
305          * doesn't look right.
306          */
307         if (!peraggstate->transtypeByVal && !fcinfo.isnull &&
308                 !MemoryContextContains(CurrentMemoryContext,
309                                                            DatumGetPointer(newVal)))
310                 newVal = datumCopy(newVal,
311                                                    peraggstate->transtypeByVal,
312                                                    peraggstate->transtypeLen);
313
314         peraggstate->transValue = newVal;
315         peraggstate->transValueIsNull = fcinfo.isnull;
316 }
317
318 /*
319  * Advance all the aggregates for one input tuple.  The input tuple
320  * has been stored in econtext->ecxt_scantuple, so that it is accessible
321  * to ExecEvalExpr.
322  *
323  * When called, CurrentMemoryContext should be the per-query context.
324  */
325 static void
326 advance_aggregates(AggState *aggstate, ExprContext *econtext)
327 {
328         MemoryContext oldContext;
329         int                     aggno;
330
331         /*
332          * Clear and select the current working context for evaluation
333          * of the input expressions and transition functions at this
334          * input tuple.
335          */
336         econtext->ecxt_per_tuple_memory = aggstate->agg_cxt[aggstate->which_cxt];
337         ResetExprContext(econtext);
338         oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
339
340         for (aggno = 0; aggno < aggstate->numaggs; aggno++)
341         {
342                 AggStatePerAgg peraggstate = &aggstate->peragg[aggno];
343                 Aggref     *aggref = peraggstate->aggref;
344                 Datum           newVal;
345                 bool            isNull;
346
347                 newVal = ExecEvalExpr(aggref->target, econtext, &isNull, NULL);
348
349                 if (aggref->aggdistinct)
350                 {
351                         /* in DISTINCT mode, we may ignore nulls */
352                         if (isNull)
353                                 continue;
354                         /* putdatum has to be called in per-query context */
355                         MemoryContextSwitchTo(oldContext);
356                         tuplesort_putdatum(peraggstate->sortstate, newVal, isNull);
357                         MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
358                 }
359                 else
360                 {
361                         advance_transition_function(peraggstate, newVal, isNull);
362                 }
363         }
364
365         /*
366          * Make the other context current so that these transition
367          * results are preserved.
368          */
369         aggstate->which_cxt = 1 - aggstate->which_cxt;
370
371         MemoryContextSwitchTo(oldContext);
372 }
373
374 /*
375  * Run the transition function for a DISTINCT aggregate.  This is called
376  * after we have completed entering all the input values into the sort
377  * object.      We complete the sort, read out the values in sorted order,
378  * and run the transition function on each non-duplicate value.
379  *
380  * When called, CurrentMemoryContext should be the per-query context.
381  */
382 static void
383 process_sorted_aggregate(AggState *aggstate,
384                                                  AggStatePerAgg peraggstate)
385 {
386         Datum           oldVal = (Datum) 0;
387         bool            haveOldVal = false;
388         MemoryContext oldContext;
389         Datum           newVal;
390         bool            isNull;
391
392         tuplesort_performsort(peraggstate->sortstate);
393
394         /*
395          * Note: if input type is pass-by-ref, the datums returned by the sort
396          * are freshly palloc'd in the per-query context, so we must be
397          * careful to pfree them when they are no longer needed.
398          */
399
400         while (tuplesort_getdatum(peraggstate->sortstate, true,
401                                                           &newVal, &isNull))
402         {
403                 /*
404                  * DISTINCT always suppresses nulls, per SQL spec, regardless of
405                  * the transition function's strictness.
406                  */
407                 if (isNull)
408                         continue;
409
410                 /*
411                  * Clear and select the current working context for evaluation of
412                  * the equality function and transition function.
413                  */
414                 MemoryContextReset(aggstate->agg_cxt[aggstate->which_cxt]);
415                 oldContext =
416                         MemoryContextSwitchTo(aggstate->agg_cxt[aggstate->which_cxt]);
417
418                 if (haveOldVal &&
419                         DatumGetBool(FunctionCall2(&peraggstate->equalfn,
420                                                                            oldVal, newVal)))
421                 {
422                         /* equal to prior, so forget this one */
423                         if (!peraggstate->inputtypeByVal)
424                                 pfree(DatumGetPointer(newVal));
425
426                         /*
427                          * note we do NOT flip contexts in this case, so no need to
428                          * copy prior transValue to other context.
429                          */
430                 }
431                 else
432                 {
433                         advance_transition_function(peraggstate, newVal, false);
434
435                         /*
436                          * Make the other context current so that this transition
437                          * result is preserved.
438                          */
439                         aggstate->which_cxt = 1 - aggstate->which_cxt;
440                         /* forget the old value, if any */
441                         if (haveOldVal && !peraggstate->inputtypeByVal)
442                                 pfree(DatumGetPointer(oldVal));
443                         oldVal = newVal;
444                         haveOldVal = true;
445                 }
446
447                 MemoryContextSwitchTo(oldContext);
448         }
449
450         if (haveOldVal && !peraggstate->inputtypeByVal)
451                 pfree(DatumGetPointer(oldVal));
452
453         tuplesort_end(peraggstate->sortstate);
454         peraggstate->sortstate = NULL;
455 }
456
457 /*
458  * Compute the final value of one aggregate.
459  *
460  * When called, CurrentMemoryContext should be the context where we want
461  * final values delivered (ie, the per-output-tuple expression context).
462  */
463 static void
464 finalize_aggregate(AggStatePerAgg peraggstate,
465                                    Datum *resultVal, bool *resultIsNull)
466 {
467         /*
468          * Apply the agg's finalfn if one is provided, else return transValue.
469          */
470         if (OidIsValid(peraggstate->finalfn_oid))
471         {
472                 FunctionCallInfoData fcinfo;
473
474                 MemSet(&fcinfo, 0, sizeof(fcinfo));
475                 fcinfo.flinfo = &peraggstate->finalfn;
476                 fcinfo.nargs = 1;
477                 fcinfo.arg[0] = peraggstate->transValue;
478                 fcinfo.argnull[0] = peraggstate->transValueIsNull;
479                 if (fcinfo.flinfo->fn_strict && peraggstate->transValueIsNull)
480                 {
481                         /* don't call a strict function with NULL inputs */
482                         *resultVal = (Datum) 0;
483                         *resultIsNull = true;
484                 }
485                 else
486                 {
487                         *resultVal = FunctionCallInvoke(&fcinfo);
488                         *resultIsNull = fcinfo.isnull;
489                 }
490         }
491         else
492         {
493                 *resultVal = peraggstate->transValue;
494                 *resultIsNull = peraggstate->transValueIsNull;
495         }
496
497         /*
498          * If result is pass-by-ref, make sure it is in the right context.
499          */
500         if (!peraggstate->resulttypeByVal && !*resultIsNull &&
501                 !MemoryContextContains(CurrentMemoryContext,
502                                                            DatumGetPointer(*resultVal)))
503                 *resultVal = datumCopy(*resultVal,
504                                                            peraggstate->resulttypeByVal,
505                                                            peraggstate->resulttypeLen);
506 }
507
508
509 /*
510  * ExecAgg -
511  *
512  *        ExecAgg receives tuples from its outer subplan and aggregates over
513  *        the appropriate attribute for each aggregate function use (Aggref
514  *        node) appearing in the targetlist or qual of the node.  The number
515  *        of tuples to aggregate over depends on whether grouped or plain
516  *        aggregation is selected.  In grouped aggregation, we produce a result
517  *        row for each group; in plain aggregation there's a single result row
518  *        for the whole query.  In either case, the value of each aggregate is
519  *        stored in the expression context to be used when ExecProject evaluates
520  *        the result tuple.
521  */
522 TupleTableSlot *
523 ExecAgg(Agg *node)
524 {
525         AggState   *aggstate;
526         EState     *estate;
527         Plan       *outerPlan;
528         ExprContext *econtext;
529         ProjectionInfo *projInfo;
530         Datum      *aggvalues;
531         bool       *aggnulls;
532         AggStatePerAgg peragg;
533         MemoryContext oldContext;
534         TupleTableSlot *outerslot;
535         TupleTableSlot *firstSlot;
536         TupleTableSlot *resultSlot;
537         int                     aggno;
538
539         /*
540          * get state info from node
541          */
542         aggstate = node->aggstate;
543         estate = node->plan.state;
544         outerPlan = outerPlan(node);
545         econtext = aggstate->csstate.cstate.cs_ExprContext;
546         aggvalues = econtext->ecxt_aggvalues;
547         aggnulls = econtext->ecxt_aggnulls;
548         projInfo = aggstate->csstate.cstate.cs_ProjInfo;
549         peragg = aggstate->peragg;
550         firstSlot = aggstate->csstate.css_ScanTupleSlot;
551
552         /*
553          * We loop retrieving groups until we find one matching
554          * node->plan.qual
555          */
556         do
557         {
558                 if (aggstate->agg_done)
559                         return NULL;
560
561                 /*
562                  * If we don't already have the first tuple of the new group,
563                  * fetch it from the outer plan.
564                  */
565                 if (aggstate->grp_firstTuple == NULL)
566                 {
567                         outerslot = ExecProcNode(outerPlan, (Plan *) node);
568                         if (!TupIsNull(outerslot))
569                         {
570                                 /*
571                                  * Make a copy of the first input tuple; we will use this
572                                  * for comparisons (in group mode) and for projection.
573                                  */
574                                 aggstate->grp_firstTuple = heap_copytuple(outerslot->val);
575                         }
576                         else
577                         {
578                                 /* outer plan produced no tuples at all */
579                                 aggstate->agg_done = true;
580                                 /* If we are grouping, we should produce no tuples too */
581                                 if (node->aggstrategy != AGG_PLAIN)
582                                         return NULL;
583                         }
584                 }
585
586                 /*
587                  * Clear the per-output-tuple context for each group
588                  */
589                 MemoryContextReset(aggstate->tup_cxt);
590
591                 /*
592                  * Initialize working state for a new input tuple group
593                  */
594                 for (aggno = 0; aggno < aggstate->numaggs; aggno++)
595                 {
596                         AggStatePerAgg peraggstate = &peragg[aggno];
597
598                         initialize_aggregate(peraggstate);
599                 }
600
601                 if (aggstate->grp_firstTuple != NULL)
602                 {
603                         /*
604                          * Store the copied first input tuple in the tuple table slot
605                          * reserved for it.  The tuple will be deleted when it is
606                          * cleared from the slot.
607                          */
608                         ExecStoreTuple(aggstate->grp_firstTuple,
609                                                    firstSlot,
610                                                    InvalidBuffer,
611                                                    true);
612                         aggstate->grp_firstTuple = NULL; /* don't keep two pointers */
613
614                         /* set up for first advance_aggregates call */
615                         econtext->ecxt_scantuple = firstSlot;
616
617                         /*
618                          * Process each outer-plan tuple, and then fetch the next one,
619                          * until we exhaust the outer plan or cross a group boundary.
620                          */
621                         for (;;)
622                         {
623                                 advance_aggregates(aggstate, econtext);
624
625                                 outerslot = ExecProcNode(outerPlan, (Plan *) node);
626                                 if (TupIsNull(outerslot))
627                                 {
628                                         /* no more outer-plan tuples available */
629                                         aggstate->agg_done = true;
630                                         break;
631                                 }
632                                 /* set up for next advance_aggregates call */
633                                 econtext->ecxt_scantuple = outerslot;
634
635                                 /*
636                                  * If we are grouping, check whether we've crossed a group
637                                  * boundary.
638                                  */
639                                 if (node->aggstrategy == AGG_SORTED)
640                                 {
641                                         if (!execTuplesMatch(firstSlot->val,
642                                                                                  outerslot->val,
643                                                                                  firstSlot->ttc_tupleDescriptor,
644                                                                                  node->numCols, node->grpColIdx,
645                                                                                  aggstate->eqfunctions,
646                                                                                  aggstate->agg_cxt[aggstate->which_cxt]))
647                                         {
648                                                 /*
649                                                  * Save the first input tuple of the next group.
650                                                  */
651                                                 aggstate->grp_firstTuple = heap_copytuple(outerslot->val);
652                                                 break;
653                                         }
654                                 }
655                         }
656                 }
657
658                 /*
659                  * Done scanning input tuple group. Finalize each aggregate
660                  * calculation, and stash results in the per-output-tuple context.
661                  *
662                  * This is a bit tricky when there are both DISTINCT and plain
663                  * aggregates: we must first finalize all the plain aggs and then
664                  * all the DISTINCT ones.  This is needed because the last
665                  * transition values for the plain aggs are stored in the
666                  * not-current working context, and we have to evaluate those aggs
667                  * (and stash the results in the output tup_cxt!) before we start
668                  * flipping contexts again in process_sorted_aggregate.
669                  */
670                 oldContext = MemoryContextSwitchTo(aggstate->tup_cxt);
671                 for (aggno = 0; aggno < aggstate->numaggs; aggno++)
672                 {
673                         AggStatePerAgg peraggstate = &peragg[aggno];
674
675                         if (!peraggstate->aggref->aggdistinct)
676                                 finalize_aggregate(peraggstate,
677                                                                    &aggvalues[aggno], &aggnulls[aggno]);
678                 }
679                 MemoryContextSwitchTo(oldContext);
680                 for (aggno = 0; aggno < aggstate->numaggs; aggno++)
681                 {
682                         AggStatePerAgg peraggstate = &peragg[aggno];
683
684                         if (peraggstate->aggref->aggdistinct)
685                         {
686                                 process_sorted_aggregate(aggstate, peraggstate);
687                                 oldContext = MemoryContextSwitchTo(aggstate->tup_cxt);
688                                 finalize_aggregate(peraggstate,
689                                                                    &aggvalues[aggno], &aggnulls[aggno]);
690                                 MemoryContextSwitchTo(oldContext);
691                         }
692                 }
693
694                 /*
695                  * If we have no first tuple (ie, the outerPlan didn't return
696                  * anything), create a dummy all-nulls input tuple for use by
697                  * ExecProject. 99.44% of the time this is a waste of cycles,
698                  * because ordinarily the projected output tuple's targetlist
699                  * cannot contain any direct (non-aggregated) references to
700                  * input columns, so the dummy tuple will not be referenced.
701                  * However there are special cases where this isn't so --- in
702                  * particular an UPDATE involving an aggregate will have a
703                  * targetlist reference to ctid.  We need to return a null for
704                  * ctid in that situation, not coredump.
705                  *
706                  * The values returned for the aggregates will be the initial
707                  * values of the transition functions.
708                  */
709                 if (TupIsNull(firstSlot))
710                 {
711                         TupleDesc       tupType;
712
713                         /* Should only happen in non-grouped mode */
714                         Assert(node->aggstrategy == AGG_PLAIN);
715                         Assert(aggstate->agg_done);
716
717                         tupType = firstSlot->ttc_tupleDescriptor;
718                         /* watch out for zero-column input tuples, though... */
719                         if (tupType && tupType->natts > 0)
720                         {
721                                 HeapTuple       nullsTuple;
722                                 Datum      *dvalues;
723                                 char       *dnulls;
724
725                                 dvalues = (Datum *) palloc(sizeof(Datum) * tupType->natts);
726                                 dnulls = (char *) palloc(sizeof(char) * tupType->natts);
727                                 MemSet(dvalues, 0, sizeof(Datum) * tupType->natts);
728                                 MemSet(dnulls, 'n', sizeof(char) * tupType->natts);
729                                 nullsTuple = heap_formtuple(tupType, dvalues, dnulls);
730                                 ExecStoreTuple(nullsTuple,
731                                                            firstSlot,
732                                                            InvalidBuffer,
733                                                            true);
734                                 pfree(dvalues);
735                                 pfree(dnulls);
736                         }
737                 }
738
739                 /*
740                  * Do projection and qual check in the per-output-tuple context.
741                  */
742                 econtext->ecxt_per_tuple_memory = aggstate->tup_cxt;
743
744                 /*
745                  * Form a projection tuple using the aggregate results and the
746                  * representative input tuple.  Store it in the result tuple slot.
747                  * Note we do not support aggregates returning sets ...
748                  */
749                 econtext->ecxt_scantuple = firstSlot;
750                 resultSlot = ExecProject(projInfo, NULL);
751
752                 /*
753                  * If the completed tuple does not match the qualifications, it is
754                  * ignored and we loop back to try to process another group.
755                  * Otherwise, return the tuple.
756                  */
757         }
758         while (!ExecQual(node->plan.qual, econtext, false));
759
760         return resultSlot;
761 }
762
763 /* -----------------
764  * ExecInitAgg
765  *
766  *      Creates the run-time information for the agg node produced by the
767  *      planner and initializes its outer subtree
768  * -----------------
769  */
770 bool
771 ExecInitAgg(Agg *node, EState *estate, Plan *parent)
772 {
773         AggState   *aggstate;
774         AggStatePerAgg peragg;
775         Plan       *outerPlan;
776         ExprContext *econtext;
777         int                     numaggs,
778                                 aggno;
779         List       *alist;
780
781         /*
782          * assign the node's execution state
783          */
784         node->plan.state = estate;
785
786         /*
787          * create state structure
788          */
789         aggstate = makeNode(AggState);
790         node->aggstate = aggstate;
791         aggstate->eqfunctions = NULL;
792         aggstate->grp_firstTuple = NULL;
793         aggstate->agg_done = false;
794
795         /*
796          * find aggregates in targetlist and quals
797          *
798          * Note: pull_agg_clauses also checks that no aggs contain other agg
799          * calls in their arguments.  This would make no sense under SQL
800          * semantics anyway (and it's forbidden by the spec).  Because that is
801          * true, we don't need to worry about evaluating the aggs in any
802          * particular order.
803          */
804         aggstate->aggs = nconc(pull_agg_clause((Node *) node->plan.targetlist),
805                                                    pull_agg_clause((Node *) node->plan.qual));
806         aggstate->numaggs = numaggs = length(aggstate->aggs);
807         if (numaggs <= 0)
808         {
809                 /*
810                  * This is not an error condition: we might be using the Agg node just
811                  * to do hash-based grouping.  Even in the regular case,
812                  * constant-expression simplification could optimize away all of the
813                  * Aggrefs in the targetlist and qual.  So keep going, but force local
814                  * copy of numaggs positive so that palloc()s below don't choke.
815                  */
816                 numaggs = 1;
817         }
818
819         /*
820          * Create expression context
821          */
822         ExecAssignExprContext(estate, &aggstate->csstate.cstate);
823
824         /*
825          * We actually need three separate expression memory contexts: one for
826          * calculating per-output-tuple values (ie, the finished aggregate
827          * results), and two that we ping-pong between for per-input-tuple
828          * evaluation of input expressions and transition functions.  The
829          * context made by ExecAssignExprContext() is used as the output
830          * context.
831          */
832         aggstate->tup_cxt =
833                 aggstate->csstate.cstate.cs_ExprContext->ecxt_per_tuple_memory;
834         aggstate->agg_cxt[0] =
835                 AllocSetContextCreate(CurrentMemoryContext,
836                                                           "AggExprContext1",
837                                                           ALLOCSET_DEFAULT_MINSIZE,
838                                                           ALLOCSET_DEFAULT_INITSIZE,
839                                                           ALLOCSET_DEFAULT_MAXSIZE);
840         aggstate->agg_cxt[1] =
841                 AllocSetContextCreate(CurrentMemoryContext,
842                                                           "AggExprContext2",
843                                                           ALLOCSET_DEFAULT_MINSIZE,
844                                                           ALLOCSET_DEFAULT_INITSIZE,
845                                                           ALLOCSET_DEFAULT_MAXSIZE);
846         aggstate->which_cxt = 0;
847
848 #define AGG_NSLOTS 2
849
850         /*
851          * tuple table initialization
852          */
853         ExecInitScanTupleSlot(estate, &aggstate->csstate);
854         ExecInitResultTupleSlot(estate, &aggstate->csstate.cstate);
855
856         /*
857          * Set up aggregate-result storage in the expr context, and also
858          * allocate my private per-agg working storage
859          */
860         econtext = aggstate->csstate.cstate.cs_ExprContext;
861         econtext->ecxt_aggvalues = (Datum *) palloc(sizeof(Datum) * numaggs);
862         MemSet(econtext->ecxt_aggvalues, 0, sizeof(Datum) * numaggs);
863         econtext->ecxt_aggnulls = (bool *) palloc(sizeof(bool) * numaggs);
864         MemSet(econtext->ecxt_aggnulls, 0, sizeof(bool) * numaggs);
865
866         peragg = (AggStatePerAgg) palloc(sizeof(AggStatePerAggData) * numaggs);
867         MemSet(peragg, 0, sizeof(AggStatePerAggData) * numaggs);
868         aggstate->peragg = peragg;
869
870         /*
871          * initialize child nodes
872          */
873         outerPlan = outerPlan(node);
874         ExecInitNode(outerPlan, estate, (Plan *) node);
875
876         /*
877          * initialize source tuple type.
878          */
879         ExecAssignScanTypeFromOuterPlan((Plan *) node, &aggstate->csstate);
880
881         /*
882          * Initialize result tuple type and projection info.
883          */
884         ExecAssignResultTypeFromTL((Plan *) node, &aggstate->csstate.cstate);
885         ExecAssignProjectionInfo((Plan *) node, &aggstate->csstate.cstate);
886
887         /*
888          * If we are grouping, precompute fmgr lookup data for inner loop
889          */
890         if (node->numCols > 0)
891         {
892                 aggstate->eqfunctions =
893                         execTuplesMatchPrepare(ExecGetScanType(&aggstate->csstate),
894                                                                    node->numCols,
895                                                                    node->grpColIdx);
896         }
897
898         /*
899          * Perform lookups of aggregate function info, and initialize the
900          * unchanging fields of the per-agg data
901          */
902         aggno = -1;
903         foreach(alist, aggstate->aggs)
904         {
905                 Aggref     *aggref = (Aggref *) lfirst(alist);
906                 AggStatePerAgg peraggstate = &peragg[++aggno];
907                 HeapTuple       aggTuple;
908                 Form_pg_aggregate aggform;
909                 AclResult       aclresult;
910                 Oid                     transfn_oid,
911                                         finalfn_oid;
912                 Datum           textInitVal;
913
914                 /* Mark Aggref node with its associated index in the result array */
915                 aggref->aggno = aggno;
916
917                 /* Fill in the peraggstate data */
918                 peraggstate->aggref = aggref;
919
920                 aggTuple = SearchSysCache(AGGFNOID,
921                                                                   ObjectIdGetDatum(aggref->aggfnoid),
922                                                                   0, 0, 0);
923                 if (!HeapTupleIsValid(aggTuple))
924                         elog(ERROR, "ExecAgg: cache lookup failed for aggregate %u",
925                                  aggref->aggfnoid);
926                 aggform = (Form_pg_aggregate) GETSTRUCT(aggTuple);
927
928                 /* Check permission to call aggregate function */
929                 aclresult = pg_proc_aclcheck(aggref->aggfnoid, GetUserId(),
930                                                                          ACL_EXECUTE);
931                 if (aclresult != ACLCHECK_OK)
932                         aclcheck_error(aclresult, get_func_name(aggref->aggfnoid));
933
934                 get_typlenbyval(aggref->aggtype,
935                                                 &peraggstate->resulttypeLen,
936                                                 &peraggstate->resulttypeByVal);
937                 get_typlenbyval(aggform->aggtranstype,
938                                                 &peraggstate->transtypeLen,
939                                                 &peraggstate->transtypeByVal);
940
941                 /*
942                  * initval is potentially null, so don't try to access it as a
943                  * struct field. Must do it the hard way with SysCacheGetAttr.
944                  */
945                 textInitVal = SysCacheGetAttr(AGGFNOID, aggTuple,
946                                                                           Anum_pg_aggregate_agginitval,
947                                                                           &peraggstate->initValueIsNull);
948
949                 if (peraggstate->initValueIsNull)
950                         peraggstate->initValue = (Datum) 0;
951                 else
952                         peraggstate->initValue = GetAggInitVal(textInitVal,
953                                                                                                    aggform->aggtranstype);
954
955                 peraggstate->transfn_oid = transfn_oid = aggform->aggtransfn;
956                 peraggstate->finalfn_oid = finalfn_oid = aggform->aggfinalfn;
957
958                 fmgr_info(transfn_oid, &peraggstate->transfn);
959                 if (OidIsValid(finalfn_oid))
960                         fmgr_info(finalfn_oid, &peraggstate->finalfn);
961
962                 /*
963                  * If the transfn is strict and the initval is NULL, make sure
964                  * input type and transtype are the same (or at least binary-
965                  * compatible), so that it's OK to use the first input value as
966                  * the initial transValue.      This should have been checked at agg
967                  * definition time, but just in case...
968                  */
969                 if (peraggstate->transfn.fn_strict && peraggstate->initValueIsNull)
970                 {
971                         /*
972                          * Note: use the type from the input expression here, not from
973                          * pg_proc.proargtypes, because the latter might be 0.
974                          * (Consider COUNT(*).)
975                          */
976                         Oid                     inputType = exprType(aggref->target);
977
978                         if (!IsBinaryCoercible(inputType, aggform->aggtranstype))
979                                 elog(ERROR, "Aggregate %u needs to have compatible input type and transition type",
980                                          aggref->aggfnoid);
981                 }
982
983                 if (aggref->aggdistinct)
984                 {
985                         /*
986                          * Note: use the type from the input expression here, not from
987                          * pg_proc.proargtypes, because the latter might be 0.
988                          * (Consider COUNT(*).)
989                          */
990                         Oid                     inputType = exprType(aggref->target);
991                         Oid                     eq_function;
992
993                         peraggstate->inputType = inputType;
994                         get_typlenbyval(inputType,
995                                                         &peraggstate->inputtypeLen,
996                                                         &peraggstate->inputtypeByVal);
997
998                         eq_function = compatible_oper_funcid(makeList1(makeString("=")),
999                                                                                                  inputType, inputType,
1000                                                                                                  true);
1001                         if (!OidIsValid(eq_function))
1002                                 elog(ERROR, "Unable to identify an equality operator for type %s",
1003                                          format_type_be(inputType));
1004                         fmgr_info(eq_function, &(peraggstate->equalfn));
1005                         peraggstate->sortOperator = any_ordering_op(inputType);
1006                         peraggstate->sortstate = NULL;
1007                 }
1008
1009                 ReleaseSysCache(aggTuple);
1010         }
1011
1012         return TRUE;
1013 }
1014
1015 static Datum
1016 GetAggInitVal(Datum textInitVal, Oid transtype)
1017 {
1018         char       *strInitVal;
1019         HeapTuple       tup;
1020         Oid                     typinput,
1021                                 typelem;
1022         Datum           initVal;
1023
1024         strInitVal = DatumGetCString(DirectFunctionCall1(textout, textInitVal));
1025
1026         tup = SearchSysCache(TYPEOID,
1027                                                  ObjectIdGetDatum(transtype),
1028                                                  0, 0, 0);
1029         if (!HeapTupleIsValid(tup))
1030                 elog(ERROR, "GetAggInitVal: cache lookup failed on aggregate transition function return type %u", transtype);
1031
1032         typinput = ((Form_pg_type) GETSTRUCT(tup))->typinput;
1033         typelem = ((Form_pg_type) GETSTRUCT(tup))->typelem;
1034         ReleaseSysCache(tup);
1035
1036         initVal = OidFunctionCall3(typinput,
1037                                                            CStringGetDatum(strInitVal),
1038                                                            ObjectIdGetDatum(typelem),
1039                                                            Int32GetDatum(-1));
1040
1041         pfree(strInitVal);
1042         return initVal;
1043 }
1044
1045 int
1046 ExecCountSlotsAgg(Agg *node)
1047 {
1048         return ExecCountSlotsNode(outerPlan(node)) +
1049                 ExecCountSlotsNode(innerPlan(node)) +
1050                 AGG_NSLOTS;
1051 }
1052
1053 void
1054 ExecEndAgg(Agg *node)
1055 {
1056         AggState   *aggstate = node->aggstate;
1057         Plan       *outerPlan;
1058
1059         ExecFreeProjectionInfo(&aggstate->csstate.cstate);
1060
1061         /*
1062          * Make sure ExecFreeExprContext() frees the right expr context...
1063          */
1064         aggstate->csstate.cstate.cs_ExprContext->ecxt_per_tuple_memory =
1065                 aggstate->tup_cxt;
1066         ExecFreeExprContext(&aggstate->csstate.cstate);
1067
1068         /*
1069          * ... and I free the others.
1070          */
1071         MemoryContextDelete(aggstate->agg_cxt[0]);
1072         MemoryContextDelete(aggstate->agg_cxt[1]);
1073
1074         outerPlan = outerPlan(node);
1075         ExecEndNode(outerPlan, (Plan *) node);
1076
1077         /* clean up tuple table */
1078         ExecClearTuple(aggstate->csstate.css_ScanTupleSlot);
1079         if (aggstate->grp_firstTuple != NULL)
1080         {
1081                 heap_freetuple(aggstate->grp_firstTuple);
1082                 aggstate->grp_firstTuple = NULL;
1083         }
1084 }
1085
1086 void
1087 ExecReScanAgg(Agg *node, ExprContext *exprCtxt, Plan *parent)
1088 {
1089         AggState   *aggstate = node->aggstate;
1090         ExprContext *econtext = aggstate->csstate.cstate.cs_ExprContext;
1091
1092         aggstate->agg_done = false;
1093         if (aggstate->grp_firstTuple != NULL)
1094         {
1095                 heap_freetuple(aggstate->grp_firstTuple);
1096                 aggstate->grp_firstTuple = NULL;
1097         }
1098         MemSet(econtext->ecxt_aggvalues, 0, sizeof(Datum) * aggstate->numaggs);
1099         MemSet(econtext->ecxt_aggnulls, 0, sizeof(bool) * aggstate->numaggs);
1100
1101         /*
1102          * if chgParam of subnode is not null then plan will be re-scanned by
1103          * first ExecProcNode.
1104          */
1105         if (((Plan *) node)->lefttree->chgParam == NULL)
1106                 ExecReScan(((Plan *) node)->lefttree, exprCtxt, (Plan *) node);
1107 }
1108
1109 /*
1110  * aggregate_dummy - dummy execution routine for aggregate functions
1111  *
1112  * This function is listed as the implementation (prosrc field) of pg_proc
1113  * entries for aggregate functions.  Its only purpose is to throw an error
1114  * if someone mistakenly executes such a function in the normal way.
1115  *
1116  * Perhaps someday we could assign real meaning to the prosrc field of
1117  * an aggregate?
1118  */
1119 Datum
1120 aggregate_dummy(PG_FUNCTION_ARGS)
1121 {
1122         elog(ERROR, "Aggregate function %u called as normal function",
1123                  fcinfo->flinfo->fn_oid);
1124         return (Datum) 0;                       /* keep compiler quiet */
1125 }