1 /*-------------------------------------------------------------------------
4 * Routines to handle aggregate nodes.
6 * ExecAgg evaluates each aggregate in the following steps:
8 * transvalue = initcond
9 * foreach input_tuple do
10 * transvalue = transfunc(transvalue, input_value(s))
11 * result = finalfunc(transvalue, direct_argument(s))
13 * If a finalfunc is not supplied then the result is just the ending
14 * value of transvalue.
16 * If a normal aggregate call specifies DISTINCT or ORDER BY, we sort the
17 * input tuples and eliminate duplicates (if required) before performing
18 * the above-depicted process. (However, we don't do that for ordered-set
19 * aggregates; their "ORDER BY" inputs are ordinary aggregate arguments
20 * so far as this module is concerned.)
22 * If transfunc is marked "strict" in pg_proc and initcond is NULL,
23 * then the first non-NULL input_value is assigned directly to transvalue,
24 * and transfunc isn't applied until the second non-NULL input_value.
25 * The agg's first input type and transtype must be the same in this case!
27 * If transfunc is marked "strict" then NULL input_values are skipped,
28 * keeping the previous transvalue. If transfunc is not strict then it
29 * is called for every input tuple and must deal with NULL initcond
30 * or NULL input_values for itself.
32 * If finalfunc is marked "strict" then it is not called when the
33 * ending transvalue is NULL, instead a NULL result is created
34 * automatically (this is just the usual handling of strict functions,
35 * of course). A non-strict finalfunc can make its own choice of
36 * what to return for a NULL ending transvalue.
38 * Ordered-set aggregates are treated specially in one other way: we
39 * evaluate any "direct" arguments and pass them to the finalfunc along
40 * with the transition value.
42 * A finalfunc can have additional arguments beyond the transvalue and
43 * any "direct" arguments, corresponding to the input arguments of the
44 * aggregate. These are always just passed as NULL. Such arguments may be
45 * needed to allow resolution of a polymorphic aggregate's result type.
47 * We compute aggregate input expressions and run the transition functions
48 * in a temporary econtext (aggstate->tmpcontext). This is reset at
49 * least once per input tuple, so when the transvalue datatype is
50 * pass-by-reference, we have to be careful to copy it into a longer-lived
51 * memory context, and free the prior value to avoid memory leakage.
52 * We store transvalues in the memory context aggstate->aggcontext,
53 * which is also used for the hashtable structures in AGG_HASHED mode.
54 * The node's regular econtext (aggstate->ss.ps.ps_ExprContext)
55 * is used to run finalize functions and compute the output tuple;
56 * this context can be reset once per output tuple.
58 * The executor's AggState node is passed as the fmgr "context" value in
59 * all transfunc and finalfunc calls. It is not recommended that the
60 * transition functions look at the AggState node directly, but they can
61 * use AggCheckCallContext() to verify that they are being called by
62 * nodeAgg.c (and not as ordinary SQL functions). The main reason a
63 * transition function might want to know this is so that it can avoid
64 * palloc'ing a fixed-size pass-by-ref transition value on every call:
65 * it can instead just scribble on and return its left input. Ordinarily
66 * it is completely forbidden for functions to modify pass-by-ref inputs,
67 * but in the aggregate case we know the left input is either the initial
68 * transition value or a previous function result, and in either case its
69 * value need not be preserved. See int8inc() for an example. Notice that
70 * advance_transition_function() is coded to avoid a data copy step when
71 * the previous transition value pointer is returned. Also, some
72 * transition functions want to store working state in addition to the
73 * nominal transition value; they can use the memory context returned by
74 * AggCheckCallContext() to do that.
76 * Note: AggCheckCallContext() is available as of PostgreSQL 9.0. The
77 * AggState is available as context in earlier releases (back to 8.1),
78 * but direct examination of the node is needed to use it before 9.0.
80 * As of 9.4, aggregate transition functions can also use AggGetAggref()
81 * to get hold of the Aggref expression node for their aggregate call.
82 * This is mainly intended for ordered-set aggregates, which are not
83 * supported as window functions. (A regular aggregate function would
84 * need some fallback logic to use this, since there's no Aggref node
85 * for a window function.)
88 * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
89 * Portions Copyright (c) 1994, Regents of the University of California
92 * src/backend/executor/nodeAgg.c
94 *-------------------------------------------------------------------------
99 #include "access/htup_details.h"
100 #include "catalog/objectaccess.h"
101 #include "catalog/pg_aggregate.h"
102 #include "catalog/pg_proc.h"
103 #include "executor/executor.h"
104 #include "executor/nodeAgg.h"
105 #include "miscadmin.h"
106 #include "nodes/nodeFuncs.h"
107 #include "optimizer/clauses.h"
108 #include "optimizer/tlist.h"
109 #include "parser/parse_agg.h"
110 #include "parser/parse_coerce.h"
111 #include "utils/acl.h"
112 #include "utils/builtins.h"
113 #include "utils/lsyscache.h"
114 #include "utils/memutils.h"
115 #include "utils/syscache.h"
116 #include "utils/tuplesort.h"
117 #include "utils/datum.h"
121 * AggStatePerAggData - per-aggregate working state for the Agg scan
123 typedef struct AggStatePerAggData
126 * These values are set up during ExecInitAgg() and do not change
130 /* Links to Aggref expr and state nodes this working state is for */
131 AggrefExprState *aggrefstate;
135 * Nominal number of arguments for aggregate function. For plain aggs,
136 * this excludes any ORDER BY expressions. For ordered-set aggs, this
137 * counts both the direct and aggregated (ORDER BY) arguments.
142 * Number of aggregated input columns. This includes ORDER BY expressions
143 * in both the plain-agg and ordered-set cases. Ordered-set direct args
144 * are not counted, though.
149 * Number of aggregated input columns to pass to the transfn. This
150 * includes the ORDER BY columns for ordered-set aggs, but not for plain
151 * aggs. (This doesn't count the transition state value!)
156 * Number of arguments to pass to the finalfn. This is always at least 1
157 * (the transition state value) plus any ordered-set direct args. If the
158 * finalfn wants extra args then we pass nulls corresponding to the
159 * aggregated input columns.
163 /* Oids of transfer functions */
165 Oid finalfn_oid; /* may be InvalidOid */
168 * fmgr lookup data for transfer functions --- only valid when
169 * corresponding oid is not InvalidOid. Note in particular that fn_strict
170 * flags are kept here.
175 /* Input collation derived for aggregate */
178 /* number of sorting columns */
181 /* number of sorting columns to consider in DISTINCT comparisons */
182 /* (this is either zero or the same as numSortCols) */
185 /* deconstructed sorting information (arrays of length numSortCols) */
186 AttrNumber *sortColIdx;
189 bool *sortNullsFirst;
192 * fmgr lookup data for input columns' equality operators --- only
193 * set/used when aggregate has DISTINCT flag. Note that these are in
194 * order of sort column index, not parameter index.
196 FmgrInfo *equalfns; /* array of length numDistinctCols */
199 * initial value from pg_aggregate entry
202 bool initValueIsNull;
205 * We need the len and byval info for the agg's input, result, and
206 * transition data types in order to know how to copy/delete values.
208 * Note that the info for the input type is used only when handling
209 * DISTINCT aggs with just one argument, so there is only one input type.
219 * Stuff for evaluation of inputs. We used to just use ExecEvalExpr, but
220 * with the addition of ORDER BY we now need at least a slot for passing
221 * data to the sort object, which requires a tupledesc, so we might as
222 * well go whole hog and use ExecProject too.
224 TupleDesc evaldesc; /* descriptor of input tuples */
225 ProjectionInfo *evalproj; /* projection machinery */
228 * Slots for holding the evaluated input arguments. These are set up
229 * during ExecInitAgg() and then used for each input row.
231 TupleTableSlot *evalslot; /* current input tuple */
232 TupleTableSlot *uniqslot; /* used for multi-column DISTINCT */
235 * These values are working state that is initialized at the start of an
236 * input tuple group and updated for each input tuple.
238 * For a simple (non DISTINCT/ORDER BY) aggregate, we just feed the input
239 * values straight to the transition function. If it's DISTINCT or
240 * requires ORDER BY, we pass the input values into a Tuplesort object;
241 * then at completion of the input tuple group, we scan the sorted values,
242 * eliminate duplicates if needed, and run the transition function on the
246 Tuplesortstate *sortstate; /* sort object, if DISTINCT or ORDER BY */
249 * This field is a pre-initialized FunctionCallInfo struct used for
250 * calling this aggregate's transfn. We save a few cycles per row by not
251 * re-initializing the unchanging fields; which isn't much, but it seems
252 * worth the extra space consumption.
254 FunctionCallInfoData transfn_fcinfo;
255 } AggStatePerAggData;
258 * AggStatePerGroupData - per-aggregate-per-group working state
260 * These values are working state that is initialized at the start of
261 * an input tuple group and updated for each input tuple.
263 * In AGG_PLAIN and AGG_SORTED modes, we have a single array of these
264 * structs (pointed to by aggstate->pergroup); we re-use the array for
265 * each input group, if it's AGG_SORTED mode. In AGG_HASHED mode, the
266 * hash table contains an array of these structs for each tuple group.
268 * Logically, the sortstate field belongs in this struct, but we do not
269 * keep it here for space reasons: we don't support DISTINCT aggregates
270 * in AGG_HASHED mode, so there's no reason to use up a pointer field
271 * in every entry of the hashtable.
273 typedef struct AggStatePerGroupData
275 Datum transValue; /* current transition value */
276 bool transValueIsNull;
278 bool noTransValue; /* true if transValue not set yet */
281 * Note: noTransValue initially has the same value as transValueIsNull,
282 * and if true both are cleared to false at the same time. They are not
283 * the same though: if transfn later returns a NULL, we want to keep that
284 * NULL and not auto-replace it with a later input value. Only the first
285 * non-NULL input will be auto-substituted.
287 } AggStatePerGroupData;
290 * To implement hashed aggregation, we need a hashtable that stores a
291 * representative tuple and an array of AggStatePerGroup structs for each
292 * distinct set of GROUP BY column values. We compute the hash key from
293 * the GROUP BY columns.
295 typedef struct AggHashEntryData *AggHashEntry;
297 typedef struct AggHashEntryData
299 TupleHashEntryData shared; /* common header for hash table entries */
300 /* per-aggregate transition status array - must be last! */
301 AggStatePerGroupData pergroup[1]; /* VARIABLE LENGTH ARRAY */
302 } AggHashEntryData; /* VARIABLE LENGTH STRUCT */
305 static void initialize_aggregates(AggState *aggstate,
306 AggStatePerAgg peragg,
307 AggStatePerGroup pergroup);
308 static void advance_transition_function(AggState *aggstate,
309 AggStatePerAgg peraggstate,
310 AggStatePerGroup pergroupstate);
311 static void advance_aggregates(AggState *aggstate, AggStatePerGroup pergroup);
312 static void process_ordered_aggregate_single(AggState *aggstate,
313 AggStatePerAgg peraggstate,
314 AggStatePerGroup pergroupstate);
315 static void process_ordered_aggregate_multi(AggState *aggstate,
316 AggStatePerAgg peraggstate,
317 AggStatePerGroup pergroupstate);
318 static void finalize_aggregate(AggState *aggstate,
319 AggStatePerAgg peraggstate,
320 AggStatePerGroup pergroupstate,
321 Datum *resultVal, bool *resultIsNull);
322 static Bitmapset *find_unaggregated_cols(AggState *aggstate);
323 static bool find_unaggregated_cols_walker(Node *node, Bitmapset **colnos);
324 static void build_hash_table(AggState *aggstate);
325 static AggHashEntry lookup_hash_entry(AggState *aggstate,
326 TupleTableSlot *inputslot);
327 static TupleTableSlot *agg_retrieve_direct(AggState *aggstate);
328 static void agg_fill_hash_table(AggState *aggstate);
329 static TupleTableSlot *agg_retrieve_hash_table(AggState *aggstate);
330 static Datum GetAggInitVal(Datum textInitVal, Oid transtype);
334 * Initialize all aggregates for a new group of input values.
336 * When called, CurrentMemoryContext should be the per-query context.
339 initialize_aggregates(AggState *aggstate,
340 AggStatePerAgg peragg,
341 AggStatePerGroup pergroup)
345 for (aggno = 0; aggno < aggstate->numaggs; aggno++)
347 AggStatePerAgg peraggstate = &peragg[aggno];
348 AggStatePerGroup pergroupstate = &pergroup[aggno];
351 * Start a fresh sort operation for each DISTINCT/ORDER BY aggregate.
353 if (peraggstate->numSortCols > 0)
356 * In case of rescan, maybe there could be an uncompleted sort
357 * operation? Clean it up if so.
359 if (peraggstate->sortstate)
360 tuplesort_end(peraggstate->sortstate);
363 * We use a plain Datum sorter when there's a single input column;
364 * otherwise sort the full tuple. (See comments for
365 * process_ordered_aggregate_single.)
367 peraggstate->sortstate =
368 (peraggstate->numInputs == 1) ?
369 tuplesort_begin_datum(peraggstate->evaldesc->attrs[0]->atttypid,
370 peraggstate->sortOperators[0],
371 peraggstate->sortCollations[0],
372 peraggstate->sortNullsFirst[0],
374 tuplesort_begin_heap(peraggstate->evaldesc,
375 peraggstate->numSortCols,
376 peraggstate->sortColIdx,
377 peraggstate->sortOperators,
378 peraggstate->sortCollations,
379 peraggstate->sortNullsFirst,
384 * (Re)set transValue to the initial value.
386 * Note that when the initial value is pass-by-ref, we must copy it
387 * (into the aggcontext) since we will pfree the transValue later.
389 if (peraggstate->initValueIsNull)
390 pergroupstate->transValue = peraggstate->initValue;
393 MemoryContext oldContext;
395 oldContext = MemoryContextSwitchTo(aggstate->aggcontext);
396 pergroupstate->transValue = datumCopy(peraggstate->initValue,
397 peraggstate->transtypeByVal,
398 peraggstate->transtypeLen);
399 MemoryContextSwitchTo(oldContext);
401 pergroupstate->transValueIsNull = peraggstate->initValueIsNull;
404 * If the initial value for the transition state doesn't exist in the
405 * pg_aggregate table then we will let the first non-NULL value
406 * returned from the outer procNode become the initial value. (This is
407 * useful for aggregates like max() and min().) The noTransValue flag
408 * signals that we still need to do this.
410 pergroupstate->noTransValue = peraggstate->initValueIsNull;
415 * Given new input value(s), advance the transition function of an aggregate.
417 * The new values (and null flags) have been preloaded into argument positions
418 * 1 and up in peraggstate->transfn_fcinfo, so that we needn't copy them again
419 * to pass to the transition function. We also expect that the static fields
420 * of the fcinfo are already initialized; that was done by ExecInitAgg().
422 * It doesn't matter which memory context this is called in.
425 advance_transition_function(AggState *aggstate,
426 AggStatePerAgg peraggstate,
427 AggStatePerGroup pergroupstate)
429 FunctionCallInfo fcinfo = &peraggstate->transfn_fcinfo;
430 MemoryContext oldContext;
433 if (peraggstate->transfn.fn_strict)
436 * For a strict transfn, nothing happens when there's a NULL input; we
437 * just keep the prior transValue.
439 int numTransInputs = peraggstate->numTransInputs;
442 for (i = 1; i <= numTransInputs; i++)
444 if (fcinfo->argnull[i])
447 if (pergroupstate->noTransValue)
450 * transValue has not been initialized. This is the first non-NULL
451 * input value. We use it as the initial value for transValue. (We
452 * already checked that the agg's input type is binary-compatible
453 * with its transtype, so straight copy here is OK.)
455 * We must copy the datum into aggcontext if it is pass-by-ref. We
456 * do not need to pfree the old transValue, since it's NULL.
458 oldContext = MemoryContextSwitchTo(aggstate->aggcontext);
459 pergroupstate->transValue = datumCopy(fcinfo->arg[1],
460 peraggstate->transtypeByVal,
461 peraggstate->transtypeLen);
462 pergroupstate->transValueIsNull = false;
463 pergroupstate->noTransValue = false;
464 MemoryContextSwitchTo(oldContext);
467 if (pergroupstate->transValueIsNull)
470 * Don't call a strict function with NULL inputs. Note it is
471 * possible to get here despite the above tests, if the transfn is
472 * strict *and* returned a NULL on a prior cycle. If that happens
473 * we will propagate the NULL all the way to the end.
479 /* We run the transition functions in per-input-tuple memory context */
480 oldContext = MemoryContextSwitchTo(aggstate->tmpcontext->ecxt_per_tuple_memory);
482 /* set up aggstate->curperagg for AggGetAggref() */
483 aggstate->curperagg = peraggstate;
486 * OK to call the transition function
488 fcinfo->arg[0] = pergroupstate->transValue;
489 fcinfo->argnull[0] = pergroupstate->transValueIsNull;
490 fcinfo->isnull = false; /* just in case transfn doesn't set it */
492 newVal = FunctionCallInvoke(fcinfo);
494 aggstate->curperagg = NULL;
497 * If pass-by-ref datatype, must copy the new value into aggcontext and
498 * pfree the prior transValue. But if transfn returned a pointer to its
499 * first input, we don't need to do anything.
501 if (!peraggstate->transtypeByVal &&
502 DatumGetPointer(newVal) != DatumGetPointer(pergroupstate->transValue))
506 MemoryContextSwitchTo(aggstate->aggcontext);
507 newVal = datumCopy(newVal,
508 peraggstate->transtypeByVal,
509 peraggstate->transtypeLen);
511 if (!pergroupstate->transValueIsNull)
512 pfree(DatumGetPointer(pergroupstate->transValue));
515 pergroupstate->transValue = newVal;
516 pergroupstate->transValueIsNull = fcinfo->isnull;
518 MemoryContextSwitchTo(oldContext);
522 * Advance all the aggregates for one input tuple. The input tuple
523 * has been stored in tmpcontext->ecxt_outertuple, so that it is accessible
524 * to ExecEvalExpr. pergroup is the array of per-group structs to use
525 * (this might be in a hashtable entry).
527 * When called, CurrentMemoryContext should be the per-query context.
530 advance_aggregates(AggState *aggstate, AggStatePerGroup pergroup)
534 for (aggno = 0; aggno < aggstate->numaggs; aggno++)
536 AggStatePerAgg peraggstate = &aggstate->peragg[aggno];
537 AggStatePerGroup pergroupstate = &pergroup[aggno];
538 ExprState *filter = peraggstate->aggrefstate->aggfilter;
539 int numTransInputs = peraggstate->numTransInputs;
541 TupleTableSlot *slot;
543 /* Skip anything FILTERed out */
549 res = ExecEvalExprSwitchContext(filter, aggstate->tmpcontext,
551 if (isnull || !DatumGetBool(res))
555 /* Evaluate the current input expressions for this aggregate */
556 slot = ExecProject(peraggstate->evalproj, NULL);
558 if (peraggstate->numSortCols > 0)
560 /* DISTINCT and/or ORDER BY case */
561 Assert(slot->tts_nvalid == peraggstate->numInputs);
564 * If the transfn is strict, we want to check for nullity before
565 * storing the row in the sorter, to save space if there are a lot
566 * of nulls. Note that we must only check numTransInputs columns,
567 * not numInputs, since nullity in columns used only for sorting
568 * is not relevant here.
570 if (peraggstate->transfn.fn_strict)
572 for (i = 0; i < numTransInputs; i++)
574 if (slot->tts_isnull[i])
577 if (i < numTransInputs)
581 /* OK, put the tuple into the tuplesort object */
582 if (peraggstate->numInputs == 1)
583 tuplesort_putdatum(peraggstate->sortstate,
585 slot->tts_isnull[0]);
587 tuplesort_puttupleslot(peraggstate->sortstate, slot);
591 /* We can apply the transition function immediately */
592 FunctionCallInfo fcinfo = &peraggstate->transfn_fcinfo;
594 /* Load values into fcinfo */
595 /* Start from 1, since the 0th arg will be the transition value */
596 Assert(slot->tts_nvalid >= numTransInputs);
597 for (i = 0; i < numTransInputs; i++)
599 fcinfo->arg[i + 1] = slot->tts_values[i];
600 fcinfo->argnull[i + 1] = slot->tts_isnull[i];
603 advance_transition_function(aggstate, peraggstate, pergroupstate);
610 * Run the transition function for a DISTINCT or ORDER BY aggregate
611 * with only one input. This is called after we have completed
612 * entering all the input values into the sort object. We complete the
613 * sort, read out the values in sorted order, and run the transition
614 * function on each value (applying DISTINCT if appropriate).
616 * Note that the strictness of the transition function was checked when
617 * entering the values into the sort, so we don't check it again here;
618 * we just apply standard SQL DISTINCT logic.
620 * The one-input case is handled separately from the multi-input case
621 * for performance reasons: for single by-value inputs, such as the
622 * common case of count(distinct id), the tuplesort_getdatum code path
623 * is around 300% faster. (The speedup for by-reference types is less
624 * but still noticeable.)
626 * When called, CurrentMemoryContext should be the per-query context.
629 process_ordered_aggregate_single(AggState *aggstate,
630 AggStatePerAgg peraggstate,
631 AggStatePerGroup pergroupstate)
633 Datum oldVal = (Datum) 0;
634 bool oldIsNull = true;
635 bool haveOldVal = false;
636 MemoryContext workcontext = aggstate->tmpcontext->ecxt_per_tuple_memory;
637 MemoryContext oldContext;
638 bool isDistinct = (peraggstate->numDistinctCols > 0);
639 FunctionCallInfo fcinfo = &peraggstate->transfn_fcinfo;
643 Assert(peraggstate->numDistinctCols < 2);
645 tuplesort_performsort(peraggstate->sortstate);
647 /* Load the column into argument 1 (arg 0 will be transition value) */
648 newVal = fcinfo->arg + 1;
649 isNull = fcinfo->argnull + 1;
652 * Note: if input type is pass-by-ref, the datums returned by the sort are
653 * freshly palloc'd in the per-query context, so we must be careful to
654 * pfree them when they are no longer needed.
657 while (tuplesort_getdatum(peraggstate->sortstate, true,
661 * Clear and select the working context for evaluation of the equality
662 * function and transition function.
664 MemoryContextReset(workcontext);
665 oldContext = MemoryContextSwitchTo(workcontext);
668 * If DISTINCT mode, and not distinct from prior, skip it.
670 * Note: we assume equality functions don't care about collation.
674 ((oldIsNull && *isNull) ||
675 (!oldIsNull && !*isNull &&
676 DatumGetBool(FunctionCall2(&peraggstate->equalfns[0],
679 /* equal to prior, so forget this one */
680 if (!peraggstate->inputtypeByVal && !*isNull)
681 pfree(DatumGetPointer(*newVal));
685 advance_transition_function(aggstate, peraggstate, pergroupstate);
686 /* forget the old value, if any */
687 if (!oldIsNull && !peraggstate->inputtypeByVal)
688 pfree(DatumGetPointer(oldVal));
689 /* and remember the new one for subsequent equality checks */
695 MemoryContextSwitchTo(oldContext);
698 if (!oldIsNull && !peraggstate->inputtypeByVal)
699 pfree(DatumGetPointer(oldVal));
701 tuplesort_end(peraggstate->sortstate);
702 peraggstate->sortstate = NULL;
706 * Run the transition function for a DISTINCT or ORDER BY aggregate
707 * with more than one input. This is called after we have completed
708 * entering all the input values into the sort object. We complete the
709 * sort, read out the values in sorted order, and run the transition
710 * function on each value (applying DISTINCT if appropriate).
712 * When called, CurrentMemoryContext should be the per-query context.
715 process_ordered_aggregate_multi(AggState *aggstate,
716 AggStatePerAgg peraggstate,
717 AggStatePerGroup pergroupstate)
719 MemoryContext workcontext = aggstate->tmpcontext->ecxt_per_tuple_memory;
720 FunctionCallInfo fcinfo = &peraggstate->transfn_fcinfo;
721 TupleTableSlot *slot1 = peraggstate->evalslot;
722 TupleTableSlot *slot2 = peraggstate->uniqslot;
723 int numTransInputs = peraggstate->numTransInputs;
724 int numDistinctCols = peraggstate->numDistinctCols;
725 bool haveOldValue = false;
728 tuplesort_performsort(peraggstate->sortstate);
730 ExecClearTuple(slot1);
732 ExecClearTuple(slot2);
734 while (tuplesort_gettupleslot(peraggstate->sortstate, true, slot1))
737 * Extract the first numTransInputs columns as datums to pass to the
738 * transfn. (This will help execTuplesMatch too, so we do it
741 slot_getsomeattrs(slot1, numTransInputs);
743 if (numDistinctCols == 0 ||
745 !execTuplesMatch(slot1, slot2,
747 peraggstate->sortColIdx,
748 peraggstate->equalfns,
751 /* Load values into fcinfo */
752 /* Start from 1, since the 0th arg will be the transition value */
753 for (i = 0; i < numTransInputs; i++)
755 fcinfo->arg[i + 1] = slot1->tts_values[i];
756 fcinfo->argnull[i + 1] = slot1->tts_isnull[i];
759 advance_transition_function(aggstate, peraggstate, pergroupstate);
761 if (numDistinctCols > 0)
763 /* swap the slot pointers to retain the current tuple */
764 TupleTableSlot *tmpslot = slot2;
772 /* Reset context each time, unless execTuplesMatch did it for us */
773 if (numDistinctCols == 0)
774 MemoryContextReset(workcontext);
776 ExecClearTuple(slot1);
780 ExecClearTuple(slot2);
782 tuplesort_end(peraggstate->sortstate);
783 peraggstate->sortstate = NULL;
787 * Compute the final value of one aggregate.
789 * The finalfunction will be run, and the result delivered, in the
790 * output-tuple context; caller's CurrentMemoryContext does not matter.
793 finalize_aggregate(AggState *aggstate,
794 AggStatePerAgg peraggstate,
795 AggStatePerGroup pergroupstate,
796 Datum *resultVal, bool *resultIsNull)
798 FunctionCallInfoData fcinfo;
799 bool anynull = false;
800 MemoryContext oldContext;
804 oldContext = MemoryContextSwitchTo(aggstate->ss.ps.ps_ExprContext->ecxt_per_tuple_memory);
807 * Evaluate any direct arguments. We do this even if there's no finalfn
808 * (which is unlikely anyway), so that side-effects happen as expected.
809 * The direct arguments go into arg positions 1 and up, leaving position 0
810 * for the transition state value.
813 foreach(lc, peraggstate->aggrefstate->aggdirectargs)
815 ExprState *expr = (ExprState *) lfirst(lc);
817 fcinfo.arg[i] = ExecEvalExpr(expr,
818 aggstate->ss.ps.ps_ExprContext,
821 anynull |= fcinfo.argnull[i];
826 * Apply the agg's finalfn if one is provided, else return transValue.
828 if (OidIsValid(peraggstate->finalfn_oid))
830 int numFinalArgs = peraggstate->numFinalArgs;
832 /* set up aggstate->curperagg for AggGetAggref() */
833 aggstate->curperagg = peraggstate;
835 InitFunctionCallInfoData(fcinfo, &(peraggstate->finalfn),
837 peraggstate->aggCollation,
838 (void *) aggstate, NULL);
840 /* Fill in the transition state value */
841 fcinfo.arg[0] = pergroupstate->transValue;
842 fcinfo.argnull[0] = pergroupstate->transValueIsNull;
843 anynull |= pergroupstate->transValueIsNull;
845 /* Fill any remaining argument positions with nulls */
846 for (; i < numFinalArgs; i++)
848 fcinfo.arg[i] = (Datum) 0;
849 fcinfo.argnull[i] = true;
853 if (fcinfo.flinfo->fn_strict && anynull)
855 /* don't call a strict function with NULL inputs */
856 *resultVal = (Datum) 0;
857 *resultIsNull = true;
861 *resultVal = FunctionCallInvoke(&fcinfo);
862 *resultIsNull = fcinfo.isnull;
864 aggstate->curperagg = NULL;
868 *resultVal = pergroupstate->transValue;
869 *resultIsNull = pergroupstate->transValueIsNull;
873 * If result is pass-by-ref, make sure it is in the right context.
875 if (!peraggstate->resulttypeByVal && !*resultIsNull &&
876 !MemoryContextContains(CurrentMemoryContext,
877 DatumGetPointer(*resultVal)))
878 *resultVal = datumCopy(*resultVal,
879 peraggstate->resulttypeByVal,
880 peraggstate->resulttypeLen);
882 MemoryContextSwitchTo(oldContext);
886 * find_unaggregated_cols
887 * Construct a bitmapset of the column numbers of un-aggregated Vars
888 * appearing in our targetlist and qual (HAVING clause)
891 find_unaggregated_cols(AggState *aggstate)
893 Agg *node = (Agg *) aggstate->ss.ps.plan;
897 (void) find_unaggregated_cols_walker((Node *) node->plan.targetlist,
899 (void) find_unaggregated_cols_walker((Node *) node->plan.qual,
905 find_unaggregated_cols_walker(Node *node, Bitmapset **colnos)
911 Var *var = (Var *) node;
913 /* setrefs.c should have set the varno to OUTER_VAR */
914 Assert(var->varno == OUTER_VAR);
915 Assert(var->varlevelsup == 0);
916 *colnos = bms_add_member(*colnos, var->varattno);
919 if (IsA(node, Aggref)) /* do not descend into aggregate exprs */
921 return expression_tree_walker(node, find_unaggregated_cols_walker,
926 * Initialize the hash table to empty.
928 * The hash table always lives in the aggcontext memory context.
931 build_hash_table(AggState *aggstate)
933 Agg *node = (Agg *) aggstate->ss.ps.plan;
934 MemoryContext tmpmem = aggstate->tmpcontext->ecxt_per_tuple_memory;
937 Assert(node->aggstrategy == AGG_HASHED);
938 Assert(node->numGroups > 0);
940 entrysize = sizeof(AggHashEntryData) +
941 (aggstate->numaggs - 1) * sizeof(AggStatePerGroupData);
943 aggstate->hashtable = BuildTupleHashTable(node->numCols,
945 aggstate->eqfunctions,
946 aggstate->hashfunctions,
949 aggstate->aggcontext,
954 * Create a list of the tuple columns that actually need to be stored in
955 * hashtable entries. The incoming tuples from the child plan node will
956 * contain grouping columns, other columns referenced in our targetlist and
957 * qual, columns used to compute the aggregate functions, and perhaps just
958 * junk columns we don't use at all. Only columns of the first two types
959 * need to be stored in the hashtable, and getting rid of the others can
960 * make the table entries significantly smaller. To avoid messing up Var
961 * numbering, we keep the same tuple descriptor for hashtable entries as the
962 * incoming tuples have, but set unwanted columns to NULL in the tuples that
965 * To eliminate duplicates, we build a bitmapset of the needed columns, then
966 * convert it to an integer list (cheaper to scan at runtime). The list is
967 * in decreasing order so that the first entry is the largest;
968 * lookup_hash_entry depends on this to use slot_getsomeattrs correctly.
969 * Note that the list is preserved over ExecReScanAgg, so we allocate it in
970 * the per-query context (unlike the hash table itself).
972 * Note: at present, searching the tlist/qual is not really necessary since
973 * the parser should disallow any unaggregated references to ungrouped
974 * columns. However, the search will be needed when we add support for
975 * SQL99 semantics that allow use of "functionally dependent" columns that
976 * haven't been explicitly grouped by.
979 find_hash_columns(AggState *aggstate)
981 Agg *node = (Agg *) aggstate->ss.ps.plan;
986 /* Find Vars that will be needed in tlist and qual */
987 colnos = find_unaggregated_cols(aggstate);
988 /* Add in all the grouping columns */
989 for (i = 0; i < node->numCols; i++)
990 colnos = bms_add_member(colnos, node->grpColIdx[i]);
991 /* Convert to list, using lcons so largest element ends up first */
993 while ((i = bms_first_member(colnos)) >= 0)
994 collist = lcons_int(i, collist);
1001 * Estimate per-hash-table-entry overhead for the planner.
1003 * Note that the estimate does not include space for pass-by-reference
1004 * transition data values, nor for the representative tuple of each group.
1007 hash_agg_entry_size(int numAggs)
1011 /* This must match build_hash_table */
1012 entrysize = sizeof(AggHashEntryData) +
1013 (numAggs - 1) * sizeof(AggStatePerGroupData);
1014 entrysize = MAXALIGN(entrysize);
1015 /* Account for hashtable overhead (assuming fill factor = 1) */
1016 entrysize += 3 * sizeof(void *);
1021 * Find or create a hashtable entry for the tuple group containing the
1024 * When called, CurrentMemoryContext should be the per-query context.
1027 lookup_hash_entry(AggState *aggstate, TupleTableSlot *inputslot)
1029 TupleTableSlot *hashslot = aggstate->hashslot;
1034 /* if first time through, initialize hashslot by cloning input slot */
1035 if (hashslot->tts_tupleDescriptor == NULL)
1037 ExecSetSlotDescriptor(hashslot, inputslot->tts_tupleDescriptor);
1038 /* Make sure all unused columns are NULLs */
1039 ExecStoreAllNullTuple(hashslot);
1042 /* transfer just the needed columns into hashslot */
1043 slot_getsomeattrs(inputslot, linitial_int(aggstate->hash_needed));
1044 foreach(l, aggstate->hash_needed)
1046 int varNumber = lfirst_int(l) - 1;
1048 hashslot->tts_values[varNumber] = inputslot->tts_values[varNumber];
1049 hashslot->tts_isnull[varNumber] = inputslot->tts_isnull[varNumber];
1052 /* find or create the hashtable entry using the filtered tuple */
1053 entry = (AggHashEntry) LookupTupleHashEntry(aggstate->hashtable,
1059 /* initialize aggregates for new tuple group */
1060 initialize_aggregates(aggstate, aggstate->peragg, entry->pergroup);
1069 * ExecAgg receives tuples from its outer subplan and aggregates over
1070 * the appropriate attribute for each aggregate function use (Aggref
1071 * node) appearing in the targetlist or qual of the node. The number
1072 * of tuples to aggregate over depends on whether grouped or plain
1073 * aggregation is selected. In grouped aggregation, we produce a result
1074 * row for each group; in plain aggregation there's a single result row
1075 * for the whole query. In either case, the value of each aggregate is
1076 * stored in the expression context to be used when ExecProject evaluates
1080 ExecAgg(AggState *node)
1083 * Check to see if we're still projecting out tuples from a previous agg
1084 * tuple (because there is a function-returning-set in the projection
1085 * expressions). If so, try to project another one.
1087 if (node->ss.ps.ps_TupFromTlist)
1089 TupleTableSlot *result;
1090 ExprDoneCond isDone;
1092 result = ExecProject(node->ss.ps.ps_ProjInfo, &isDone);
1093 if (isDone == ExprMultipleResult)
1095 /* Done with that source tuple... */
1096 node->ss.ps.ps_TupFromTlist = false;
1100 * Exit if nothing left to do. (We must do the ps_TupFromTlist check
1101 * first, because in some cases agg_done gets set before we emit the final
1102 * aggregate tuple, and we have to finish running SRFs for it.)
1107 /* Dispatch based on strategy */
1108 if (((Agg *) node->ss.ps.plan)->aggstrategy == AGG_HASHED)
1110 if (!node->table_filled)
1111 agg_fill_hash_table(node);
1112 return agg_retrieve_hash_table(node);
1115 return agg_retrieve_direct(node);
1119 * ExecAgg for non-hashed case
1121 static TupleTableSlot *
1122 agg_retrieve_direct(AggState *aggstate)
1124 Agg *node = (Agg *) aggstate->ss.ps.plan;
1125 PlanState *outerPlan;
1126 ExprContext *econtext;
1127 ExprContext *tmpcontext;
1130 AggStatePerAgg peragg;
1131 AggStatePerGroup pergroup;
1132 TupleTableSlot *outerslot;
1133 TupleTableSlot *firstSlot;
1137 * get state info from node
1139 outerPlan = outerPlanState(aggstate);
1140 /* econtext is the per-output-tuple expression context */
1141 econtext = aggstate->ss.ps.ps_ExprContext;
1142 aggvalues = econtext->ecxt_aggvalues;
1143 aggnulls = econtext->ecxt_aggnulls;
1144 /* tmpcontext is the per-input-tuple expression context */
1145 tmpcontext = aggstate->tmpcontext;
1146 peragg = aggstate->peragg;
1147 pergroup = aggstate->pergroup;
1148 firstSlot = aggstate->ss.ss_ScanTupleSlot;
1151 * We loop retrieving groups until we find one matching
1152 * aggstate->ss.ps.qual
1154 while (!aggstate->agg_done)
1157 * If we don't already have the first tuple of the new group, fetch it
1158 * from the outer plan.
1160 if (aggstate->grp_firstTuple == NULL)
1162 outerslot = ExecProcNode(outerPlan);
1163 if (!TupIsNull(outerslot))
1166 * Make a copy of the first input tuple; we will use this for
1167 * comparisons (in group mode) and for projection.
1169 aggstate->grp_firstTuple = ExecCopySlotTuple(outerslot);
1173 /* outer plan produced no tuples at all */
1174 aggstate->agg_done = true;
1175 /* If we are grouping, we should produce no tuples too */
1176 if (node->aggstrategy != AGG_PLAIN)
1182 * Clear the per-output-tuple context for each group, as well as
1183 * aggcontext (which contains any pass-by-ref transvalues of the old
1184 * group). We also clear any child contexts of the aggcontext; some
1185 * aggregate functions store working state in such contexts.
1187 * We use ReScanExprContext not just ResetExprContext because we want
1188 * any registered shutdown callbacks to be called. That allows
1189 * aggregate functions to ensure they've cleaned up any non-memory
1192 ReScanExprContext(econtext);
1194 MemoryContextResetAndDeleteChildren(aggstate->aggcontext);
1197 * Initialize working state for a new input tuple group
1199 initialize_aggregates(aggstate, peragg, pergroup);
1201 if (aggstate->grp_firstTuple != NULL)
1204 * Store the copied first input tuple in the tuple table slot
1205 * reserved for it. The tuple will be deleted when it is cleared
1208 ExecStoreTuple(aggstate->grp_firstTuple,
1212 aggstate->grp_firstTuple = NULL; /* don't keep two pointers */
1214 /* set up for first advance_aggregates call */
1215 tmpcontext->ecxt_outertuple = firstSlot;
1218 * Process each outer-plan tuple, and then fetch the next one,
1219 * until we exhaust the outer plan or cross a group boundary.
1223 advance_aggregates(aggstate, pergroup);
1225 /* Reset per-input-tuple context after each tuple */
1226 ResetExprContext(tmpcontext);
1228 outerslot = ExecProcNode(outerPlan);
1229 if (TupIsNull(outerslot))
1231 /* no more outer-plan tuples available */
1232 aggstate->agg_done = true;
1235 /* set up for next advance_aggregates call */
1236 tmpcontext->ecxt_outertuple = outerslot;
1239 * If we are grouping, check whether we've crossed a group
1242 if (node->aggstrategy == AGG_SORTED)
1244 if (!execTuplesMatch(firstSlot,
1246 node->numCols, node->grpColIdx,
1247 aggstate->eqfunctions,
1248 tmpcontext->ecxt_per_tuple_memory))
1251 * Save the first input tuple of the next group.
1253 aggstate->grp_firstTuple = ExecCopySlotTuple(outerslot);
1261 * Use the representative input tuple for any references to
1262 * non-aggregated input columns in aggregate direct args, the node
1263 * qual, and the tlist. (If we are not grouping, and there are no
1264 * input rows at all, we will come here with an empty firstSlot ...
1265 * but if not grouping, there can't be any references to
1266 * non-aggregated input columns, so no problem.)
1268 econtext->ecxt_outertuple = firstSlot;
1271 * Done scanning input tuple group. Finalize each aggregate
1272 * calculation, and stash results in the per-output-tuple context.
1274 for (aggno = 0; aggno < aggstate->numaggs; aggno++)
1276 AggStatePerAgg peraggstate = &peragg[aggno];
1277 AggStatePerGroup pergroupstate = &pergroup[aggno];
1279 if (peraggstate->numSortCols > 0)
1281 if (peraggstate->numInputs == 1)
1282 process_ordered_aggregate_single(aggstate,
1286 process_ordered_aggregate_multi(aggstate,
1291 finalize_aggregate(aggstate, peraggstate, pergroupstate,
1292 &aggvalues[aggno], &aggnulls[aggno]);
1296 * Check the qual (HAVING clause); if the group does not match, ignore
1297 * it and loop back to try to process another group.
1299 if (ExecQual(aggstate->ss.ps.qual, econtext, false))
1302 * Form and return a projection tuple using the aggregate results
1303 * and the representative input tuple.
1305 TupleTableSlot *result;
1306 ExprDoneCond isDone;
1308 result = ExecProject(aggstate->ss.ps.ps_ProjInfo, &isDone);
1310 if (isDone != ExprEndResult)
1312 aggstate->ss.ps.ps_TupFromTlist =
1313 (isDone == ExprMultipleResult);
1318 InstrCountFiltered1(aggstate, 1);
1321 /* No more groups */
1326 * ExecAgg for hashed case: phase 1, read input and build hash table
1329 agg_fill_hash_table(AggState *aggstate)
1331 PlanState *outerPlan;
1332 ExprContext *tmpcontext;
1334 TupleTableSlot *outerslot;
1337 * get state info from node
1339 outerPlan = outerPlanState(aggstate);
1340 /* tmpcontext is the per-input-tuple expression context */
1341 tmpcontext = aggstate->tmpcontext;
1344 * Process each outer-plan tuple, and then fetch the next one, until we
1345 * exhaust the outer plan.
1349 outerslot = ExecProcNode(outerPlan);
1350 if (TupIsNull(outerslot))
1352 /* set up for advance_aggregates call */
1353 tmpcontext->ecxt_outertuple = outerslot;
1355 /* Find or build hashtable entry for this tuple's group */
1356 entry = lookup_hash_entry(aggstate, outerslot);
1358 /* Advance the aggregates */
1359 advance_aggregates(aggstate, entry->pergroup);
1361 /* Reset per-input-tuple context after each tuple */
1362 ResetExprContext(tmpcontext);
1365 aggstate->table_filled = true;
1366 /* Initialize to walk the hash table */
1367 ResetTupleHashIterator(aggstate->hashtable, &aggstate->hashiter);
1371 * ExecAgg for hashed case: phase 2, retrieving groups from hash table
1373 static TupleTableSlot *
1374 agg_retrieve_hash_table(AggState *aggstate)
1376 ExprContext *econtext;
1379 AggStatePerAgg peragg;
1380 AggStatePerGroup pergroup;
1382 TupleTableSlot *firstSlot;
1386 * get state info from node
1388 /* econtext is the per-output-tuple expression context */
1389 econtext = aggstate->ss.ps.ps_ExprContext;
1390 aggvalues = econtext->ecxt_aggvalues;
1391 aggnulls = econtext->ecxt_aggnulls;
1392 peragg = aggstate->peragg;
1393 firstSlot = aggstate->ss.ss_ScanTupleSlot;
1396 * We loop retrieving groups until we find one satisfying
1397 * aggstate->ss.ps.qual
1399 while (!aggstate->agg_done)
1402 * Find the next entry in the hash table
1404 entry = (AggHashEntry) ScanTupleHashTable(&aggstate->hashiter);
1407 /* No more entries in hashtable, so done */
1408 aggstate->agg_done = TRUE;
1413 * Clear the per-output-tuple context for each group
1415 * We intentionally don't use ReScanExprContext here; if any aggs have
1416 * registered shutdown callbacks, they mustn't be called yet, since we
1417 * might not be done with that agg.
1419 ResetExprContext(econtext);
1422 * Store the copied first input tuple in the tuple table slot reserved
1423 * for it, so that it can be used in ExecProject.
1425 ExecStoreMinimalTuple(entry->shared.firstTuple,
1429 pergroup = entry->pergroup;
1432 * Finalize each aggregate calculation, and stash results in the
1433 * per-output-tuple context.
1435 for (aggno = 0; aggno < aggstate->numaggs; aggno++)
1437 AggStatePerAgg peraggstate = &peragg[aggno];
1438 AggStatePerGroup pergroupstate = &pergroup[aggno];
1440 Assert(peraggstate->numSortCols == 0);
1441 finalize_aggregate(aggstate, peraggstate, pergroupstate,
1442 &aggvalues[aggno], &aggnulls[aggno]);
1446 * Use the representative input tuple for any references to
1447 * non-aggregated input columns in the qual and tlist.
1449 econtext->ecxt_outertuple = firstSlot;
1452 * Check the qual (HAVING clause); if the group does not match, ignore
1453 * it and loop back to try to process another group.
1455 if (ExecQual(aggstate->ss.ps.qual, econtext, false))
1458 * Form and return a projection tuple using the aggregate results
1459 * and the representative input tuple.
1461 TupleTableSlot *result;
1462 ExprDoneCond isDone;
1464 result = ExecProject(aggstate->ss.ps.ps_ProjInfo, &isDone);
1466 if (isDone != ExprEndResult)
1468 aggstate->ss.ps.ps_TupFromTlist =
1469 (isDone == ExprMultipleResult);
1474 InstrCountFiltered1(aggstate, 1);
1477 /* No more groups */
1481 /* -----------------
1484 * Creates the run-time information for the agg node produced by the
1485 * planner and initializes its outer subtree
1489 ExecInitAgg(Agg *node, EState *estate, int eflags)
1492 AggStatePerAgg peragg;
1494 ExprContext *econtext;
1499 /* check for unsupported flags */
1500 Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
1503 * create state structure
1505 aggstate = makeNode(AggState);
1506 aggstate->ss.ps.plan = (Plan *) node;
1507 aggstate->ss.ps.state = estate;
1509 aggstate->aggs = NIL;
1510 aggstate->numaggs = 0;
1511 aggstate->eqfunctions = NULL;
1512 aggstate->hashfunctions = NULL;
1513 aggstate->peragg = NULL;
1514 aggstate->curperagg = NULL;
1515 aggstate->agg_done = false;
1516 aggstate->pergroup = NULL;
1517 aggstate->grp_firstTuple = NULL;
1518 aggstate->hashtable = NULL;
1521 * Create expression contexts. We need two, one for per-input-tuple
1522 * processing and one for per-output-tuple processing. We cheat a little
1523 * by using ExecAssignExprContext() to build both.
1525 ExecAssignExprContext(estate, &aggstate->ss.ps);
1526 aggstate->tmpcontext = aggstate->ss.ps.ps_ExprContext;
1527 ExecAssignExprContext(estate, &aggstate->ss.ps);
1530 * We also need a long-lived memory context for holding hashtable data
1531 * structures and transition values. NOTE: the details of what is stored
1532 * in aggcontext and what is stored in the regular per-query memory
1533 * context are driven by a simple decision: we want to reset the
1534 * aggcontext at group boundaries (if not hashing) and in ExecReScanAgg to
1535 * recover no-longer-wanted space.
1537 aggstate->aggcontext =
1538 AllocSetContextCreate(CurrentMemoryContext,
1540 ALLOCSET_DEFAULT_MINSIZE,
1541 ALLOCSET_DEFAULT_INITSIZE,
1542 ALLOCSET_DEFAULT_MAXSIZE);
1545 * tuple table initialization
1547 ExecInitScanTupleSlot(estate, &aggstate->ss);
1548 ExecInitResultTupleSlot(estate, &aggstate->ss.ps);
1549 aggstate->hashslot = ExecInitExtraTupleSlot(estate);
1552 * initialize child expressions
1554 * Note: ExecInitExpr finds Aggrefs for us, and also checks that no aggs
1555 * contain other agg calls in their arguments. This would make no sense
1556 * under SQL semantics anyway (and it's forbidden by the spec). Because
1557 * that is true, we don't need to worry about evaluating the aggs in any
1560 aggstate->ss.ps.targetlist = (List *)
1561 ExecInitExpr((Expr *) node->plan.targetlist,
1562 (PlanState *) aggstate);
1563 aggstate->ss.ps.qual = (List *)
1564 ExecInitExpr((Expr *) node->plan.qual,
1565 (PlanState *) aggstate);
1568 * initialize child nodes
1570 * If we are doing a hashed aggregation then the child plan does not need
1571 * to handle REWIND efficiently; see ExecReScanAgg.
1573 if (node->aggstrategy == AGG_HASHED)
1574 eflags &= ~EXEC_FLAG_REWIND;
1575 outerPlan = outerPlan(node);
1576 outerPlanState(aggstate) = ExecInitNode(outerPlan, estate, eflags);
1579 * initialize source tuple type.
1581 ExecAssignScanTypeFromOuterPlan(&aggstate->ss);
1584 * Initialize result tuple type and projection info.
1586 ExecAssignResultTypeFromTL(&aggstate->ss.ps);
1587 ExecAssignProjectionInfo(&aggstate->ss.ps, NULL);
1589 aggstate->ss.ps.ps_TupFromTlist = false;
1592 * get the count of aggregates in targetlist and quals
1594 numaggs = aggstate->numaggs;
1595 Assert(numaggs == list_length(aggstate->aggs));
1599 * This is not an error condition: we might be using the Agg node just
1600 * to do hash-based grouping. Even in the regular case,
1601 * constant-expression simplification could optimize away all of the
1602 * Aggrefs in the targetlist and qual. So keep going, but force local
1603 * copy of numaggs positive so that palloc()s below don't choke.
1609 * If we are grouping, precompute fmgr lookup data for inner loop. We need
1610 * both equality and hashing functions to do it by hashing, but only
1611 * equality if not hashing.
1613 if (node->numCols > 0)
1615 if (node->aggstrategy == AGG_HASHED)
1616 execTuplesHashPrepare(node->numCols,
1618 &aggstate->eqfunctions,
1619 &aggstate->hashfunctions);
1621 aggstate->eqfunctions =
1622 execTuplesMatchPrepare(node->numCols,
1623 node->grpOperators);
1627 * Set up aggregate-result storage in the output expr context, and also
1628 * allocate my private per-agg working storage
1630 econtext = aggstate->ss.ps.ps_ExprContext;
1631 econtext->ecxt_aggvalues = (Datum *) palloc0(sizeof(Datum) * numaggs);
1632 econtext->ecxt_aggnulls = (bool *) palloc0(sizeof(bool) * numaggs);
1634 peragg = (AggStatePerAgg) palloc0(sizeof(AggStatePerAggData) * numaggs);
1635 aggstate->peragg = peragg;
1637 if (node->aggstrategy == AGG_HASHED)
1639 build_hash_table(aggstate);
1640 aggstate->table_filled = false;
1641 /* Compute the columns we actually need to hash on */
1642 aggstate->hash_needed = find_hash_columns(aggstate);
1646 AggStatePerGroup pergroup;
1648 pergroup = (AggStatePerGroup) palloc0(sizeof(AggStatePerGroupData) * numaggs);
1649 aggstate->pergroup = pergroup;
1653 * Perform lookups of aggregate function info, and initialize the
1654 * unchanging fields of the per-agg data. We also detect duplicate
1655 * aggregates (for example, "SELECT sum(x) ... HAVING sum(x) > 0"). When
1656 * duplicates are detected, we only make an AggStatePerAgg struct for the
1657 * first one. The clones are simply pointed at the same result entry by
1658 * giving them duplicate aggno values.
1661 foreach(l, aggstate->aggs)
1663 AggrefExprState *aggrefstate = (AggrefExprState *) lfirst(l);
1664 Aggref *aggref = (Aggref *) aggrefstate->xprstate.expr;
1665 AggStatePerAgg peraggstate;
1666 Oid inputTypes[FUNC_MAX_ARGS];
1671 int numDistinctCols;
1674 Form_pg_aggregate aggform;
1676 AclResult aclresult;
1685 /* Planner should have assigned aggregate to correct level */
1686 Assert(aggref->agglevelsup == 0);
1688 /* Look for a previous duplicate aggregate */
1689 for (i = 0; i <= aggno; i++)
1691 if (equal(aggref, peragg[i].aggref) &&
1692 !contain_volatile_functions((Node *) aggref))
1697 /* Found a match to an existing entry, so just mark it */
1698 aggrefstate->aggno = i;
1702 /* Nope, so assign a new PerAgg record */
1703 peraggstate = &peragg[++aggno];
1705 /* Mark Aggref state node with assigned index in the result array */
1706 aggrefstate->aggno = aggno;
1708 /* Begin filling in the peraggstate data */
1709 peraggstate->aggrefstate = aggrefstate;
1710 peraggstate->aggref = aggref;
1711 peraggstate->sortstate = NULL;
1713 /* Fetch the pg_aggregate row */
1714 aggTuple = SearchSysCache1(AGGFNOID,
1715 ObjectIdGetDatum(aggref->aggfnoid));
1716 if (!HeapTupleIsValid(aggTuple))
1717 elog(ERROR, "cache lookup failed for aggregate %u",
1719 aggform = (Form_pg_aggregate) GETSTRUCT(aggTuple);
1721 /* Check permission to call aggregate function */
1722 aclresult = pg_proc_aclcheck(aggref->aggfnoid, GetUserId(),
1724 if (aclresult != ACLCHECK_OK)
1725 aclcheck_error(aclresult, ACL_KIND_PROC,
1726 get_func_name(aggref->aggfnoid));
1727 InvokeFunctionExecuteHook(aggref->aggfnoid);
1729 peraggstate->transfn_oid = transfn_oid = aggform->aggtransfn;
1730 peraggstate->finalfn_oid = finalfn_oid = aggform->aggfinalfn;
1732 /* Check that aggregate owner has permission to call component fns */
1734 HeapTuple procTuple;
1737 procTuple = SearchSysCache1(PROCOID,
1738 ObjectIdGetDatum(aggref->aggfnoid));
1739 if (!HeapTupleIsValid(procTuple))
1740 elog(ERROR, "cache lookup failed for function %u",
1742 aggOwner = ((Form_pg_proc) GETSTRUCT(procTuple))->proowner;
1743 ReleaseSysCache(procTuple);
1745 aclresult = pg_proc_aclcheck(transfn_oid, aggOwner,
1747 if (aclresult != ACLCHECK_OK)
1748 aclcheck_error(aclresult, ACL_KIND_PROC,
1749 get_func_name(transfn_oid));
1750 InvokeFunctionExecuteHook(transfn_oid);
1751 if (OidIsValid(finalfn_oid))
1753 aclresult = pg_proc_aclcheck(finalfn_oid, aggOwner,
1755 if (aclresult != ACLCHECK_OK)
1756 aclcheck_error(aclresult, ACL_KIND_PROC,
1757 get_func_name(finalfn_oid));
1758 InvokeFunctionExecuteHook(finalfn_oid);
1763 * Get actual datatypes of the (nominal) aggregate inputs. These
1764 * could be different from the agg's declared input types, when the
1765 * agg accepts ANY or a polymorphic type.
1767 numArguments = get_aggregate_argtypes(aggref, inputTypes);
1768 peraggstate->numArguments = numArguments;
1770 /* Count the "direct" arguments, if any */
1771 numDirectArgs = list_length(aggref->aggdirectargs);
1773 /* Count the number of aggregated input columns */
1774 numInputs = list_length(aggref->args);
1775 peraggstate->numInputs = numInputs;
1777 /* Detect how many arguments to pass to the transfn */
1778 if (AGGKIND_IS_ORDERED_SET(aggref->aggkind))
1779 peraggstate->numTransInputs = numInputs;
1781 peraggstate->numTransInputs = numArguments;
1783 /* Detect how many arguments to pass to the finalfn */
1784 if (aggform->aggfinalextra)
1785 peraggstate->numFinalArgs = numArguments + 1;
1787 peraggstate->numFinalArgs = numDirectArgs + 1;
1789 /* resolve actual type of transition state, if polymorphic */
1790 aggtranstype = resolve_aggregate_transtype(aggref->aggfnoid,
1791 aggform->aggtranstype,
1795 /* build expression trees using actual argument & result types */
1796 build_aggregate_fnexprs(inputTypes,
1799 peraggstate->numFinalArgs,
1800 aggref->aggvariadic,
1803 aggref->inputcollid,
1805 InvalidOid, /* invtrans is not needed here */
1811 /* set up infrastructure for calling the transfn and finalfn */
1812 fmgr_info(transfn_oid, &peraggstate->transfn);
1813 fmgr_info_set_expr((Node *) transfnexpr, &peraggstate->transfn);
1815 if (OidIsValid(finalfn_oid))
1817 fmgr_info(finalfn_oid, &peraggstate->finalfn);
1818 fmgr_info_set_expr((Node *) finalfnexpr, &peraggstate->finalfn);
1821 peraggstate->aggCollation = aggref->inputcollid;
1823 InitFunctionCallInfoData(peraggstate->transfn_fcinfo,
1824 &peraggstate->transfn,
1825 peraggstate->numTransInputs + 1,
1826 peraggstate->aggCollation,
1827 (void *) aggstate, NULL);
1829 /* get info about relevant datatypes */
1830 get_typlenbyval(aggref->aggtype,
1831 &peraggstate->resulttypeLen,
1832 &peraggstate->resulttypeByVal);
1833 get_typlenbyval(aggtranstype,
1834 &peraggstate->transtypeLen,
1835 &peraggstate->transtypeByVal);
1838 * initval is potentially null, so don't try to access it as a struct
1839 * field. Must do it the hard way with SysCacheGetAttr.
1841 textInitVal = SysCacheGetAttr(AGGFNOID, aggTuple,
1842 Anum_pg_aggregate_agginitval,
1843 &peraggstate->initValueIsNull);
1845 if (peraggstate->initValueIsNull)
1846 peraggstate->initValue = (Datum) 0;
1848 peraggstate->initValue = GetAggInitVal(textInitVal,
1852 * If the transfn is strict and the initval is NULL, make sure input
1853 * type and transtype are the same (or at least binary-compatible), so
1854 * that it's OK to use the first aggregated input value as the initial
1855 * transValue. This should have been checked at agg definition time,
1856 * but we must check again in case the transfn's strictness property
1859 if (peraggstate->transfn.fn_strict && peraggstate->initValueIsNull)
1861 if (numArguments <= numDirectArgs ||
1862 !IsBinaryCoercible(inputTypes[numDirectArgs], aggtranstype))
1864 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
1865 errmsg("aggregate %u needs to have compatible input type and transition type",
1866 aggref->aggfnoid)));
1870 * Get a tupledesc corresponding to the aggregated inputs (including
1871 * sort expressions) of the agg.
1873 peraggstate->evaldesc = ExecTypeFromTL(aggref->args, false);
1875 /* Create slot we're going to do argument evaluation in */
1876 peraggstate->evalslot = ExecInitExtraTupleSlot(estate);
1877 ExecSetSlotDescriptor(peraggstate->evalslot, peraggstate->evaldesc);
1879 /* Set up projection info for evaluation */
1880 peraggstate->evalproj = ExecBuildProjectionInfo(aggrefstate->args,
1881 aggstate->tmpcontext,
1882 peraggstate->evalslot,
1886 * If we're doing either DISTINCT or ORDER BY for a plain agg, then we
1887 * have a list of SortGroupClause nodes; fish out the data in them and
1888 * stick them into arrays. We ignore ORDER BY for an ordered-set agg,
1889 * however; the agg's transfn and finalfn are responsible for that.
1891 * Note that by construction, if there is a DISTINCT clause then the
1892 * ORDER BY clause is a prefix of it (see transformDistinctClause).
1894 if (AGGKIND_IS_ORDERED_SET(aggref->aggkind))
1897 numSortCols = numDistinctCols = 0;
1899 else if (aggref->aggdistinct)
1901 sortlist = aggref->aggdistinct;
1902 numSortCols = numDistinctCols = list_length(sortlist);
1903 Assert(numSortCols >= list_length(aggref->aggorder));
1907 sortlist = aggref->aggorder;
1908 numSortCols = list_length(sortlist);
1909 numDistinctCols = 0;
1912 peraggstate->numSortCols = numSortCols;
1913 peraggstate->numDistinctCols = numDistinctCols;
1915 if (numSortCols > 0)
1918 * We don't implement DISTINCT or ORDER BY aggs in the HASHED case
1921 Assert(node->aggstrategy != AGG_HASHED);
1923 /* If we have only one input, we need its len/byval info. */
1926 get_typlenbyval(inputTypes[numDirectArgs],
1927 &peraggstate->inputtypeLen,
1928 &peraggstate->inputtypeByVal);
1930 else if (numDistinctCols > 0)
1932 /* we will need an extra slot to store prior values */
1933 peraggstate->uniqslot = ExecInitExtraTupleSlot(estate);
1934 ExecSetSlotDescriptor(peraggstate->uniqslot,
1935 peraggstate->evaldesc);
1938 /* Extract the sort information for use later */
1939 peraggstate->sortColIdx =
1940 (AttrNumber *) palloc(numSortCols * sizeof(AttrNumber));
1941 peraggstate->sortOperators =
1942 (Oid *) palloc(numSortCols * sizeof(Oid));
1943 peraggstate->sortCollations =
1944 (Oid *) palloc(numSortCols * sizeof(Oid));
1945 peraggstate->sortNullsFirst =
1946 (bool *) palloc(numSortCols * sizeof(bool));
1949 foreach(lc, sortlist)
1951 SortGroupClause *sortcl = (SortGroupClause *) lfirst(lc);
1952 TargetEntry *tle = get_sortgroupclause_tle(sortcl,
1955 /* the parser should have made sure of this */
1956 Assert(OidIsValid(sortcl->sortop));
1958 peraggstate->sortColIdx[i] = tle->resno;
1959 peraggstate->sortOperators[i] = sortcl->sortop;
1960 peraggstate->sortCollations[i] = exprCollation((Node *) tle->expr);
1961 peraggstate->sortNullsFirst[i] = sortcl->nulls_first;
1964 Assert(i == numSortCols);
1967 if (aggref->aggdistinct)
1969 Assert(numArguments > 0);
1972 * We need the equal function for each DISTINCT comparison we will
1975 peraggstate->equalfns =
1976 (FmgrInfo *) palloc(numDistinctCols * sizeof(FmgrInfo));
1979 foreach(lc, aggref->aggdistinct)
1981 SortGroupClause *sortcl = (SortGroupClause *) lfirst(lc);
1983 fmgr_info(get_opcode(sortcl->eqop), &peraggstate->equalfns[i]);
1986 Assert(i == numDistinctCols);
1989 ReleaseSysCache(aggTuple);
1992 /* Update numaggs to match number of unique aggregates found */
1993 aggstate->numaggs = aggno + 1;
1999 GetAggInitVal(Datum textInitVal, Oid transtype)
2006 getTypeInputInfo(transtype, &typinput, &typioparam);
2007 strInitVal = TextDatumGetCString(textInitVal);
2008 initVal = OidInputFunctionCall(typinput, strInitVal,
2015 ExecEndAgg(AggState *node)
2017 PlanState *outerPlan;
2020 /* Make sure we have closed any open tuplesorts */
2021 for (aggno = 0; aggno < node->numaggs; aggno++)
2023 AggStatePerAgg peraggstate = &node->peragg[aggno];
2025 if (peraggstate->sortstate)
2026 tuplesort_end(peraggstate->sortstate);
2029 /* And ensure any agg shutdown callbacks have been called */
2030 ReScanExprContext(node->ss.ps.ps_ExprContext);
2033 * Free both the expr contexts.
2035 ExecFreeExprContext(&node->ss.ps);
2036 node->ss.ps.ps_ExprContext = node->tmpcontext;
2037 ExecFreeExprContext(&node->ss.ps);
2039 /* clean up tuple table */
2040 ExecClearTuple(node->ss.ss_ScanTupleSlot);
2042 MemoryContextDelete(node->aggcontext);
2044 outerPlan = outerPlanState(node);
2045 ExecEndNode(outerPlan);
2049 ExecReScanAgg(AggState *node)
2051 ExprContext *econtext = node->ss.ps.ps_ExprContext;
2054 node->agg_done = false;
2056 node->ss.ps.ps_TupFromTlist = false;
2058 if (((Agg *) node->ss.ps.plan)->aggstrategy == AGG_HASHED)
2061 * In the hashed case, if we haven't yet built the hash table then we
2062 * can just return; nothing done yet, so nothing to undo. If subnode's
2063 * chgParam is not NULL then it will be re-scanned by ExecProcNode,
2064 * else no reason to re-scan it at all.
2066 if (!node->table_filled)
2070 * If we do have the hash table and the subplan does not have any
2071 * parameter changes, then we can just rescan the existing hash table;
2072 * no need to build it again.
2074 if (node->ss.ps.lefttree->chgParam == NULL)
2076 ResetTupleHashIterator(node->hashtable, &node->hashiter);
2081 /* Make sure we have closed any open tuplesorts */
2082 for (aggno = 0; aggno < node->numaggs; aggno++)
2084 AggStatePerAgg peraggstate = &node->peragg[aggno];
2086 if (peraggstate->sortstate)
2087 tuplesort_end(peraggstate->sortstate);
2088 peraggstate->sortstate = NULL;
2091 /* We don't need to ReScanExprContext here; ExecReScan already did it */
2093 /* Release first tuple of group, if we have made a copy */
2094 if (node->grp_firstTuple != NULL)
2096 heap_freetuple(node->grp_firstTuple);
2097 node->grp_firstTuple = NULL;
2100 /* Forget current agg values */
2101 MemSet(econtext->ecxt_aggvalues, 0, sizeof(Datum) * node->numaggs);
2102 MemSet(econtext->ecxt_aggnulls, 0, sizeof(bool) * node->numaggs);
2105 * Release all temp storage. Note that with AGG_HASHED, the hash table is
2106 * allocated in a sub-context of the aggcontext. We're going to rebuild
2107 * the hash table from scratch, so we need to use
2108 * MemoryContextResetAndDeleteChildren() to avoid leaking the old hash
2109 * table's memory context header.
2111 MemoryContextResetAndDeleteChildren(node->aggcontext);
2113 if (((Agg *) node->ss.ps.plan)->aggstrategy == AGG_HASHED)
2115 /* Rebuild an empty hash table */
2116 build_hash_table(node);
2117 node->table_filled = false;
2122 * Reset the per-group state (in particular, mark transvalues null)
2124 MemSet(node->pergroup, 0,
2125 sizeof(AggStatePerGroupData) * node->numaggs);
2129 * if chgParam of subnode is not null then plan will be re-scanned by
2130 * first ExecProcNode.
2132 if (node->ss.ps.lefttree->chgParam == NULL)
2133 ExecReScan(node->ss.ps.lefttree);
2137 /***********************************************************************
2138 * API exposed to aggregate functions
2139 ***********************************************************************/
2143 * AggCheckCallContext - test if a SQL function is being called as an aggregate
2145 * The transition and/or final functions of an aggregate may want to verify
2146 * that they are being called as aggregates, rather than as plain SQL
2147 * functions. They should use this function to do so. The return value
2148 * is nonzero if being called as an aggregate, or zero if not. (Specific
2149 * nonzero values are AGG_CONTEXT_AGGREGATE or AGG_CONTEXT_WINDOW, but more
2150 * values could conceivably appear in future.)
2152 * If aggcontext isn't NULL, the function also stores at *aggcontext the
2153 * identity of the memory context that aggregate transition values are
2157 AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
2159 if (fcinfo->context && IsA(fcinfo->context, AggState))
2162 *aggcontext = ((AggState *) fcinfo->context)->aggcontext;
2163 return AGG_CONTEXT_AGGREGATE;
2165 if (fcinfo->context && IsA(fcinfo->context, WindowAggState))
2168 *aggcontext = ((WindowAggState *) fcinfo->context)->curaggcontext;
2169 return AGG_CONTEXT_WINDOW;
2172 /* this is just to prevent "uninitialized variable" warnings */
2179 * AggGetAggref - allow an aggregate support function to get its Aggref
2181 * If the function is being called as an aggregate support function,
2182 * return the Aggref node for the aggregate call. Otherwise, return NULL.
2184 * Note that if an aggregate is being used as a window function, this will
2185 * return NULL. We could provide a similar function to return the relevant
2186 * WindowFunc node in such cases, but it's not needed yet.
2189 AggGetAggref(FunctionCallInfo fcinfo)
2191 if (fcinfo->context && IsA(fcinfo->context, AggState))
2193 AggStatePerAgg curperagg = ((AggState *) fcinfo->context)->curperagg;
2196 return curperagg->aggref;
2202 * AggGetPerTupleEContext - fetch per-input-tuple ExprContext
2204 * This is useful in agg final functions; the econtext returned is the
2205 * same per-tuple context that the transfn was called in (which can
2206 * safely get reset during the final function).
2208 * As above, this is currently not useful for aggs called as window functions.
2211 AggGetPerTupleEContext(FunctionCallInfo fcinfo)
2213 if (fcinfo->context && IsA(fcinfo->context, AggState))
2215 AggState *aggstate = (AggState *) fcinfo->context;
2217 return aggstate->tmpcontext;
2223 * AggGetPerAggEContext - fetch per-output-tuple ExprContext
2225 * This is useful for aggs to register shutdown callbacks, which will ensure
2226 * that non-memory resources are freed.
2228 * As above, this is currently not useful for aggs called as window functions.
2231 AggGetPerAggEContext(FunctionCallInfo fcinfo)
2233 if (fcinfo->context && IsA(fcinfo->context, AggState))
2235 AggState *aggstate = (AggState *) fcinfo->context;
2237 return aggstate->ss.ps.ps_ExprContext;
2244 * aggregate_dummy - dummy execution routine for aggregate functions
2246 * This function is listed as the implementation (prosrc field) of pg_proc
2247 * entries for aggregate functions. Its only purpose is to throw an error
2248 * if someone mistakenly executes such a function in the normal way.
2250 * Perhaps someday we could assign real meaning to the prosrc field of
2254 aggregate_dummy(PG_FUNCTION_ARGS)
2256 elog(ERROR, "aggregate function %u called as normal function",
2257 fcinfo->flinfo->fn_oid);
2258 return (Datum) 0; /* keep compiler quiet */