PostgreSQL Source Code  git master
nodeAgg.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * nodeAgg.c
4  * Routines to handle aggregate nodes.
5  *
6  * ExecAgg normally evaluates each aggregate in the following steps:
7  *
8  * transvalue = initcond
9  * foreach input_tuple do
10  * transvalue = transfunc(transvalue, input_value(s))
11  * result = finalfunc(transvalue, direct_argument(s))
12  *
13  * If a finalfunc is not supplied then the result is just the ending
14  * value of transvalue.
15  *
16  * Other behaviors can be selected by the "aggsplit" mode, which exists
17  * to support partial aggregation. It is possible to:
18  * * Skip running the finalfunc, so that the output is always the
19  * final transvalue state.
20  * * Substitute the combinefunc for the transfunc, so that transvalue
21  * states (propagated up from a child partial-aggregation step) are merged
22  * rather than processing raw input rows. (The statements below about
23  * the transfunc apply equally to the combinefunc, when it's selected.)
24  * * Apply the serializefunc to the output values (this only makes sense
25  * when skipping the finalfunc, since the serializefunc works on the
26  * transvalue data type).
27  * * Apply the deserializefunc to the input values (this only makes sense
28  * when using the combinefunc, for similar reasons).
29  * It is the planner's responsibility to connect up Agg nodes using these
30  * alternate behaviors in a way that makes sense, with partial aggregation
31  * results being fed to nodes that expect them.
32  *
33  * If a normal aggregate call specifies DISTINCT or ORDER BY, we sort the
34  * input tuples and eliminate duplicates (if required) before performing
35  * the above-depicted process. (However, we don't do that for ordered-set
36  * aggregates; their "ORDER BY" inputs are ordinary aggregate arguments
37  * so far as this module is concerned.) Note that partial aggregation
38  * is not supported in these cases, since we couldn't ensure global
39  * ordering or distinctness of the inputs.
40  *
41  * If transfunc is marked "strict" in pg_proc and initcond is NULL,
42  * then the first non-NULL input_value is assigned directly to transvalue,
43  * and transfunc isn't applied until the second non-NULL input_value.
44  * The agg's first input type and transtype must be the same in this case!
45  *
46  * If transfunc is marked "strict" then NULL input_values are skipped,
47  * keeping the previous transvalue. If transfunc is not strict then it
48  * is called for every input tuple and must deal with NULL initcond
49  * or NULL input_values for itself.
50  *
51  * If finalfunc is marked "strict" then it is not called when the
52  * ending transvalue is NULL, instead a NULL result is created
53  * automatically (this is just the usual handling of strict functions,
54  * of course). A non-strict finalfunc can make its own choice of
55  * what to return for a NULL ending transvalue.
56  *
57  * Ordered-set aggregates are treated specially in one other way: we
58  * evaluate any "direct" arguments and pass them to the finalfunc along
59  * with the transition value.
60  *
61  * A finalfunc can have additional arguments beyond the transvalue and
62  * any "direct" arguments, corresponding to the input arguments of the
63  * aggregate. These are always just passed as NULL. Such arguments may be
64  * needed to allow resolution of a polymorphic aggregate's result type.
65  *
66  * We compute aggregate input expressions and run the transition functions
67  * in a temporary econtext (aggstate->tmpcontext). This is reset at least
68  * once per input tuple, so when the transvalue datatype is
69  * pass-by-reference, we have to be careful to copy it into a longer-lived
70  * memory context, and free the prior value to avoid memory leakage. We
71  * store transvalues in another set of econtexts, aggstate->aggcontexts
72  * (one per grouping set, see below), which are also used for the hashtable
73  * structures in AGG_HASHED mode. These econtexts are rescanned, not just
74  * reset, at group boundaries so that aggregate transition functions can
75  * register shutdown callbacks via AggRegisterCallback.
76  *
77  * The node's regular econtext (aggstate->ss.ps.ps_ExprContext) is used to
78  * run finalize functions and compute the output tuple; this context can be
79  * reset once per output tuple.
80  *
81  * The executor's AggState node is passed as the fmgr "context" value in
82  * all transfunc and finalfunc calls. It is not recommended that the
83  * transition functions look at the AggState node directly, but they can
84  * use AggCheckCallContext() to verify that they are being called by
85  * nodeAgg.c (and not as ordinary SQL functions). The main reason a
86  * transition function might want to know this is so that it can avoid
87  * palloc'ing a fixed-size pass-by-ref transition value on every call:
88  * it can instead just scribble on and return its left input. Ordinarily
89  * it is completely forbidden for functions to modify pass-by-ref inputs,
90  * but in the aggregate case we know the left input is either the initial
91  * transition value or a previous function result, and in either case its
92  * value need not be preserved. See int8inc() for an example. Notice that
93  * advance_transition_function() is coded to avoid a data copy step when
94  * the previous transition value pointer is returned. It is also possible
95  * to avoid repeated data copying when the transition value is an expanded
96  * object: to do that, the transition function must take care to return
97  * an expanded object that is in a child context of the memory context
98  * returned by AggCheckCallContext(). Also, some transition functions want
99  * to store working state in addition to the nominal transition value; they
100  * can use the memory context returned by AggCheckCallContext() to do that.
101  *
102  * Note: AggCheckCallContext() is available as of PostgreSQL 9.0. The
103  * AggState is available as context in earlier releases (back to 8.1),
104  * but direct examination of the node is needed to use it before 9.0.
105  *
106  * As of 9.4, aggregate transition functions can also use AggGetAggref()
107  * to get hold of the Aggref expression node for their aggregate call.
108  * This is mainly intended for ordered-set aggregates, which are not
109  * supported as window functions. (A regular aggregate function would
110  * need some fallback logic to use this, since there's no Aggref node
111  * for a window function.)
112  *
113  * Grouping sets:
114  *
115  * A list of grouping sets which is structurally equivalent to a ROLLUP
116  * clause (e.g. (a,b,c), (a,b), (a)) can be processed in a single pass over
117  * ordered data. We do this by keeping a separate set of transition values
118  * for each grouping set being concurrently processed; for each input tuple
119  * we update them all, and on group boundaries we reset those states
120  * (starting at the front of the list) whose grouping values have changed
121  * (the list of grouping sets is ordered from most specific to least
122  * specific).
123  *
124  * Where more complex grouping sets are used, we break them down into
125  * "phases", where each phase has a different sort order (except phase 0
126  * which is reserved for hashing). During each phase but the last, the
127  * input tuples are additionally stored in a tuplesort which is keyed to the
128  * next phase's sort order; during each phase but the first, the input
129  * tuples are drawn from the previously sorted data. (The sorting of the
130  * data for the first phase is handled by the planner, as it might be
131  * satisfied by underlying nodes.)
132  *
133  * Hashing can be mixed with sorted grouping. To do this, we have an
134  * AGG_MIXED strategy that populates the hashtables during the first sorted
135  * phase, and switches to reading them out after completing all sort phases.
136  * We can also support AGG_HASHED with multiple hash tables and no sorting
137  * at all.
138  *
139  * From the perspective of aggregate transition and final functions, the
140  * only issue regarding grouping sets is this: a single call site (flinfo)
141  * of an aggregate function may be used for updating several different
142  * transition values in turn. So the function must not cache in the flinfo
143  * anything which logically belongs as part of the transition value (most
144  * importantly, the memory context in which the transition value exists).
145  * The support API functions (AggCheckCallContext, AggRegisterCallback) are
146  * sensitive to the grouping set for which the aggregate function is
147  * currently being called.
148  *
149  * Plan structure:
150  *
151  * What we get from the planner is actually one "real" Agg node which is
152  * part of the plan tree proper, but which optionally has an additional list
153  * of Agg nodes hung off the side via the "chain" field. This is because an
154  * Agg node happens to be a convenient representation of all the data we
155  * need for grouping sets.
156  *
157  * For many purposes, we treat the "real" node as if it were just the first
158  * node in the chain. The chain must be ordered such that hashed entries
159  * come before sorted/plain entries; the real node is marked AGG_MIXED if
160  * there are both types present (in which case the real node describes one
161  * of the hashed groupings, other AGG_HASHED nodes may optionally follow in
162  * the chain, followed in turn by AGG_SORTED or (one) AGG_PLAIN node). If
163  * the real node is marked AGG_HASHED or AGG_SORTED, then all the chained
164  * nodes must be of the same type; if it is AGG_PLAIN, there can be no
165  * chained nodes.
166  *
167  * We collect all hashed nodes into a single "phase", numbered 0, and create
168  * a sorted phase (numbered 1..n) for each AGG_SORTED or AGG_PLAIN node.
169  * Phase 0 is allocated even if there are no hashes, but remains unused in
170  * that case.
171  *
172  * AGG_HASHED nodes actually refer to only a single grouping set each,
173  * because for each hashed grouping we need a separate grpColIdx and
174  * numGroups estimate. AGG_SORTED nodes represent a "rollup", a list of
175  * grouping sets that share a sort order. Each AGG_SORTED node other than
176  * the first one has an associated Sort node which describes the sort order
177  * to be used; the first sorted node takes its input from the outer subtree,
178  * which the planner has already arranged to provide ordered data.
179  *
180  * Memory and ExprContext usage:
181  *
182  * Because we're accumulating aggregate values across input rows, we need to
183  * use more memory contexts than just simple input/output tuple contexts.
184  * In fact, for a rollup, we need a separate context for each grouping set
185  * so that we can reset the inner (finer-grained) aggregates on their group
186  * boundaries while continuing to accumulate values for outer
187  * (coarser-grained) groupings. On top of this, we might be simultaneously
188  * populating hashtables; however, we only need one context for all the
189  * hashtables.
190  *
191  * So we create an array, aggcontexts, with an ExprContext for each grouping
192  * set in the largest rollup that we're going to process, and use the
193  * per-tuple memory context of those ExprContexts to store the aggregate
194  * transition values. hashcontext is the single context created to support
195  * all hash tables.
196  *
197  *
198  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
199  * Portions Copyright (c) 1994, Regents of the University of California
200  *
201  * IDENTIFICATION
202  * src/backend/executor/nodeAgg.c
203  *
204  *-------------------------------------------------------------------------
205  */
206 
207 #include "postgres.h"
208 
209 #include "access/htup_details.h"
210 #include "catalog/objectaccess.h"
211 #include "catalog/pg_aggregate.h"
212 #include "catalog/pg_proc.h"
213 #include "catalog/pg_type.h"
214 #include "executor/executor.h"
215 #include "executor/nodeAgg.h"
216 #include "miscadmin.h"
217 #include "nodes/makefuncs.h"
218 #include "nodes/nodeFuncs.h"
219 #include "optimizer/clauses.h"
220 #include "optimizer/tlist.h"
221 #include "parser/parse_agg.h"
222 #include "parser/parse_coerce.h"
223 #include "utils/acl.h"
224 #include "utils/builtins.h"
225 #include "utils/lsyscache.h"
226 #include "utils/memutils.h"
227 #include "utils/syscache.h"
228 #include "utils/tuplesort.h"
229 #include "utils/datum.h"
230 
231 
232 /*
233  * AggStatePerTransData - per aggregate state value information
234  *
235  * Working state for updating the aggregate's state value, by calling the
236  * transition function with an input row. This struct does not store the
237  * information needed to produce the final aggregate result from the transition
238  * state, that's stored in AggStatePerAggData instead. This separation allows
239  * multiple aggregate results to be produced from a single state value.
240  */
241 typedef struct AggStatePerTransData
242 {
243  /*
244  * These values are set up during ExecInitAgg() and do not change
245  * thereafter:
246  */
247 
248  /*
249  * Link to an Aggref expr this state value is for.
250  *
251  * There can be multiple Aggref's sharing the same state value, so long as
252  * the inputs and transition functions are identical and the final
253  * functions are not read-write. This points to the first one of them.
254  */
256 
257  /*
258  * Is this state value actually being shared by more than one Aggref?
259  */
260  bool aggshared;
261 
262  /*
263  * Number of aggregated input columns. This includes ORDER BY expressions
264  * in both the plain-agg and ordered-set cases. Ordered-set direct args
265  * are not counted, though.
266  */
268 
269  /*
270  * Number of aggregated input columns to pass to the transfn. This
271  * includes the ORDER BY columns for ordered-set aggs, but not for plain
272  * aggs. (This doesn't count the transition state value!)
273  */
275 
276  /*
277  * At each input row, we perform a single ExecProject call to evaluate all
278  * argument expressions that will certainly be needed at this row; that
279  * includes this aggregate's filter expression if it has one, or its
280  * regular argument expressions (including any ORDER BY columns) if it
281  * doesn't. inputoff is the starting index of this aggregate's required
282  * expressions in the resulting tuple.
283  */
284  int inputoff;
285 
286  /* Oid of the state transition or combine function */
288 
289  /* Oid of the serialization function or InvalidOid */
291 
292  /* Oid of the deserialization function or InvalidOid */
294 
295  /* Oid of state value's datatype */
297 
298  /*
299  * fmgr lookup data for transition function or combine function. Note in
300  * particular that the fn_strict flag is kept here.
301  */
303 
304  /* fmgr lookup data for serialization function */
306 
307  /* fmgr lookup data for deserialization function */
309 
310  /* Input collation derived for aggregate */
312 
313  /* number of sorting columns */
315 
316  /* number of sorting columns to consider in DISTINCT comparisons */
317  /* (this is either zero or the same as numSortCols) */
319 
320  /* deconstructed sorting information (arrays of length numSortCols) */
325 
326  /*
327  * fmgr lookup data for input columns' equality operators --- only
328  * set/used when aggregate has DISTINCT flag. Note that these are in
329  * order of sort column index, not parameter index.
330  */
331  FmgrInfo *equalfns; /* array of length numDistinctCols */
332 
333  /*
334  * initial value from pg_aggregate entry
335  */
338 
339  /*
340  * We need the len and byval info for the agg's input and transition data
341  * types in order to know how to copy/delete values.
342  *
343  * Note that the info for the input type is used only when handling
344  * DISTINCT aggs with just one argument, so there is only one input type.
345  */
347  transtypeLen;
350 
351  /*
352  * Stuff for evaluation of aggregate inputs, when they must be evaluated
353  * separately because there's a FILTER expression. In such cases we will
354  * create a sortslot and the result will be stored there, whether or not
355  * we're actually sorting.
356  */
357  ProjectionInfo *evalproj; /* projection machinery */
358 
359  /*
360  * Slots for holding the evaluated input arguments. These are set up
361  * during ExecInitAgg() and then used for each input row requiring either
362  * FILTER or ORDER BY/DISTINCT processing.
363  */
364  TupleTableSlot *sortslot; /* current input tuple */
365  TupleTableSlot *uniqslot; /* used for multi-column DISTINCT */
366  TupleDesc sortdesc; /* descriptor of input tuples */
367 
368  /*
369  * These values are working state that is initialized at the start of an
370  * input tuple group and updated for each input tuple.
371  *
372  * For a simple (non DISTINCT/ORDER BY) aggregate, we just feed the input
373  * values straight to the transition function. If it's DISTINCT or
374  * requires ORDER BY, we pass the input values into a Tuplesort object;
375  * then at completion of the input tuple group, we scan the sorted values,
376  * eliminate duplicates if needed, and run the transition function on the
377  * rest.
378  *
379  * We need a separate tuplesort for each grouping set.
380  */
381 
382  Tuplesortstate **sortstates; /* sort objects, if DISTINCT or ORDER BY */
383 
384  /*
385  * This field is a pre-initialized FunctionCallInfo struct used for
386  * calling this aggregate's transfn. We save a few cycles per row by not
387  * re-initializing the unchanging fields; which isn't much, but it seems
388  * worth the extra space consumption.
389  */
391 
392  /* Likewise for serialization and deserialization functions */
394 
397 
398 /*
399  * AggStatePerAggData - per-aggregate information
400  *
401  * This contains the information needed to call the final function, to produce
402  * a final aggregate result from the state value. If there are multiple
403  * identical Aggrefs in the query, they can all share the same per-agg data.
404  *
405  * These values are set up during ExecInitAgg() and do not change thereafter.
406  */
407 typedef struct AggStatePerAggData
408 {
409  /*
410  * Link to an Aggref expr this state value is for.
411  *
412  * There can be multiple identical Aggref's sharing the same per-agg. This
413  * points to the first one of them.
414  */
416 
417  /* index to the state value which this agg should use */
418  int transno;
419 
420  /* Optional Oid of final function (may be InvalidOid) */
422 
423  /*
424  * fmgr lookup data for final function --- only valid when finalfn_oid is
425  * not InvalidOid.
426  */
428 
429  /*
430  * Number of arguments to pass to the finalfn. This is always at least 1
431  * (the transition state value) plus any ordered-set direct args. If the
432  * finalfn wants extra args then we pass nulls corresponding to the
433  * aggregated input columns.
434  */
436 
437  /* ExprStates for any direct-argument expressions */
439 
440  /*
441  * We need the len and byval info for the agg's result data type in order
442  * to know how to copy/delete values.
443  */
446 
447  /*
448  * "sharable" is false if this agg cannot share state values with other
449  * aggregates because the final function is read-write.
450  */
451  bool sharable;
453 
454 /*
455  * AggStatePerGroupData - per-aggregate-per-group working state
456  *
457  * These values are working state that is initialized at the start of
458  * an input tuple group and updated for each input tuple.
459  *
460  * In AGG_PLAIN and AGG_SORTED modes, we have a single array of these
461  * structs (pointed to by aggstate->pergroup); we re-use the array for
462  * each input group, if it's AGG_SORTED mode. In AGG_HASHED mode, the
463  * hash table contains an array of these structs for each tuple group.
464  *
465  * Logically, the sortstate field belongs in this struct, but we do not
466  * keep it here for space reasons: we don't support DISTINCT aggregates
467  * in AGG_HASHED mode, so there's no reason to use up a pointer field
468  * in every entry of the hashtable.
469  */
470 typedef struct AggStatePerGroupData
471 {
472  Datum transValue; /* current transition value */
474 
475  bool noTransValue; /* true if transValue not set yet */
476 
477  /*
478  * Note: noTransValue initially has the same value as transValueIsNull,
479  * and if true both are cleared to false at the same time. They are not
480  * the same though: if transfn later returns a NULL, we want to keep that
481  * NULL and not auto-replace it with a later input value. Only the first
482  * non-NULL input will be auto-substituted.
483  */
485 
486 /*
487  * AggStatePerPhaseData - per-grouping-set-phase state
488  *
489  * Grouping sets are divided into "phases", where a single phase can be
490  * processed in one pass over the input. If there is more than one phase, then
491  * at the end of input from the current phase, state is reset and another pass
492  * taken over the data which has been re-sorted in the mean time.
493  *
494  * Accordingly, each phase specifies a list of grouping sets and group clause
495  * information, plus each phase after the first also has a sort order.
496  */
497 typedef struct AggStatePerPhaseData
498 {
499  AggStrategy aggstrategy; /* strategy for this phase */
500  int numsets; /* number of grouping sets (or 0) */
501  int *gset_lengths; /* lengths of grouping sets */
502  Bitmapset **grouped_cols; /* column groupings for rollup */
503  FmgrInfo *eqfunctions; /* per-grouping-field equality fns */
504  Agg *aggnode; /* Agg node for phase data */
505  Sort *sortnode; /* Sort node for input ordering for phase */
507 
508 /*
509  * AggStatePerHashData - per-hashtable state
510  *
511  * When doing grouping sets with hashing, we have one of these for each
512  * grouping set. (When doing hashing without grouping sets, we have just one of
513  * them.)
514  */
515 typedef struct AggStatePerHashData
516 {
517  TupleHashTable hashtable; /* hash table with one entry per group */
518  TupleHashIterator hashiter; /* for iterating through hash table */
519  TupleTableSlot *hashslot; /* slot for loading hash table */
520  FmgrInfo *hashfunctions; /* per-grouping-field hash fns */
521  FmgrInfo *eqfunctions; /* per-grouping-field equality fns */
522  int numCols; /* number of hash key columns */
523  int numhashGrpCols; /* number of columns in hash table */
524  int largestGrpColIdx; /* largest col required for hashing */
525  AttrNumber *hashGrpColIdxInput; /* hash col indices in input slot */
526  AttrNumber *hashGrpColIdxHash; /* indices in hashtbl tuples */
527  Agg *aggnode; /* original Agg node, for numGroups etc. */
529 
530 
531 static void select_current_set(AggState *aggstate, int setno, bool is_hash);
532 static void initialize_phase(AggState *aggstate, int newphase);
533 static TupleTableSlot *fetch_input_tuple(AggState *aggstate);
534 static void initialize_aggregates(AggState *aggstate,
535  AggStatePerGroup pergroup,
536  int numReset);
537 static void advance_transition_function(AggState *aggstate,
538  AggStatePerTrans pertrans,
539  AggStatePerGroup pergroupstate);
540 static void advance_aggregates(AggState *aggstate, AggStatePerGroup pergroup,
541  AggStatePerGroup *pergroups);
542 static void advance_combine_function(AggState *aggstate,
543  AggStatePerTrans pertrans,
544  AggStatePerGroup pergroupstate);
545 static void combine_aggregates(AggState *aggstate, AggStatePerGroup pergroup);
546 static void process_ordered_aggregate_single(AggState *aggstate,
547  AggStatePerTrans pertrans,
548  AggStatePerGroup pergroupstate);
549 static void process_ordered_aggregate_multi(AggState *aggstate,
550  AggStatePerTrans pertrans,
551  AggStatePerGroup pergroupstate);
552 static void finalize_aggregate(AggState *aggstate,
553  AggStatePerAgg peragg,
554  AggStatePerGroup pergroupstate,
555  Datum *resultVal, bool *resultIsNull);
556 static void finalize_partialaggregate(AggState *aggstate,
557  AggStatePerAgg peragg,
558  AggStatePerGroup pergroupstate,
559  Datum *resultVal, bool *resultIsNull);
560 static void prepare_projection_slot(AggState *aggstate,
561  TupleTableSlot *slot,
562  int currentSet);
563 static void finalize_aggregates(AggState *aggstate,
564  AggStatePerAgg peragg,
565  AggStatePerGroup pergroup);
566 static TupleTableSlot *project_aggregates(AggState *aggstate);
567 static Bitmapset *find_unaggregated_cols(AggState *aggstate);
568 static bool find_unaggregated_cols_walker(Node *node, Bitmapset **colnos);
569 static void build_hash_table(AggState *aggstate);
572 static TupleTableSlot *agg_retrieve_direct(AggState *aggstate);
573 static void agg_fill_hash_table(AggState *aggstate);
575 static Datum GetAggInitVal(Datum textInitVal, Oid transtype);
576 static void build_pertrans_for_aggref(AggStatePerTrans pertrans,
577  AggState *aggstate, EState *estate,
578  Aggref *aggref, Oid aggtransfn, Oid aggtranstype,
579  Oid aggserialfn, Oid aggdeserialfn,
581  Oid *inputTypes, int numArguments);
582 static int find_compatible_peragg(Aggref *newagg, AggState *aggstate,
583  int lastaggno, List **same_input_transnos);
584 static int find_compatible_pertrans(AggState *aggstate, Aggref *newagg,
585  bool sharable,
586  Oid aggtransfn, Oid aggtranstype,
587  Oid aggserialfn, Oid aggdeserialfn,
589  List *transnos);
590 
591 
592 /*
593  * Select the current grouping set; affects current_set and
594  * curaggcontext.
595  */
596 static void
597 select_current_set(AggState *aggstate, int setno, bool is_hash)
598 {
599  if (is_hash)
600  aggstate->curaggcontext = aggstate->hashcontext;
601  else
602  aggstate->curaggcontext = aggstate->aggcontexts[setno];
603 
604  aggstate->current_set = setno;
605 }
606 
607 /*
608  * Switch to phase "newphase", which must either be 0 or 1 (to reset) or
609  * current_phase + 1. Juggle the tuplesorts accordingly.
610  *
611  * Phase 0 is for hashing, which we currently handle last in the AGG_MIXED
612  * case, so when entering phase 0, all we need to do is drop open sorts.
613  */
614 static void
615 initialize_phase(AggState *aggstate, int newphase)
616 {
617  Assert(newphase <= 1 || newphase == aggstate->current_phase + 1);
618 
619  /*
620  * Whatever the previous state, we're now done with whatever input
621  * tuplesort was in use.
622  */
623  if (aggstate->sort_in)
624  {
625  tuplesort_end(aggstate->sort_in);
626  aggstate->sort_in = NULL;
627  }
628 
629  if (newphase <= 1)
630  {
631  /*
632  * Discard any existing output tuplesort.
633  */
634  if (aggstate->sort_out)
635  {
636  tuplesort_end(aggstate->sort_out);
637  aggstate->sort_out = NULL;
638  }
639  }
640  else
641  {
642  /*
643  * The old output tuplesort becomes the new input one, and this is the
644  * right time to actually sort it.
645  */
646  aggstate->sort_in = aggstate->sort_out;
647  aggstate->sort_out = NULL;
648  Assert(aggstate->sort_in);
649  tuplesort_performsort(aggstate->sort_in);
650  }
651 
652  /*
653  * If this isn't the last phase, we need to sort appropriately for the
654  * next phase in sequence.
655  */
656  if (newphase > 0 && newphase < aggstate->numphases - 1)
657  {
658  Sort *sortnode = aggstate->phases[newphase + 1].sortnode;
659  PlanState *outerNode = outerPlanState(aggstate);
660  TupleDesc tupDesc = ExecGetResultType(outerNode);
661 
662  aggstate->sort_out = tuplesort_begin_heap(tupDesc,
663  sortnode->numCols,
664  sortnode->sortColIdx,
665  sortnode->sortOperators,
666  sortnode->collations,
667  sortnode->nullsFirst,
668  work_mem,
669  false);
670  }
671 
672  aggstate->current_phase = newphase;
673  aggstate->phase = &aggstate->phases[newphase];
674 }
675 
676 /*
677  * Fetch a tuple from either the outer plan (for phase 1) or from the sorter
678  * populated by the previous phase. Copy it to the sorter for the next phase
679  * if any.
680  *
681  * Callers cannot rely on memory for tuple in returned slot remaining valid
682  * past any subsequently fetched tuple.
683  */
684 static TupleTableSlot *
686 {
687  TupleTableSlot *slot;
688 
689  if (aggstate->sort_in)
690  {
691  /* make sure we check for interrupts in either path through here */
693  if (!tuplesort_gettupleslot(aggstate->sort_in, true, false,
694  aggstate->sort_slot, NULL))
695  return NULL;
696  slot = aggstate->sort_slot;
697  }
698  else
699  slot = ExecProcNode(outerPlanState(aggstate));
700 
701  if (!TupIsNull(slot) && aggstate->sort_out)
702  tuplesort_puttupleslot(aggstate->sort_out, slot);
703 
704  return slot;
705 }
706 
707 /*
708  * (Re)Initialize an individual aggregate.
709  *
710  * This function handles only one grouping set, already set in
711  * aggstate->current_set.
712  *
713  * When called, CurrentMemoryContext should be the per-query context.
714  */
715 static void
717  AggStatePerGroup pergroupstate)
718 {
719  /*
720  * Start a fresh sort operation for each DISTINCT/ORDER BY aggregate.
721  */
722  if (pertrans->numSortCols > 0)
723  {
724  /*
725  * In case of rescan, maybe there could be an uncompleted sort
726  * operation? Clean it up if so.
727  */
728  if (pertrans->sortstates[aggstate->current_set])
729  tuplesort_end(pertrans->sortstates[aggstate->current_set]);
730 
731 
732  /*
733  * We use a plain Datum sorter when there's a single input column;
734  * otherwise sort the full tuple. (See comments for
735  * process_ordered_aggregate_single.)
736  */
737  if (pertrans->numInputs == 1)
738  {
739  Form_pg_attribute attr = TupleDescAttr(pertrans->sortdesc, 0);
740 
741  pertrans->sortstates[aggstate->current_set] =
742  tuplesort_begin_datum(attr->atttypid,
743  pertrans->sortOperators[0],
744  pertrans->sortCollations[0],
745  pertrans->sortNullsFirst[0],
746  work_mem, false);
747  }
748  else
749  pertrans->sortstates[aggstate->current_set] =
750  tuplesort_begin_heap(pertrans->sortdesc,
751  pertrans->numSortCols,
752  pertrans->sortColIdx,
753  pertrans->sortOperators,
754  pertrans->sortCollations,
755  pertrans->sortNullsFirst,
756  work_mem, false);
757  }
758 
759  /*
760  * (Re)set transValue to the initial value.
761  *
762  * Note that when the initial value is pass-by-ref, we must copy it (into
763  * the aggcontext) since we will pfree the transValue later.
764  */
765  if (pertrans->initValueIsNull)
766  pergroupstate->transValue = pertrans->initValue;
767  else
768  {
769  MemoryContext oldContext;
770 
771  oldContext = MemoryContextSwitchTo(
773  pergroupstate->transValue = datumCopy(pertrans->initValue,
774  pertrans->transtypeByVal,
775  pertrans->transtypeLen);
776  MemoryContextSwitchTo(oldContext);
777  }
778  pergroupstate->transValueIsNull = pertrans->initValueIsNull;
779 
780  /*
781  * If the initial value for the transition state doesn't exist in the
782  * pg_aggregate table then we will let the first non-NULL value returned
783  * from the outer procNode become the initial value. (This is useful for
784  * aggregates like max() and min().) The noTransValue flag signals that we
785  * still need to do this.
786  */
787  pergroupstate->noTransValue = pertrans->initValueIsNull;
788 }
789 
790 /*
791  * Initialize all aggregate transition states for a new group of input values.
792  *
793  * If there are multiple grouping sets, we initialize only the first numReset
794  * of them (the grouping sets are ordered so that the most specific one, which
795  * is reset most often, is first). As a convenience, if numReset is 0, we
796  * reinitialize all sets. numReset is -1 to initialize a hashtable entry, in
797  * which case the caller must have used select_current_set appropriately.
798  *
799  * When called, CurrentMemoryContext should be the per-query context.
800  */
801 static void
803  AggStatePerGroup pergroup,
804  int numReset)
805 {
806  int transno;
807  int numGroupingSets = Max(aggstate->phase->numsets, 1);
808  int setno = 0;
809  int numTrans = aggstate->numtrans;
810  AggStatePerTrans transstates = aggstate->pertrans;
811 
812  if (numReset == 0)
813  numReset = numGroupingSets;
814 
815  for (transno = 0; transno < numTrans; transno++)
816  {
817  AggStatePerTrans pertrans = &transstates[transno];
818 
819  if (numReset < 0)
820  {
821  AggStatePerGroup pergroupstate;
822 
823  pergroupstate = &pergroup[transno];
824 
825  initialize_aggregate(aggstate, pertrans, pergroupstate);
826  }
827  else
828  {
829  for (setno = 0; setno < numReset; setno++)
830  {
831  AggStatePerGroup pergroupstate;
832 
833  pergroupstate = &pergroup[transno + (setno * numTrans)];
834 
835  select_current_set(aggstate, setno, false);
836 
837  initialize_aggregate(aggstate, pertrans, pergroupstate);
838  }
839  }
840  }
841 }
842 
843 /*
844  * Given new input value(s), advance the transition function of one aggregate
845  * state within one grouping set only (already set in aggstate->current_set)
846  *
847  * The new values (and null flags) have been preloaded into argument positions
848  * 1 and up in pertrans->transfn_fcinfo, so that we needn't copy them again to
849  * pass to the transition function. We also expect that the static fields of
850  * the fcinfo are already initialized; that was done by ExecInitAgg().
851  *
852  * It doesn't matter which memory context this is called in.
853  */
854 static void
856  AggStatePerTrans pertrans,
857  AggStatePerGroup pergroupstate)
858 {
859  FunctionCallInfo fcinfo = &pertrans->transfn_fcinfo;
860  MemoryContext oldContext;
861  Datum newVal;
862 
863  if (pertrans->transfn.fn_strict)
864  {
865  /*
866  * For a strict transfn, nothing happens when there's a NULL input; we
867  * just keep the prior transValue.
868  */
869  int numTransInputs = pertrans->numTransInputs;
870  int i;
871 
872  for (i = 1; i <= numTransInputs; i++)
873  {
874  if (fcinfo->argnull[i])
875  return;
876  }
877  if (pergroupstate->noTransValue)
878  {
879  /*
880  * transValue has not been initialized. This is the first non-NULL
881  * input value. We use it as the initial value for transValue. (We
882  * already checked that the agg's input type is binary-compatible
883  * with its transtype, so straight copy here is OK.)
884  *
885  * We must copy the datum into aggcontext if it is pass-by-ref. We
886  * do not need to pfree the old transValue, since it's NULL.
887  */
888  oldContext = MemoryContextSwitchTo(
890  pergroupstate->transValue = datumCopy(fcinfo->arg[1],
891  pertrans->transtypeByVal,
892  pertrans->transtypeLen);
893  pergroupstate->transValueIsNull = false;
894  pergroupstate->noTransValue = false;
895  MemoryContextSwitchTo(oldContext);
896  return;
897  }
898  if (pergroupstate->transValueIsNull)
899  {
900  /*
901  * Don't call a strict function with NULL inputs. Note it is
902  * possible to get here despite the above tests, if the transfn is
903  * strict *and* returned a NULL on a prior cycle. If that happens
904  * we will propagate the NULL all the way to the end.
905  */
906  return;
907  }
908  }
909 
910  /* We run the transition functions in per-input-tuple memory context */
911  oldContext = MemoryContextSwitchTo(aggstate->tmpcontext->ecxt_per_tuple_memory);
912 
913  /* set up aggstate->curpertrans for AggGetAggref() */
914  aggstate->curpertrans = pertrans;
915 
916  /*
917  * OK to call the transition function
918  */
919  fcinfo->arg[0] = pergroupstate->transValue;
920  fcinfo->argnull[0] = pergroupstate->transValueIsNull;
921  fcinfo->isnull = false; /* just in case transfn doesn't set it */
922 
923  newVal = FunctionCallInvoke(fcinfo);
924 
925  aggstate->curpertrans = NULL;
926 
927  /*
928  * If pass-by-ref datatype, must copy the new value into aggcontext and
929  * free the prior transValue. But if transfn returned a pointer to its
930  * first input, we don't need to do anything. Also, if transfn returned a
931  * pointer to a R/W expanded object that is already a child of the
932  * aggcontext, assume we can adopt that value without copying it.
933  */
934  if (!pertrans->transtypeByVal &&
935  DatumGetPointer(newVal) != DatumGetPointer(pergroupstate->transValue))
936  {
937  if (!fcinfo->isnull)
938  {
941  false,
942  pertrans->transtypeLen) &&
944  /* do nothing */ ;
945  else
946  newVal = datumCopy(newVal,
947  pertrans->transtypeByVal,
948  pertrans->transtypeLen);
949  }
950  if (!pergroupstate->transValueIsNull)
951  {
952  if (DatumIsReadWriteExpandedObject(pergroupstate->transValue,
953  false,
954  pertrans->transtypeLen))
955  DeleteExpandedObject(pergroupstate->transValue);
956  else
957  pfree(DatumGetPointer(pergroupstate->transValue));
958  }
959  }
960 
961  pergroupstate->transValue = newVal;
962  pergroupstate->transValueIsNull = fcinfo->isnull;
963 
964  MemoryContextSwitchTo(oldContext);
965 }
966 
967 /*
968  * Advance each aggregate transition state for one input tuple. The input
969  * tuple has been stored in tmpcontext->ecxt_outertuple, so that it is
970  * accessible to ExecEvalExpr.
971  *
972  * We have two sets of transition states to handle: one for sorted aggregation
973  * and one for hashed; we do them both here, to avoid multiple evaluation of
974  * the inputs.
975  *
976  * When called, CurrentMemoryContext should be the per-query context.
977  */
978 static void
980 {
981  int transno;
982  int setno = 0;
983  int numGroupingSets = Max(aggstate->phase->numsets, 1);
984  int numHashes = aggstate->num_hashes;
985  int numTrans = aggstate->numtrans;
986  TupleTableSlot *combinedslot;
987 
988  /* compute required inputs for all aggregates */
989  combinedslot = ExecProject(aggstate->combinedproj);
990 
991  for (transno = 0; transno < numTrans; transno++)
992  {
993  AggStatePerTrans pertrans = &aggstate->pertrans[transno];
994  int numTransInputs = pertrans->numTransInputs;
995  int inputoff = pertrans->inputoff;
996  TupleTableSlot *slot;
997  int i;
998 
999  /* Skip anything FILTERed out */
1000  if (pertrans->aggref->aggfilter)
1001  {
1002  /* Check the result of the filter expression */
1003  if (combinedslot->tts_isnull[inputoff] ||
1004  !DatumGetBool(combinedslot->tts_values[inputoff]))
1005  continue;
1006 
1007  /* Now it's safe to evaluate this agg's arguments */
1008  slot = ExecProject(pertrans->evalproj);
1009  /* There's no offset needed in this slot, of course */
1010  inputoff = 0;
1011  }
1012  else
1013  {
1014  /* arguments are already evaluated into combinedslot @ inputoff */
1015  slot = combinedslot;
1016  }
1017 
1018  if (pertrans->numSortCols > 0)
1019  {
1020  /* DISTINCT and/or ORDER BY case */
1021  Assert(slot->tts_nvalid >= (pertrans->numInputs + inputoff));
1022  Assert(!pergroups);
1023 
1024  /*
1025  * If the transfn is strict, we want to check for nullity before
1026  * storing the row in the sorter, to save space if there are a lot
1027  * of nulls. Note that we must only check numTransInputs columns,
1028  * not numInputs, since nullity in columns used only for sorting
1029  * is not relevant here.
1030  */
1031  if (pertrans->transfn.fn_strict)
1032  {
1033  for (i = 0; i < numTransInputs; i++)
1034  {
1035  if (slot->tts_isnull[i + inputoff])
1036  break;
1037  }
1038  if (i < numTransInputs)
1039  continue;
1040  }
1041 
1042  for (setno = 0; setno < numGroupingSets; setno++)
1043  {
1044  /* OK, put the tuple into the tuplesort object */
1045  if (pertrans->numInputs == 1)
1046  tuplesort_putdatum(pertrans->sortstates[setno],
1047  slot->tts_values[inputoff],
1048  slot->tts_isnull[inputoff]);
1049  else if (pertrans->aggref->aggfilter)
1050  {
1051  /*
1052  * When filtering and ordering, we already have a slot
1053  * containing just the argument columns.
1054  */
1055  Assert(slot == pertrans->sortslot);
1056  tuplesort_puttupleslot(pertrans->sortstates[setno], slot);
1057  }
1058  else
1059  {
1060  /*
1061  * Copy argument columns from combined slot, starting at
1062  * inputoff, into sortslot, so that we can store just the
1063  * columns we want.
1064  */
1065  ExecClearTuple(pertrans->sortslot);
1066  memcpy(pertrans->sortslot->tts_values,
1067  &slot->tts_values[inputoff],
1068  pertrans->numInputs * sizeof(Datum));
1069  memcpy(pertrans->sortslot->tts_isnull,
1070  &slot->tts_isnull[inputoff],
1071  pertrans->numInputs * sizeof(bool));
1072  ExecStoreVirtualTuple(pertrans->sortslot);
1073  tuplesort_puttupleslot(pertrans->sortstates[setno],
1074  pertrans->sortslot);
1075  }
1076  }
1077  }
1078  else
1079  {
1080  /* We can apply the transition function immediately */
1081  FunctionCallInfo fcinfo = &pertrans->transfn_fcinfo;
1082 
1083  /* Load values into fcinfo */
1084  /* Start from 1, since the 0th arg will be the transition value */
1085  Assert(slot->tts_nvalid >= (numTransInputs + inputoff));
1086 
1087  for (i = 0; i < numTransInputs; i++)
1088  {
1089  fcinfo->arg[i + 1] = slot->tts_values[i + inputoff];
1090  fcinfo->argnull[i + 1] = slot->tts_isnull[i + inputoff];
1091  }
1092 
1093  if (pergroup)
1094  {
1095  /* advance transition states for ordered grouping */
1096 
1097  for (setno = 0; setno < numGroupingSets; setno++)
1098  {
1099  AggStatePerGroup pergroupstate;
1100 
1101  select_current_set(aggstate, setno, false);
1102 
1103  pergroupstate = &pergroup[transno + (setno * numTrans)];
1104 
1105  advance_transition_function(aggstate, pertrans, pergroupstate);
1106  }
1107  }
1108 
1109  if (pergroups)
1110  {
1111  /* advance transition states for hashed grouping */
1112 
1113  for (setno = 0; setno < numHashes; setno++)
1114  {
1115  AggStatePerGroup pergroupstate;
1116 
1117  select_current_set(aggstate, setno, true);
1118 
1119  pergroupstate = &pergroups[setno][transno];
1120 
1121  advance_transition_function(aggstate, pertrans, pergroupstate);
1122  }
1123  }
1124  }
1125  }
1126 }
1127 
1128 /*
1129  * combine_aggregates replaces advance_aggregates in DO_AGGSPLIT_COMBINE
1130  * mode. The principal difference is that here we may need to apply the
1131  * deserialization function before running the transfn (which, in this mode,
1132  * is actually the aggregate's combinefn). Also, we know we don't need to
1133  * handle FILTER, DISTINCT, ORDER BY, or grouping sets.
1134  */
1135 static void
1137 {
1138  int transno;
1139  int numTrans = aggstate->numtrans;
1140  TupleTableSlot *slot;
1141 
1142  /* combine not supported with grouping sets */
1143  Assert(aggstate->phase->numsets <= 1);
1144 
1145  /* compute input for all aggregates */
1146  slot = ExecProject(aggstate->combinedproj);
1147 
1148  for (transno = 0; transno < numTrans; transno++)
1149  {
1150  AggStatePerTrans pertrans = &aggstate->pertrans[transno];
1151  AggStatePerGroup pergroupstate = &pergroup[transno];
1152  FunctionCallInfo fcinfo = &pertrans->transfn_fcinfo;
1153  int inputoff = pertrans->inputoff;
1154 
1155  Assert(slot->tts_nvalid > inputoff);
1156 
1157  /*
1158  * deserialfn_oid will be set if we must deserialize the input state
1159  * before calling the combine function
1160  */
1161  if (OidIsValid(pertrans->deserialfn_oid))
1162  {
1163  /* Don't call a strict deserialization function with NULL input */
1164  if (pertrans->deserialfn.fn_strict && slot->tts_isnull[inputoff])
1165  {
1166  fcinfo->arg[1] = slot->tts_values[inputoff];
1167  fcinfo->argnull[1] = slot->tts_isnull[inputoff];
1168  }
1169  else
1170  {
1171  FunctionCallInfo dsinfo = &pertrans->deserialfn_fcinfo;
1172  MemoryContext oldContext;
1173 
1174  dsinfo->arg[0] = slot->tts_values[inputoff];
1175  dsinfo->argnull[0] = slot->tts_isnull[inputoff];
1176  /* Dummy second argument for type-safety reasons */
1177  dsinfo->arg[1] = PointerGetDatum(NULL);
1178  dsinfo->argnull[1] = false;
1179 
1180  /*
1181  * We run the deserialization functions in per-input-tuple
1182  * memory context.
1183  */
1184  oldContext = MemoryContextSwitchTo(aggstate->tmpcontext->ecxt_per_tuple_memory);
1185 
1186  fcinfo->arg[1] = FunctionCallInvoke(dsinfo);
1187  fcinfo->argnull[1] = dsinfo->isnull;
1188 
1189  MemoryContextSwitchTo(oldContext);
1190  }
1191  }
1192  else
1193  {
1194  fcinfo->arg[1] = slot->tts_values[inputoff];
1195  fcinfo->argnull[1] = slot->tts_isnull[inputoff];
1196  }
1197 
1198  advance_combine_function(aggstate, pertrans, pergroupstate);
1199  }
1200 }
1201 
1202 /*
1203  * Perform combination of states between 2 aggregate states. Effectively this
1204  * 'adds' two states together by whichever logic is defined in the aggregate
1205  * function's combine function.
1206  *
1207  * Note that in this case transfn is set to the combination function. This
1208  * perhaps should be changed to avoid confusion, but one field is ok for now
1209  * as they'll never be needed at the same time.
1210  */
1211 static void
1213  AggStatePerTrans pertrans,
1214  AggStatePerGroup pergroupstate)
1215 {
1216  FunctionCallInfo fcinfo = &pertrans->transfn_fcinfo;
1217  MemoryContext oldContext;
1218  Datum newVal;
1219 
1220  if (pertrans->transfn.fn_strict)
1221  {
1222  /* if we're asked to merge to a NULL state, then do nothing */
1223  if (fcinfo->argnull[1])
1224  return;
1225 
1226  if (pergroupstate->noTransValue)
1227  {
1228  /*
1229  * transValue has not yet been initialized. If pass-by-ref
1230  * datatype we must copy the combining state value into
1231  * aggcontext.
1232  */
1233  if (!pertrans->transtypeByVal)
1234  {
1235  oldContext = MemoryContextSwitchTo(
1237  pergroupstate->transValue = datumCopy(fcinfo->arg[1],
1238  pertrans->transtypeByVal,
1239  pertrans->transtypeLen);
1240  MemoryContextSwitchTo(oldContext);
1241  }
1242  else
1243  pergroupstate->transValue = fcinfo->arg[1];
1244 
1245  pergroupstate->transValueIsNull = false;
1246  pergroupstate->noTransValue = false;
1247  return;
1248  }
1249 
1250  if (pergroupstate->transValueIsNull)
1251  {
1252  /*
1253  * Don't call a strict function with NULL inputs. Note it is
1254  * possible to get here despite the above tests, if the combinefn
1255  * is strict *and* returned a NULL on a prior cycle. If that
1256  * happens we will propagate the NULL all the way to the end.
1257  */
1258  return;
1259  }
1260  }
1261 
1262  /* We run the combine functions in per-input-tuple memory context */
1263  oldContext = MemoryContextSwitchTo(aggstate->tmpcontext->ecxt_per_tuple_memory);
1264 
1265  /* set up aggstate->curpertrans for AggGetAggref() */
1266  aggstate->curpertrans = pertrans;
1267 
1268  /*
1269  * OK to call the combine function
1270  */
1271  fcinfo->arg[0] = pergroupstate->transValue;
1272  fcinfo->argnull[0] = pergroupstate->transValueIsNull;
1273  fcinfo->isnull = false; /* just in case combine func doesn't set it */
1274 
1275  newVal = FunctionCallInvoke(fcinfo);
1276 
1277  aggstate->curpertrans = NULL;
1278 
1279  /*
1280  * If pass-by-ref datatype, must copy the new value into aggcontext and
1281  * free the prior transValue. But if the combine function returned a
1282  * pointer to its first input, we don't need to do anything. Also, if the
1283  * combine function returned a pointer to a R/W expanded object that is
1284  * already a child of the aggcontext, assume we can adopt that value
1285  * without copying it.
1286  */
1287  if (!pertrans->transtypeByVal &&
1288  DatumGetPointer(newVal) != DatumGetPointer(pergroupstate->transValue))
1289  {
1290  if (!fcinfo->isnull)
1291  {
1293  if (DatumIsReadWriteExpandedObject(newVal,
1294  false,
1295  pertrans->transtypeLen) &&
1296  MemoryContextGetParent(DatumGetEOHP(newVal)->eoh_context) == CurrentMemoryContext)
1297  /* do nothing */ ;
1298  else
1299  newVal = datumCopy(newVal,
1300  pertrans->transtypeByVal,
1301  pertrans->transtypeLen);
1302  }
1303  if (!pergroupstate->transValueIsNull)
1304  {
1305  if (DatumIsReadWriteExpandedObject(pergroupstate->transValue,
1306  false,
1307  pertrans->transtypeLen))
1308  DeleteExpandedObject(pergroupstate->transValue);
1309  else
1310  pfree(DatumGetPointer(pergroupstate->transValue));
1311  }
1312  }
1313 
1314  pergroupstate->transValue = newVal;
1315  pergroupstate->transValueIsNull = fcinfo->isnull;
1316 
1317  MemoryContextSwitchTo(oldContext);
1318 }
1319 
1320 
1321 /*
1322  * Run the transition function for a DISTINCT or ORDER BY aggregate
1323  * with only one input. This is called after we have completed
1324  * entering all the input values into the sort object. We complete the
1325  * sort, read out the values in sorted order, and run the transition
1326  * function on each value (applying DISTINCT if appropriate).
1327  *
1328  * Note that the strictness of the transition function was checked when
1329  * entering the values into the sort, so we don't check it again here;
1330  * we just apply standard SQL DISTINCT logic.
1331  *
1332  * The one-input case is handled separately from the multi-input case
1333  * for performance reasons: for single by-value inputs, such as the
1334  * common case of count(distinct id), the tuplesort_getdatum code path
1335  * is around 300% faster. (The speedup for by-reference types is less
1336  * but still noticeable.)
1337  *
1338  * This function handles only one grouping set (already set in
1339  * aggstate->current_set).
1340  *
1341  * When called, CurrentMemoryContext should be the per-query context.
1342  */
1343 static void
1345  AggStatePerTrans pertrans,
1346  AggStatePerGroup pergroupstate)
1347 {
1348  Datum oldVal = (Datum) 0;
1349  bool oldIsNull = true;
1350  bool haveOldVal = false;
1351  MemoryContext workcontext = aggstate->tmpcontext->ecxt_per_tuple_memory;
1352  MemoryContext oldContext;
1353  bool isDistinct = (pertrans->numDistinctCols > 0);
1354  Datum newAbbrevVal = (Datum) 0;
1355  Datum oldAbbrevVal = (Datum) 0;
1356  FunctionCallInfo fcinfo = &pertrans->transfn_fcinfo;
1357  Datum *newVal;
1358  bool *isNull;
1359 
1360  Assert(pertrans->numDistinctCols < 2);
1361 
1362  tuplesort_performsort(pertrans->sortstates[aggstate->current_set]);
1363 
1364  /* Load the column into argument 1 (arg 0 will be transition value) */
1365  newVal = fcinfo->arg + 1;
1366  isNull = fcinfo->argnull + 1;
1367 
1368  /*
1369  * Note: if input type is pass-by-ref, the datums returned by the sort are
1370  * freshly palloc'd in the per-query context, so we must be careful to
1371  * pfree them when they are no longer needed.
1372  */
1373 
1374  while (tuplesort_getdatum(pertrans->sortstates[aggstate->current_set],
1375  true, newVal, isNull, &newAbbrevVal))
1376  {
1377  /*
1378  * Clear and select the working context for evaluation of the equality
1379  * function and transition function.
1380  */
1381  MemoryContextReset(workcontext);
1382  oldContext = MemoryContextSwitchTo(workcontext);
1383 
1384  /*
1385  * If DISTINCT mode, and not distinct from prior, skip it.
1386  *
1387  * Note: we assume equality functions don't care about collation.
1388  */
1389  if (isDistinct &&
1390  haveOldVal &&
1391  ((oldIsNull && *isNull) ||
1392  (!oldIsNull && !*isNull &&
1393  oldAbbrevVal == newAbbrevVal &&
1394  DatumGetBool(FunctionCall2(&pertrans->equalfns[0],
1395  oldVal, *newVal)))))
1396  {
1397  /* equal to prior, so forget this one */
1398  if (!pertrans->inputtypeByVal && !*isNull)
1399  pfree(DatumGetPointer(*newVal));
1400  }
1401  else
1402  {
1403  advance_transition_function(aggstate, pertrans, pergroupstate);
1404  /* forget the old value, if any */
1405  if (!oldIsNull && !pertrans->inputtypeByVal)
1406  pfree(DatumGetPointer(oldVal));
1407  /* and remember the new one for subsequent equality checks */
1408  oldVal = *newVal;
1409  oldAbbrevVal = newAbbrevVal;
1410  oldIsNull = *isNull;
1411  haveOldVal = true;
1412  }
1413 
1414  MemoryContextSwitchTo(oldContext);
1415  }
1416 
1417  if (!oldIsNull && !pertrans->inputtypeByVal)
1418  pfree(DatumGetPointer(oldVal));
1419 
1420  tuplesort_end(pertrans->sortstates[aggstate->current_set]);
1421  pertrans->sortstates[aggstate->current_set] = NULL;
1422 }
1423 
1424 /*
1425  * Run the transition function for a DISTINCT or ORDER BY aggregate
1426  * with more than one input. This is called after we have completed
1427  * entering all the input values into the sort object. We complete the
1428  * sort, read out the values in sorted order, and run the transition
1429  * function on each value (applying DISTINCT if appropriate).
1430  *
1431  * This function handles only one grouping set (already set in
1432  * aggstate->current_set).
1433  *
1434  * When called, CurrentMemoryContext should be the per-query context.
1435  */
1436 static void
1438  AggStatePerTrans pertrans,
1439  AggStatePerGroup pergroupstate)
1440 {
1441  MemoryContext workcontext = aggstate->tmpcontext->ecxt_per_tuple_memory;
1442  FunctionCallInfo fcinfo = &pertrans->transfn_fcinfo;
1443  TupleTableSlot *slot1 = pertrans->sortslot;
1444  TupleTableSlot *slot2 = pertrans->uniqslot;
1445  int numTransInputs = pertrans->numTransInputs;
1446  int numDistinctCols = pertrans->numDistinctCols;
1447  Datum newAbbrevVal = (Datum) 0;
1448  Datum oldAbbrevVal = (Datum) 0;
1449  bool haveOldValue = false;
1450  int i;
1451 
1452  tuplesort_performsort(pertrans->sortstates[aggstate->current_set]);
1453 
1454  ExecClearTuple(slot1);
1455  if (slot2)
1456  ExecClearTuple(slot2);
1457 
1458  while (tuplesort_gettupleslot(pertrans->sortstates[aggstate->current_set],
1459  true, true, slot1, &newAbbrevVal))
1460  {
1462 
1463  /*
1464  * Extract the first numTransInputs columns as datums to pass to the
1465  * transfn. (This will help execTuplesMatch too, so we do it
1466  * immediately.)
1467  */
1468  slot_getsomeattrs(slot1, numTransInputs);
1469 
1470  if (numDistinctCols == 0 ||
1471  !haveOldValue ||
1472  newAbbrevVal != oldAbbrevVal ||
1473  !execTuplesMatch(slot1, slot2,
1474  numDistinctCols,
1475  pertrans->sortColIdx,
1476  pertrans->equalfns,
1477  workcontext))
1478  {
1479  /* Load values into fcinfo */
1480  /* Start from 1, since the 0th arg will be the transition value */
1481  for (i = 0; i < numTransInputs; i++)
1482  {
1483  fcinfo->arg[i + 1] = slot1->tts_values[i];
1484  fcinfo->argnull[i + 1] = slot1->tts_isnull[i];
1485  }
1486 
1487  advance_transition_function(aggstate, pertrans, pergroupstate);
1488 
1489  if (numDistinctCols > 0)
1490  {
1491  /* swap the slot pointers to retain the current tuple */
1492  TupleTableSlot *tmpslot = slot2;
1493 
1494  slot2 = slot1;
1495  slot1 = tmpslot;
1496  /* avoid execTuplesMatch() calls by reusing abbreviated keys */
1497  oldAbbrevVal = newAbbrevVal;
1498  haveOldValue = true;
1499  }
1500  }
1501 
1502  /* Reset context each time, unless execTuplesMatch did it for us */
1503  if (numDistinctCols == 0)
1504  MemoryContextReset(workcontext);
1505 
1506  ExecClearTuple(slot1);
1507  }
1508 
1509  if (slot2)
1510  ExecClearTuple(slot2);
1511 
1512  tuplesort_end(pertrans->sortstates[aggstate->current_set]);
1513  pertrans->sortstates[aggstate->current_set] = NULL;
1514 }
1515 
1516 /*
1517  * Compute the final value of one aggregate.
1518  *
1519  * This function handles only one grouping set (already set in
1520  * aggstate->current_set).
1521  *
1522  * The finalfunction will be run, and the result delivered, in the
1523  * output-tuple context; caller's CurrentMemoryContext does not matter.
1524  *
1525  * The finalfn uses the state as set in the transno. This also might be
1526  * being used by another aggregate function, so it's important that we do
1527  * nothing destructive here.
1528  */
1529 static void
1531  AggStatePerAgg peragg,
1532  AggStatePerGroup pergroupstate,
1533  Datum *resultVal, bool *resultIsNull)
1534 {
1535  FunctionCallInfoData fcinfo;
1536  bool anynull = false;
1537  MemoryContext oldContext;
1538  int i;
1539  ListCell *lc;
1540  AggStatePerTrans pertrans = &aggstate->pertrans[peragg->transno];
1541 
1543 
1544  /*
1545  * Evaluate any direct arguments. We do this even if there's no finalfn
1546  * (which is unlikely anyway), so that side-effects happen as expected.
1547  * The direct arguments go into arg positions 1 and up, leaving position 0
1548  * for the transition state value.
1549  */
1550  i = 1;
1551  foreach(lc, peragg->aggdirectargs)
1552  {
1553  ExprState *expr = (ExprState *) lfirst(lc);
1554 
1555  fcinfo.arg[i] = ExecEvalExpr(expr,
1556  aggstate->ss.ps.ps_ExprContext,
1557  &fcinfo.argnull[i]);
1558  anynull |= fcinfo.argnull[i];
1559  i++;
1560  }
1561 
1562  /*
1563  * Apply the agg's finalfn if one is provided, else return transValue.
1564  */
1565  if (OidIsValid(peragg->finalfn_oid))
1566  {
1567  int numFinalArgs = peragg->numFinalArgs;
1568 
1569  /* set up aggstate->curperagg for AggGetAggref() */
1570  aggstate->curperagg = peragg;
1571 
1572  InitFunctionCallInfoData(fcinfo, &peragg->finalfn,
1573  numFinalArgs,
1574  pertrans->aggCollation,
1575  (void *) aggstate, NULL);
1576 
1577  /* Fill in the transition state value */
1578  fcinfo.arg[0] = MakeExpandedObjectReadOnly(pergroupstate->transValue,
1579  pergroupstate->transValueIsNull,
1580  pertrans->transtypeLen);
1581  fcinfo.argnull[0] = pergroupstate->transValueIsNull;
1582  anynull |= pergroupstate->transValueIsNull;
1583 
1584  /* Fill any remaining argument positions with nulls */
1585  for (; i < numFinalArgs; i++)
1586  {
1587  fcinfo.arg[i] = (Datum) 0;
1588  fcinfo.argnull[i] = true;
1589  anynull = true;
1590  }
1591 
1592  if (fcinfo.flinfo->fn_strict && anynull)
1593  {
1594  /* don't call a strict function with NULL inputs */
1595  *resultVal = (Datum) 0;
1596  *resultIsNull = true;
1597  }
1598  else
1599  {
1600  *resultVal = FunctionCallInvoke(&fcinfo);
1601  *resultIsNull = fcinfo.isnull;
1602  }
1603  aggstate->curperagg = NULL;
1604  }
1605  else
1606  {
1607  /* Don't need MakeExpandedObjectReadOnly; datumCopy will copy it */
1608  *resultVal = pergroupstate->transValue;
1609  *resultIsNull = pergroupstate->transValueIsNull;
1610  }
1611 
1612  /*
1613  * If result is pass-by-ref, make sure it is in the right context.
1614  */
1615  if (!peragg->resulttypeByVal && !*resultIsNull &&
1617  DatumGetPointer(*resultVal)))
1618  *resultVal = datumCopy(*resultVal,
1619  peragg->resulttypeByVal,
1620  peragg->resulttypeLen);
1621 
1622  MemoryContextSwitchTo(oldContext);
1623 }
1624 
1625 /*
1626  * Compute the output value of one partial aggregate.
1627  *
1628  * The serialization function will be run, and the result delivered, in the
1629  * output-tuple context; caller's CurrentMemoryContext does not matter.
1630  */
1631 static void
1633  AggStatePerAgg peragg,
1634  AggStatePerGroup pergroupstate,
1635  Datum *resultVal, bool *resultIsNull)
1636 {
1637  AggStatePerTrans pertrans = &aggstate->pertrans[peragg->transno];
1638  MemoryContext oldContext;
1639 
1641 
1642  /*
1643  * serialfn_oid will be set if we must serialize the transvalue before
1644  * returning it
1645  */
1646  if (OidIsValid(pertrans->serialfn_oid))
1647  {
1648  /* Don't call a strict serialization function with NULL input. */
1649  if (pertrans->serialfn.fn_strict && pergroupstate->transValueIsNull)
1650  {
1651  *resultVal = (Datum) 0;
1652  *resultIsNull = true;
1653  }
1654  else
1655  {
1656  FunctionCallInfo fcinfo = &pertrans->serialfn_fcinfo;
1657 
1658  fcinfo->arg[0] = MakeExpandedObjectReadOnly(pergroupstate->transValue,
1659  pergroupstate->transValueIsNull,
1660  pertrans->transtypeLen);
1661  fcinfo->argnull[0] = pergroupstate->transValueIsNull;
1662 
1663  *resultVal = FunctionCallInvoke(fcinfo);
1664  *resultIsNull = fcinfo->isnull;
1665  }
1666  }
1667  else
1668  {
1669  /* Don't need MakeExpandedObjectReadOnly; datumCopy will copy it */
1670  *resultVal = pergroupstate->transValue;
1671  *resultIsNull = pergroupstate->transValueIsNull;
1672  }
1673 
1674  /* If result is pass-by-ref, make sure it is in the right context. */
1675  if (!peragg->resulttypeByVal && !*resultIsNull &&
1677  DatumGetPointer(*resultVal)))
1678  *resultVal = datumCopy(*resultVal,
1679  peragg->resulttypeByVal,
1680  peragg->resulttypeLen);
1681 
1682  MemoryContextSwitchTo(oldContext);
1683 }
1684 
1685 /*
1686  * Prepare to finalize and project based on the specified representative tuple
1687  * slot and grouping set.
1688  *
1689  * In the specified tuple slot, force to null all attributes that should be
1690  * read as null in the context of the current grouping set. Also stash the
1691  * current group bitmap where GroupingExpr can get at it.
1692  *
1693  * This relies on three conditions:
1694  *
1695  * 1) Nothing is ever going to try and extract the whole tuple from this slot,
1696  * only reference it in evaluations, which will only access individual
1697  * attributes.
1698  *
1699  * 2) No system columns are going to need to be nulled. (If a system column is
1700  * referenced in a group clause, it is actually projected in the outer plan
1701  * tlist.)
1702  *
1703  * 3) Within a given phase, we never need to recover the value of an attribute
1704  * once it has been set to null.
1705  *
1706  * Poking into the slot this way is a bit ugly, but the consensus is that the
1707  * alternative was worse.
1708  */
1709 static void
1710 prepare_projection_slot(AggState *aggstate, TupleTableSlot *slot, int currentSet)
1711 {
1712  if (aggstate->phase->grouped_cols)
1713  {
1714  Bitmapset *grouped_cols = aggstate->phase->grouped_cols[currentSet];
1715 
1716  aggstate->grouped_cols = grouped_cols;
1717 
1718  if (slot->tts_isempty)
1719  {
1720  /*
1721  * Force all values to be NULL if working on an empty input tuple
1722  * (i.e. an empty grouping set for which no input rows were
1723  * supplied).
1724  */
1725  ExecStoreAllNullTuple(slot);
1726  }
1727  else if (aggstate->all_grouped_cols)
1728  {
1729  ListCell *lc;
1730 
1731  /* all_grouped_cols is arranged in desc order */
1733 
1734  foreach(lc, aggstate->all_grouped_cols)
1735  {
1736  int attnum = lfirst_int(lc);
1737 
1738  if (!bms_is_member(attnum, grouped_cols))
1739  slot->tts_isnull[attnum - 1] = true;
1740  }
1741  }
1742  }
1743 }
1744 
1745 /*
1746  * Compute the final value of all aggregates for one group.
1747  *
1748  * This function handles only one grouping set at a time, which the caller must
1749  * have selected. It's also the caller's responsibility to adjust the supplied
1750  * pergroup parameter to point to the current set's transvalues.
1751  *
1752  * Results are stored in the output econtext aggvalues/aggnulls.
1753  */
1754 static void
1756  AggStatePerAgg peraggs,
1757  AggStatePerGroup pergroup)
1758 {
1759  ExprContext *econtext = aggstate->ss.ps.ps_ExprContext;
1760  Datum *aggvalues = econtext->ecxt_aggvalues;
1761  bool *aggnulls = econtext->ecxt_aggnulls;
1762  int aggno;
1763  int transno;
1764 
1765  /*
1766  * If there were any DISTINCT and/or ORDER BY aggregates, sort their
1767  * inputs and run the transition functions.
1768  */
1769  for (transno = 0; transno < aggstate->numtrans; transno++)
1770  {
1771  AggStatePerTrans pertrans = &aggstate->pertrans[transno];
1772  AggStatePerGroup pergroupstate;
1773 
1774  pergroupstate = &pergroup[transno];
1775 
1776  if (pertrans->numSortCols > 0)
1777  {
1778  Assert(aggstate->aggstrategy != AGG_HASHED &&
1779  aggstate->aggstrategy != AGG_MIXED);
1780 
1781  if (pertrans->numInputs == 1)
1783  pertrans,
1784  pergroupstate);
1785  else
1787  pertrans,
1788  pergroupstate);
1789  }
1790  }
1791 
1792  /*
1793  * Run the final functions.
1794  */
1795  for (aggno = 0; aggno < aggstate->numaggs; aggno++)
1796  {
1797  AggStatePerAgg peragg = &peraggs[aggno];
1798  int transno = peragg->transno;
1799  AggStatePerGroup pergroupstate;
1800 
1801  pergroupstate = &pergroup[transno];
1802 
1803  if (DO_AGGSPLIT_SKIPFINAL(aggstate->aggsplit))
1804  finalize_partialaggregate(aggstate, peragg, pergroupstate,
1805  &aggvalues[aggno], &aggnulls[aggno]);
1806  else
1807  finalize_aggregate(aggstate, peragg, pergroupstate,
1808  &aggvalues[aggno], &aggnulls[aggno]);
1809  }
1810 }
1811 
1812 /*
1813  * Project the result of a group (whose aggs have already been calculated by
1814  * finalize_aggregates). Returns the result slot, or NULL if no row is
1815  * projected (suppressed by qual).
1816  */
1817 static TupleTableSlot *
1819 {
1820  ExprContext *econtext = aggstate->ss.ps.ps_ExprContext;
1821 
1822  /*
1823  * Check the qual (HAVING clause); if the group does not match, ignore it.
1824  */
1825  if (ExecQual(aggstate->ss.ps.qual, econtext))
1826  {
1827  /*
1828  * Form and return projection tuple using the aggregate results and
1829  * the representative input tuple.
1830  */
1831  return ExecProject(aggstate->ss.ps.ps_ProjInfo);
1832  }
1833  else
1834  InstrCountFiltered1(aggstate, 1);
1835 
1836  return NULL;
1837 }
1838 
1839 /*
1840  * find_unaggregated_cols
1841  * Construct a bitmapset of the column numbers of un-aggregated Vars
1842  * appearing in our targetlist and qual (HAVING clause)
1843  */
1844 static Bitmapset *
1846 {
1847  Agg *node = (Agg *) aggstate->ss.ps.plan;
1848  Bitmapset *colnos;
1849 
1850  colnos = NULL;
1852  &colnos);
1853  (void) find_unaggregated_cols_walker((Node *) node->plan.qual,
1854  &colnos);
1855  return colnos;
1856 }
1857 
1858 static bool
1860 {
1861  if (node == NULL)
1862  return false;
1863  if (IsA(node, Var))
1864  {
1865  Var *var = (Var *) node;
1866 
1867  /* setrefs.c should have set the varno to OUTER_VAR */
1868  Assert(var->varno == OUTER_VAR);
1869  Assert(var->varlevelsup == 0);
1870  *colnos = bms_add_member(*colnos, var->varattno);
1871  return false;
1872  }
1873  if (IsA(node, Aggref) ||IsA(node, GroupingFunc))
1874  {
1875  /* do not descend into aggregate exprs */
1876  return false;
1877  }
1879  (void *) colnos);
1880 }
1881 
1882 /*
1883  * Initialize the hash table(s) to empty.
1884  *
1885  * To implement hashed aggregation, we need a hashtable that stores a
1886  * representative tuple and an array of AggStatePerGroup structs for each
1887  * distinct set of GROUP BY column values. We compute the hash key from the
1888  * GROUP BY columns. The per-group data is allocated in lookup_hash_entry(),
1889  * for each entry.
1890  *
1891  * We have a separate hashtable and associated perhash data structure for each
1892  * grouping set for which we're doing hashing.
1893  *
1894  * The hash tables always live in the hashcontext's per-tuple memory context
1895  * (there is only one of these for all tables together, since they are all
1896  * reset at the same time).
1897  */
1898 static void
1900 {
1901  MemoryContext tmpmem = aggstate->tmpcontext->ecxt_per_tuple_memory;
1902  Size additionalsize;
1903  int i;
1904 
1905  Assert(aggstate->aggstrategy == AGG_HASHED || aggstate->aggstrategy == AGG_MIXED);
1906 
1907  additionalsize = aggstate->numtrans * sizeof(AggStatePerGroupData);
1908 
1909  for (i = 0; i < aggstate->num_hashes; ++i)
1910  {
1911  AggStatePerHash perhash = &aggstate->perhash[i];
1912 
1913  Assert(perhash->aggnode->numGroups > 0);
1914 
1915  perhash->hashtable = BuildTupleHashTable(perhash->numCols,
1916  perhash->hashGrpColIdxHash,
1917  perhash->eqfunctions,
1918  perhash->hashfunctions,
1919  perhash->aggnode->numGroups,
1920  additionalsize,
1922  tmpmem,
1923  DO_AGGSPLIT_SKIPFINAL(aggstate->aggsplit));
1924  }
1925 }
1926 
1927 /*
1928  * Compute columns that actually need to be stored in hashtable entries. The
1929  * incoming tuples from the child plan node will contain grouping columns,
1930  * other columns referenced in our targetlist and qual, columns used to
1931  * compute the aggregate functions, and perhaps just junk columns we don't use
1932  * at all. Only columns of the first two types need to be stored in the
1933  * hashtable, and getting rid of the others can make the table entries
1934  * significantly smaller. The hashtable only contains the relevant columns,
1935  * and is packed/unpacked in lookup_hash_entry() / agg_retrieve_hash_table()
1936  * into the format of the normal input descriptor.
1937  *
1938  * Additional columns, in addition to the columns grouped by, come from two
1939  * sources: Firstly functionally dependent columns that we don't need to group
1940  * by themselves, and secondly ctids for row-marks.
1941  *
1942  * To eliminate duplicates, we build a bitmapset of the needed columns, and
1943  * then build an array of the columns included in the hashtable. Note that
1944  * the array is preserved over ExecReScanAgg, so we allocate it in the
1945  * per-query context (unlike the hash table itself).
1946  */
1947 static void
1949 {
1950  Bitmapset *base_colnos;
1951  List *outerTlist = outerPlanState(aggstate)->plan->targetlist;
1952  int numHashes = aggstate->num_hashes;
1953  int j;
1954 
1955  /* Find Vars that will be needed in tlist and qual */
1956  base_colnos = find_unaggregated_cols(aggstate);
1957 
1958  for (j = 0; j < numHashes; ++j)
1959  {
1960  AggStatePerHash perhash = &aggstate->perhash[j];
1961  Bitmapset *colnos = bms_copy(base_colnos);
1962  AttrNumber *grpColIdx = perhash->aggnode->grpColIdx;
1963  List *hashTlist = NIL;
1964  TupleDesc hashDesc;
1965  int i;
1966 
1967  perhash->largestGrpColIdx = 0;
1968 
1969  /*
1970  * If we're doing grouping sets, then some Vars might be referenced in
1971  * tlist/qual for the benefit of other grouping sets, but not needed
1972  * when hashing; i.e. prepare_projection_slot will null them out, so
1973  * there'd be no point storing them. Use prepare_projection_slot's
1974  * logic to determine which.
1975  */
1976  if (aggstate->phases[0].grouped_cols)
1977  {
1978  Bitmapset *grouped_cols = aggstate->phases[0].grouped_cols[j];
1979  ListCell *lc;
1980 
1981  foreach(lc, aggstate->all_grouped_cols)
1982  {
1983  int attnum = lfirst_int(lc);
1984 
1985  if (!bms_is_member(attnum, grouped_cols))
1986  colnos = bms_del_member(colnos, attnum);
1987  }
1988  }
1989  /* Add in all the grouping columns */
1990  for (i = 0; i < perhash->numCols; i++)
1991  colnos = bms_add_member(colnos, grpColIdx[i]);
1992 
1993  perhash->hashGrpColIdxInput =
1994  palloc(bms_num_members(colnos) * sizeof(AttrNumber));
1995  perhash->hashGrpColIdxHash =
1996  palloc(perhash->numCols * sizeof(AttrNumber));
1997 
1998  /*
1999  * First build mapping for columns directly hashed. These are the
2000  * first, because they'll be accessed when computing hash values and
2001  * comparing tuples for exact matches. We also build simple mapping
2002  * for execGrouping, so it knows where to find the to-be-hashed /
2003  * compared columns in the input.
2004  */
2005  for (i = 0; i < perhash->numCols; i++)
2006  {
2007  perhash->hashGrpColIdxInput[i] = grpColIdx[i];
2008  perhash->hashGrpColIdxHash[i] = i + 1;
2009  perhash->numhashGrpCols++;
2010  /* delete already mapped columns */
2011  bms_del_member(colnos, grpColIdx[i]);
2012  }
2013 
2014  /* and add the remaining columns */
2015  while ((i = bms_first_member(colnos)) >= 0)
2016  {
2017  perhash->hashGrpColIdxInput[perhash->numhashGrpCols] = i;
2018  perhash->numhashGrpCols++;
2019  }
2020 
2021  /* and build a tuple descriptor for the hashtable */
2022  for (i = 0; i < perhash->numhashGrpCols; i++)
2023  {
2024  int varNumber = perhash->hashGrpColIdxInput[i] - 1;
2025 
2026  hashTlist = lappend(hashTlist, list_nth(outerTlist, varNumber));
2027  perhash->largestGrpColIdx =
2028  Max(varNumber + 1, perhash->largestGrpColIdx);
2029  }
2030 
2031  hashDesc = ExecTypeFromTL(hashTlist, false);
2032  ExecSetSlotDescriptor(perhash->hashslot, hashDesc);
2033 
2034  list_free(hashTlist);
2035  bms_free(colnos);
2036  }
2037 
2038  bms_free(base_colnos);
2039 }
2040 
2041 /*
2042  * Estimate per-hash-table-entry overhead for the planner.
2043  *
2044  * Note that the estimate does not include space for pass-by-reference
2045  * transition data values, nor for the representative tuple of each group.
2046  * Nor does this account of the target fill-factor and growth policy of the
2047  * hash table.
2048  */
2049 Size
2051 {
2052  Size entrysize;
2053 
2054  /* This must match build_hash_table */
2055  entrysize = sizeof(TupleHashEntryData) +
2056  numAggs * sizeof(AggStatePerGroupData);
2057  entrysize = MAXALIGN(entrysize);
2058 
2059  return entrysize;
2060 }
2061 
2062 /*
2063  * Find or create a hashtable entry for the tuple group containing the current
2064  * tuple (already set in tmpcontext's outertuple slot), in the current grouping
2065  * set (which the caller must have selected - note that initialize_aggregate
2066  * depends on this).
2067  *
2068  * When called, CurrentMemoryContext should be the per-query context.
2069  */
2070 static TupleHashEntryData *
2072 {
2073  TupleTableSlot *inputslot = aggstate->tmpcontext->ecxt_outertuple;
2074  AggStatePerHash perhash = &aggstate->perhash[aggstate->current_set];
2075  TupleTableSlot *hashslot = perhash->hashslot;
2076  TupleHashEntryData *entry;
2077  bool isnew;
2078  int i;
2079 
2080  /* transfer just the needed columns into hashslot */
2081  slot_getsomeattrs(inputslot, perhash->largestGrpColIdx);
2082  ExecClearTuple(hashslot);
2083 
2084  for (i = 0; i < perhash->numhashGrpCols; i++)
2085  {
2086  int varNumber = perhash->hashGrpColIdxInput[i] - 1;
2087 
2088  hashslot->tts_values[i] = inputslot->tts_values[varNumber];
2089  hashslot->tts_isnull[i] = inputslot->tts_isnull[varNumber];
2090  }
2091  ExecStoreVirtualTuple(hashslot);
2092 
2093  /* find or create the hashtable entry using the filtered tuple */
2094  entry = LookupTupleHashEntry(perhash->hashtable, hashslot, &isnew);
2095 
2096  if (isnew)
2097  {
2098  entry->additional = (AggStatePerGroup)
2100  sizeof(AggStatePerGroupData) * aggstate->numtrans);
2101  /* initialize aggregates for new tuple group */
2103  -1);
2104  }
2105 
2106  return entry;
2107 }
2108 
2109 /*
2110  * Look up hash entries for the current tuple in all hashed grouping sets,
2111  * returning an array of pergroup pointers suitable for advance_aggregates.
2112  *
2113  * Be aware that lookup_hash_entry can reset the tmpcontext.
2114  */
2115 static AggStatePerGroup *
2117 {
2118  int numHashes = aggstate->num_hashes;
2119  AggStatePerGroup *pergroup = aggstate->hash_pergroup;
2120  int setno;
2121 
2122  for (setno = 0; setno < numHashes; setno++)
2123  {
2124  select_current_set(aggstate, setno, true);
2125  pergroup[setno] = lookup_hash_entry(aggstate)->additional;
2126  }
2127 
2128  return pergroup;
2129 }
2130 
2131 /*
2132  * ExecAgg -
2133  *
2134  * ExecAgg receives tuples from its outer subplan and aggregates over
2135  * the appropriate attribute for each aggregate function use (Aggref
2136  * node) appearing in the targetlist or qual of the node. The number
2137  * of tuples to aggregate over depends on whether grouped or plain
2138  * aggregation is selected. In grouped aggregation, we produce a result
2139  * row for each group; in plain aggregation there's a single result row
2140  * for the whole query. In either case, the value of each aggregate is
2141  * stored in the expression context to be used when ExecProject evaluates
2142  * the result tuple.
2143  */
2144 static TupleTableSlot *
2146 {
2147  AggState *node = castNode(AggState, pstate);
2148  TupleTableSlot *result = NULL;
2149 
2151 
2152  if (!node->agg_done)
2153  {
2154  /* Dispatch based on strategy */
2155  switch (node->phase->aggstrategy)
2156  {
2157  case AGG_HASHED:
2158  if (!node->table_filled)
2159  agg_fill_hash_table(node);
2160  /* FALLTHROUGH */
2161  case AGG_MIXED:
2162  result = agg_retrieve_hash_table(node);
2163  break;
2164  case AGG_PLAIN:
2165  case AGG_SORTED:
2166  result = agg_retrieve_direct(node);
2167  break;
2168  }
2169 
2170  if (!TupIsNull(result))
2171  return result;
2172  }
2173 
2174  return NULL;
2175 }
2176 
2177 /*
2178  * ExecAgg for non-hashed case
2179  */
2180 static TupleTableSlot *
2182 {
2183  Agg *node = aggstate->phase->aggnode;
2184  ExprContext *econtext;
2185  ExprContext *tmpcontext;
2186  AggStatePerAgg peragg;
2187  AggStatePerGroup pergroup;
2188  AggStatePerGroup *hash_pergroups = NULL;
2189  TupleTableSlot *outerslot;
2190  TupleTableSlot *firstSlot;
2191  TupleTableSlot *result;
2192  bool hasGroupingSets = aggstate->phase->numsets > 0;
2193  int numGroupingSets = Max(aggstate->phase->numsets, 1);
2194  int currentSet;
2195  int nextSetSize;
2196  int numReset;
2197  int i;
2198 
2199  /*
2200  * get state info from node
2201  *
2202  * econtext is the per-output-tuple expression context
2203  *
2204  * tmpcontext is the per-input-tuple expression context
2205  */
2206  econtext = aggstate->ss.ps.ps_ExprContext;
2207  tmpcontext = aggstate->tmpcontext;
2208 
2209  peragg = aggstate->peragg;
2210  pergroup = aggstate->pergroup;
2211  firstSlot = aggstate->ss.ss_ScanTupleSlot;
2212 
2213  /*
2214  * We loop retrieving groups until we find one matching
2215  * aggstate->ss.ps.qual
2216  *
2217  * For grouping sets, we have the invariant that aggstate->projected_set
2218  * is either -1 (initial call) or the index (starting from 0) in
2219  * gset_lengths for the group we just completed (either by projecting a
2220  * row or by discarding it in the qual).
2221  */
2222  while (!aggstate->agg_done)
2223  {
2224  /*
2225  * Clear the per-output-tuple context for each group, as well as
2226  * aggcontext (which contains any pass-by-ref transvalues of the old
2227  * group). Some aggregate functions store working state in child
2228  * contexts; those now get reset automatically without us needing to
2229  * do anything special.
2230  *
2231  * We use ReScanExprContext not just ResetExprContext because we want
2232  * any registered shutdown callbacks to be called. That allows
2233  * aggregate functions to ensure they've cleaned up any non-memory
2234  * resources.
2235  */
2236  ReScanExprContext(econtext);
2237 
2238  /*
2239  * Determine how many grouping sets need to be reset at this boundary.
2240  */
2241  if (aggstate->projected_set >= 0 &&
2242  aggstate->projected_set < numGroupingSets)
2243  numReset = aggstate->projected_set + 1;
2244  else
2245  numReset = numGroupingSets;
2246 
2247  /*
2248  * numReset can change on a phase boundary, but that's OK; we want to
2249  * reset the contexts used in _this_ phase, and later, after possibly
2250  * changing phase, initialize the right number of aggregates for the
2251  * _new_ phase.
2252  */
2253 
2254  for (i = 0; i < numReset; i++)
2255  {
2256  ReScanExprContext(aggstate->aggcontexts[i]);
2257  }
2258 
2259  /*
2260  * Check if input is complete and there are no more groups to project
2261  * in this phase; move to next phase or mark as done.
2262  */
2263  if (aggstate->input_done == true &&
2264  aggstate->projected_set >= (numGroupingSets - 1))
2265  {
2266  if (aggstate->current_phase < aggstate->numphases - 1)
2267  {
2268  initialize_phase(aggstate, aggstate->current_phase + 1);
2269  aggstate->input_done = false;
2270  aggstate->projected_set = -1;
2271  numGroupingSets = Max(aggstate->phase->numsets, 1);
2272  node = aggstate->phase->aggnode;
2273  numReset = numGroupingSets;
2274  }
2275  else if (aggstate->aggstrategy == AGG_MIXED)
2276  {
2277  /*
2278  * Mixed mode; we've output all the grouped stuff and have
2279  * full hashtables, so switch to outputting those.
2280  */
2281  initialize_phase(aggstate, 0);
2282  aggstate->table_filled = true;
2284  &aggstate->perhash[0].hashiter);
2285  select_current_set(aggstate, 0, true);
2286  return agg_retrieve_hash_table(aggstate);
2287  }
2288  else
2289  {
2290  aggstate->agg_done = true;
2291  break;
2292  }
2293  }
2294 
2295  /*
2296  * Get the number of columns in the next grouping set after the last
2297  * projected one (if any). This is the number of columns to compare to
2298  * see if we reached the boundary of that set too.
2299  */
2300  if (aggstate->projected_set >= 0 &&
2301  aggstate->projected_set < (numGroupingSets - 1))
2302  nextSetSize = aggstate->phase->gset_lengths[aggstate->projected_set + 1];
2303  else
2304  nextSetSize = 0;
2305 
2306  /*----------
2307  * If a subgroup for the current grouping set is present, project it.
2308  *
2309  * We have a new group if:
2310  * - we're out of input but haven't projected all grouping sets
2311  * (checked above)
2312  * OR
2313  * - we already projected a row that wasn't from the last grouping
2314  * set
2315  * AND
2316  * - the next grouping set has at least one grouping column (since
2317  * empty grouping sets project only once input is exhausted)
2318  * AND
2319  * - the previous and pending rows differ on the grouping columns
2320  * of the next grouping set
2321  *----------
2322  */
2323  if (aggstate->input_done ||
2324  (node->aggstrategy != AGG_PLAIN &&
2325  aggstate->projected_set != -1 &&
2326  aggstate->projected_set < (numGroupingSets - 1) &&
2327  nextSetSize > 0 &&
2328  !execTuplesMatch(econtext->ecxt_outertuple,
2329  tmpcontext->ecxt_outertuple,
2330  nextSetSize,
2331  node->grpColIdx,
2332  aggstate->phase->eqfunctions,
2333  tmpcontext->ecxt_per_tuple_memory)))
2334  {
2335  aggstate->projected_set += 1;
2336 
2337  Assert(aggstate->projected_set < numGroupingSets);
2338  Assert(nextSetSize > 0 || aggstate->input_done);
2339  }
2340  else
2341  {
2342  /*
2343  * We no longer care what group we just projected, the next
2344  * projection will always be the first (or only) grouping set
2345  * (unless the input proves to be empty).
2346  */
2347  aggstate->projected_set = 0;
2348 
2349  /*
2350  * If we don't already have the first tuple of the new group,
2351  * fetch it from the outer plan.
2352  */
2353  if (aggstate->grp_firstTuple == NULL)
2354  {
2355  outerslot = fetch_input_tuple(aggstate);
2356  if (!TupIsNull(outerslot))
2357  {
2358  /*
2359  * Make a copy of the first input tuple; we will use this
2360  * for comparisons (in group mode) and for projection.
2361  */
2362  aggstate->grp_firstTuple = ExecCopySlotTuple(outerslot);
2363  }
2364  else
2365  {
2366  /* outer plan produced no tuples at all */
2367  if (hasGroupingSets)
2368  {
2369  /*
2370  * If there was no input at all, we need to project
2371  * rows only if there are grouping sets of size 0.
2372  * Note that this implies that there can't be any
2373  * references to ungrouped Vars, which would otherwise
2374  * cause issues with the empty output slot.
2375  *
2376  * XXX: This is no longer true, we currently deal with
2377  * this in finalize_aggregates().
2378  */
2379  aggstate->input_done = true;
2380 
2381  while (aggstate->phase->gset_lengths[aggstate->projected_set] > 0)
2382  {
2383  aggstate->projected_set += 1;
2384  if (aggstate->projected_set >= numGroupingSets)
2385  {
2386  /*
2387  * We can't set agg_done here because we might
2388  * have more phases to do, even though the
2389  * input is empty. So we need to restart the
2390  * whole outer loop.
2391  */
2392  break;
2393  }
2394  }
2395 
2396  if (aggstate->projected_set >= numGroupingSets)
2397  continue;
2398  }
2399  else
2400  {
2401  aggstate->agg_done = true;
2402  /* If we are grouping, we should produce no tuples too */
2403  if (node->aggstrategy != AGG_PLAIN)
2404  return NULL;
2405  }
2406  }
2407  }
2408 
2409  /*
2410  * Initialize working state for a new input tuple group.
2411  */
2412  initialize_aggregates(aggstate, pergroup, numReset);
2413 
2414  if (aggstate->grp_firstTuple != NULL)
2415  {
2416  /*
2417  * Store the copied first input tuple in the tuple table slot
2418  * reserved for it. The tuple will be deleted when it is
2419  * cleared from the slot.
2420  */
2421  ExecStoreTuple(aggstate->grp_firstTuple,
2422  firstSlot,
2423  InvalidBuffer,
2424  true);
2425  aggstate->grp_firstTuple = NULL; /* don't keep two pointers */
2426 
2427  /* set up for first advance_aggregates call */
2428  tmpcontext->ecxt_outertuple = firstSlot;
2429 
2430  /*
2431  * Process each outer-plan tuple, and then fetch the next one,
2432  * until we exhaust the outer plan or cross a group boundary.
2433  */
2434  for (;;)
2435  {
2436  /*
2437  * During phase 1 only of a mixed agg, we need to update
2438  * hashtables as well in advance_aggregates.
2439  */
2440  if (aggstate->aggstrategy == AGG_MIXED &&
2441  aggstate->current_phase == 1)
2442  {
2443  hash_pergroups = lookup_hash_entries(aggstate);
2444  }
2445  else
2446  hash_pergroups = NULL;
2447 
2448  if (DO_AGGSPLIT_COMBINE(aggstate->aggsplit))
2449  combine_aggregates(aggstate, pergroup);
2450  else
2451  advance_aggregates(aggstate, pergroup, hash_pergroups);
2452 
2453  /* Reset per-input-tuple context after each tuple */
2454  ResetExprContext(tmpcontext);
2455 
2456  outerslot = fetch_input_tuple(aggstate);
2457  if (TupIsNull(outerslot))
2458  {
2459  /* no more outer-plan tuples available */
2460  if (hasGroupingSets)
2461  {
2462  aggstate->input_done = true;
2463  break;
2464  }
2465  else
2466  {
2467  aggstate->agg_done = true;
2468  break;
2469  }
2470  }
2471  /* set up for next advance_aggregates call */
2472  tmpcontext->ecxt_outertuple = outerslot;
2473 
2474  /*
2475  * If we are grouping, check whether we've crossed a group
2476  * boundary.
2477  */
2478  if (node->aggstrategy != AGG_PLAIN)
2479  {
2480  if (!execTuplesMatch(firstSlot,
2481  outerslot,
2482  node->numCols,
2483  node->grpColIdx,
2484  aggstate->phase->eqfunctions,
2485  tmpcontext->ecxt_per_tuple_memory))
2486  {
2487  aggstate->grp_firstTuple = ExecCopySlotTuple(outerslot);
2488  break;
2489  }
2490  }
2491  }
2492  }
2493 
2494  /*
2495  * Use the representative input tuple for any references to
2496  * non-aggregated input columns in aggregate direct args, the node
2497  * qual, and the tlist. (If we are not grouping, and there are no
2498  * input rows at all, we will come here with an empty firstSlot
2499  * ... but if not grouping, there can't be any references to
2500  * non-aggregated input columns, so no problem.)
2501  */
2502  econtext->ecxt_outertuple = firstSlot;
2503  }
2504 
2505  Assert(aggstate->projected_set >= 0);
2506 
2507  currentSet = aggstate->projected_set;
2508 
2509  prepare_projection_slot(aggstate, econtext->ecxt_outertuple, currentSet);
2510 
2511  select_current_set(aggstate, currentSet, false);
2512 
2513  finalize_aggregates(aggstate,
2514  peragg,
2515  pergroup + (currentSet * aggstate->numtrans));
2516 
2517  /*
2518  * If there's no row to project right now, we must continue rather
2519  * than returning a null since there might be more groups.
2520  */
2521  result = project_aggregates(aggstate);
2522  if (result)
2523  return result;
2524  }
2525 
2526  /* No more groups */
2527  return NULL;
2528 }
2529 
2530 /*
2531  * ExecAgg for hashed case: read input and build hash table
2532  */
2533 static void
2535 {
2536  TupleTableSlot *outerslot;
2537  ExprContext *tmpcontext = aggstate->tmpcontext;
2538 
2539  /*
2540  * Process each outer-plan tuple, and then fetch the next one, until we
2541  * exhaust the outer plan.
2542  */
2543  for (;;)
2544  {
2545  AggStatePerGroup *pergroups;
2546 
2547  outerslot = fetch_input_tuple(aggstate);
2548  if (TupIsNull(outerslot))
2549  break;
2550 
2551  /* set up for lookup_hash_entries and advance_aggregates */
2552  tmpcontext->ecxt_outertuple = outerslot;
2553 
2554  /* Find or build hashtable entries */
2555  pergroups = lookup_hash_entries(aggstate);
2556 
2557  /* Advance the aggregates */
2558  if (DO_AGGSPLIT_COMBINE(aggstate->aggsplit))
2559  combine_aggregates(aggstate, pergroups[0]);
2560  else
2561  advance_aggregates(aggstate, NULL, pergroups);
2562 
2563  /*
2564  * Reset per-input-tuple context after each tuple, but note that the
2565  * hash lookups do this too
2566  */
2567  ResetExprContext(aggstate->tmpcontext);
2568  }
2569 
2570  aggstate->table_filled = true;
2571  /* Initialize to walk the first hash table */
2572  select_current_set(aggstate, 0, true);
2574  &aggstate->perhash[0].hashiter);
2575 }
2576 
2577 /*
2578  * ExecAgg for hashed case: retrieving groups from hash table
2579  */
2580 static TupleTableSlot *
2582 {
2583  ExprContext *econtext;
2584  AggStatePerAgg peragg;
2585  AggStatePerGroup pergroup;
2586  TupleHashEntryData *entry;
2587  TupleTableSlot *firstSlot;
2588  TupleTableSlot *result;
2589  AggStatePerHash perhash;
2590 
2591  /*
2592  * get state info from node.
2593  *
2594  * econtext is the per-output-tuple expression context.
2595  */
2596  econtext = aggstate->ss.ps.ps_ExprContext;
2597  peragg = aggstate->peragg;
2598  firstSlot = aggstate->ss.ss_ScanTupleSlot;
2599 
2600  /*
2601  * Note that perhash (and therefore anything accessed through it) can
2602  * change inside the loop, as we change between grouping sets.
2603  */
2604  perhash = &aggstate->perhash[aggstate->current_set];
2605 
2606  /*
2607  * We loop retrieving groups until we find one satisfying
2608  * aggstate->ss.ps.qual
2609  */
2610  while (!aggstate->agg_done)
2611  {
2612  TupleTableSlot *hashslot = perhash->hashslot;
2613  int i;
2614 
2616 
2617  /*
2618  * Find the next entry in the hash table
2619  */
2620  entry = ScanTupleHashTable(perhash->hashtable, &perhash->hashiter);
2621  if (entry == NULL)
2622  {
2623  int nextset = aggstate->current_set + 1;
2624 
2625  if (nextset < aggstate->num_hashes)
2626  {
2627  /*
2628  * Switch to next grouping set, reinitialize, and restart the
2629  * loop.
2630  */
2631  select_current_set(aggstate, nextset, true);
2632 
2633  perhash = &aggstate->perhash[aggstate->current_set];
2634 
2635  ResetTupleHashIterator(perhash->hashtable, &perhash->hashiter);
2636 
2637  continue;
2638  }
2639  else
2640  {
2641  /* No more hashtables, so done */
2642  aggstate->agg_done = true;
2643  return NULL;
2644  }
2645  }
2646 
2647  /*
2648  * Clear the per-output-tuple context for each group
2649  *
2650  * We intentionally don't use ReScanExprContext here; if any aggs have
2651  * registered shutdown callbacks, they mustn't be called yet, since we
2652  * might not be done with that agg.
2653  */
2654  ResetExprContext(econtext);
2655 
2656  /*
2657  * Transform representative tuple back into one with the right
2658  * columns.
2659  */
2660  ExecStoreMinimalTuple(entry->firstTuple, hashslot, false);
2661  slot_getallattrs(hashslot);
2662 
2663  ExecClearTuple(firstSlot);
2664  memset(firstSlot->tts_isnull, true,
2665  firstSlot->tts_tupleDescriptor->natts * sizeof(bool));
2666 
2667  for (i = 0; i < perhash->numhashGrpCols; i++)
2668  {
2669  int varNumber = perhash->hashGrpColIdxInput[i] - 1;
2670 
2671  firstSlot->tts_values[varNumber] = hashslot->tts_values[i];
2672  firstSlot->tts_isnull[varNumber] = hashslot->tts_isnull[i];
2673  }
2674  ExecStoreVirtualTuple(firstSlot);
2675 
2676  pergroup = (AggStatePerGroup) entry->additional;
2677 
2678  /*
2679  * Use the representative input tuple for any references to
2680  * non-aggregated input columns in the qual and tlist.
2681  */
2682  econtext->ecxt_outertuple = firstSlot;
2683 
2684  prepare_projection_slot(aggstate,
2685  econtext->ecxt_outertuple,
2686  aggstate->current_set);
2687 
2688  finalize_aggregates(aggstate, peragg, pergroup);
2689 
2690  result = project_aggregates(aggstate);
2691  if (result)
2692  return result;
2693  }
2694 
2695  /* No more groups */
2696  return NULL;
2697 }
2698 
2699 /* -----------------
2700  * ExecInitAgg
2701  *
2702  * Creates the run-time information for the agg node produced by the
2703  * planner and initializes its outer subtree.
2704  *
2705  * -----------------
2706  */
2707 AggState *
2708 ExecInitAgg(Agg *node, EState *estate, int eflags)
2709 {
2710  AggState *aggstate;
2711  AggStatePerAgg peraggs;
2712  AggStatePerTrans pertransstates;
2713  Plan *outerPlan;
2714  ExprContext *econtext;
2715  int numaggs,
2716  transno,
2717  aggno;
2718  int phase;
2719  int phaseidx;
2720  List *combined_inputeval;
2721  TupleDesc combineddesc;
2722  TupleTableSlot *combinedslot;
2723  ListCell *l;
2724  Bitmapset *all_grouped_cols = NULL;
2725  int numGroupingSets = 1;
2726  int numPhases;
2727  int numHashes;
2728  int column_offset;
2729  int i = 0;
2730  int j = 0;
2731  bool use_hashing = (node->aggstrategy == AGG_HASHED ||
2732  node->aggstrategy == AGG_MIXED);
2733 
2734  /* check for unsupported flags */
2735  Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
2736 
2737  /*
2738  * create state structure
2739  */
2740  aggstate = makeNode(AggState);
2741  aggstate->ss.ps.plan = (Plan *) node;
2742  aggstate->ss.ps.state = estate;
2743  aggstate->ss.ps.ExecProcNode = ExecAgg;
2744 
2745  aggstate->aggs = NIL;
2746  aggstate->numaggs = 0;
2747  aggstate->numtrans = 0;
2748  aggstate->aggstrategy = node->aggstrategy;
2749  aggstate->aggsplit = node->aggsplit;
2750  aggstate->maxsets = 0;
2751  aggstate->projected_set = -1;
2752  aggstate->current_set = 0;
2753  aggstate->peragg = NULL;
2754  aggstate->pertrans = NULL;
2755  aggstate->curperagg = NULL;
2756  aggstate->curpertrans = NULL;
2757  aggstate->input_done = false;
2758  aggstate->agg_done = false;
2759  aggstate->pergroup = NULL;
2760  aggstate->grp_firstTuple = NULL;
2761  aggstate->sort_in = NULL;
2762  aggstate->sort_out = NULL;
2763 
2764  /*
2765  * phases[0] always exists, but is dummy in sorted/plain mode
2766  */
2767  numPhases = (use_hashing ? 1 : 2);
2768  numHashes = (use_hashing ? 1 : 0);
2769 
2770  /*
2771  * Calculate the maximum number of grouping sets in any phase; this
2772  * determines the size of some allocations. Also calculate the number of
2773  * phases, since all hashed/mixed nodes contribute to only a single phase.
2774  */
2775  if (node->groupingSets)
2776  {
2777  numGroupingSets = list_length(node->groupingSets);
2778 
2779  foreach(l, node->chain)
2780  {
2781  Agg *agg = lfirst(l);
2782 
2783  numGroupingSets = Max(numGroupingSets,
2784  list_length(agg->groupingSets));
2785 
2786  /*
2787  * additional AGG_HASHED aggs become part of phase 0, but all
2788  * others add an extra phase.
2789  */
2790  if (agg->aggstrategy != AGG_HASHED)
2791  ++numPhases;
2792  else
2793  ++numHashes;
2794  }
2795  }
2796 
2797  aggstate->maxsets = numGroupingSets;
2798  aggstate->numphases = numPhases;
2799 
2800  aggstate->aggcontexts = (ExprContext **)
2801  palloc0(sizeof(ExprContext *) * numGroupingSets);
2802 
2803  /*
2804  * Create expression contexts. We need three or more, one for
2805  * per-input-tuple processing, one for per-output-tuple processing, one
2806  * for all the hashtables, and one for each grouping set. The per-tuple
2807  * memory context of the per-grouping-set ExprContexts (aggcontexts)
2808  * replaces the standalone memory context formerly used to hold transition
2809  * values. We cheat a little by using ExecAssignExprContext() to build
2810  * all of them.
2811  *
2812  * NOTE: the details of what is stored in aggcontexts and what is stored
2813  * in the regular per-query memory context are driven by a simple
2814  * decision: we want to reset the aggcontext at group boundaries (if not
2815  * hashing) and in ExecReScanAgg to recover no-longer-wanted space.
2816  */
2817  ExecAssignExprContext(estate, &aggstate->ss.ps);
2818  aggstate->tmpcontext = aggstate->ss.ps.ps_ExprContext;
2819 
2820  for (i = 0; i < numGroupingSets; ++i)
2821  {
2822  ExecAssignExprContext(estate, &aggstate->ss.ps);
2823  aggstate->aggcontexts[i] = aggstate->ss.ps.ps_ExprContext;
2824  }
2825 
2826  if (use_hashing)
2827  {
2828  ExecAssignExprContext(estate, &aggstate->ss.ps);
2829  aggstate->hashcontext = aggstate->ss.ps.ps_ExprContext;
2830  }
2831 
2832  ExecAssignExprContext(estate, &aggstate->ss.ps);
2833 
2834  /*
2835  * tuple table initialization.
2836  *
2837  * For hashtables, we create some additional slots below.
2838  */
2839  ExecInitScanTupleSlot(estate, &aggstate->ss);
2840  ExecInitResultTupleSlot(estate, &aggstate->ss.ps);
2841  aggstate->sort_slot = ExecInitExtraTupleSlot(estate);
2842 
2843  /*
2844  * initialize child expressions
2845  *
2846  * We expect the parser to have checked that no aggs contain other agg
2847  * calls in their arguments (and just to be sure, we verify it again while
2848  * initializing the plan node). This would make no sense under SQL
2849  * semantics, and it's forbidden by the spec. Because it is true, we
2850  * don't need to worry about evaluating the aggs in any particular order.
2851  *
2852  * Note: execExpr.c finds Aggrefs for us, and adds their AggrefExprState
2853  * nodes to aggstate->aggs. Aggrefs in the qual are found here; Aggrefs
2854  * in the targetlist are found during ExecAssignProjectionInfo, below.
2855  */
2856  aggstate->ss.ps.qual =
2857  ExecInitQual(node->plan.qual, (PlanState *) aggstate);
2858 
2859  /*
2860  * Initialize child nodes.
2861  *
2862  * If we are doing a hashed aggregation then the child plan does not need
2863  * to handle REWIND efficiently; see ExecReScanAgg.
2864  */
2865  if (node->aggstrategy == AGG_HASHED)
2866  eflags &= ~EXEC_FLAG_REWIND;
2867  outerPlan = outerPlan(node);
2868  outerPlanState(aggstate) = ExecInitNode(outerPlan, estate, eflags);
2869 
2870  /*
2871  * initialize source tuple type.
2872  */
2873  ExecAssignScanTypeFromOuterPlan(&aggstate->ss);
2874  if (node->chain)
2875  ExecSetSlotDescriptor(aggstate->sort_slot,
2876  aggstate->ss.ss_ScanTupleSlot->tts_tupleDescriptor);
2877 
2878  /*
2879  * Initialize result tuple type and projection info.
2880  */
2881  ExecAssignResultTypeFromTL(&aggstate->ss.ps);
2882  ExecAssignProjectionInfo(&aggstate->ss.ps, NULL);
2883 
2884  /*
2885  * We should now have found all Aggrefs in the targetlist and quals.
2886  */
2887  numaggs = aggstate->numaggs;
2888  Assert(numaggs == list_length(aggstate->aggs));
2889 
2890  /*
2891  * For each phase, prepare grouping set data and fmgr lookup data for
2892  * compare functions. Accumulate all_grouped_cols in passing.
2893  */
2894  aggstate->phases = palloc0(numPhases * sizeof(AggStatePerPhaseData));
2895 
2896  aggstate->num_hashes = numHashes;
2897  if (numHashes)
2898  {
2899  aggstate->perhash = palloc0(sizeof(AggStatePerHashData) * numHashes);
2900  aggstate->phases[0].numsets = 0;
2901  aggstate->phases[0].gset_lengths = palloc(numHashes * sizeof(int));
2902  aggstate->phases[0].grouped_cols = palloc(numHashes * sizeof(Bitmapset *));
2903  }
2904 
2905  phase = 0;
2906  for (phaseidx = 0; phaseidx <= list_length(node->chain); ++phaseidx)
2907  {
2908  Agg *aggnode;
2909  Sort *sortnode;
2910 
2911  if (phaseidx > 0)
2912  {
2913  aggnode = list_nth_node(Agg, node->chain, phaseidx - 1);
2914  sortnode = castNode(Sort, aggnode->plan.lefttree);
2915  }
2916  else
2917  {
2918  aggnode = node;
2919  sortnode = NULL;
2920  }
2921 
2922  Assert(phase <= 1 || sortnode);
2923 
2924  if (aggnode->aggstrategy == AGG_HASHED
2925  || aggnode->aggstrategy == AGG_MIXED)
2926  {
2927  AggStatePerPhase phasedata = &aggstate->phases[0];
2928  AggStatePerHash perhash;
2929  Bitmapset *cols = NULL;
2930 
2931  Assert(phase == 0);
2932  i = phasedata->numsets++;
2933  perhash = &aggstate->perhash[i];
2934 
2935  /* phase 0 always points to the "real" Agg in the hash case */
2936  phasedata->aggnode = node;
2937  phasedata->aggstrategy = node->aggstrategy;
2938 
2939  /* but the actual Agg node representing this hash is saved here */
2940  perhash->aggnode = aggnode;
2941 
2942  phasedata->gset_lengths[i] = perhash->numCols = aggnode->numCols;
2943 
2944  for (j = 0; j < aggnode->numCols; ++j)
2945  cols = bms_add_member(cols, aggnode->grpColIdx[j]);
2946 
2947  phasedata->grouped_cols[i] = cols;
2948 
2949  all_grouped_cols = bms_add_members(all_grouped_cols, cols);
2950  continue;
2951  }
2952  else
2953  {
2954  AggStatePerPhase phasedata = &aggstate->phases[++phase];
2955  int num_sets;
2956 
2957  phasedata->numsets = num_sets = list_length(aggnode->groupingSets);
2958 
2959  if (num_sets)
2960  {
2961  phasedata->gset_lengths = palloc(num_sets * sizeof(int));
2962  phasedata->grouped_cols = palloc(num_sets * sizeof(Bitmapset *));
2963 
2964  i = 0;
2965  foreach(l, aggnode->groupingSets)
2966  {
2967  int current_length = list_length(lfirst(l));
2968  Bitmapset *cols = NULL;
2969 
2970  /* planner forces this to be correct */
2971  for (j = 0; j < current_length; ++j)
2972  cols = bms_add_member(cols, aggnode->grpColIdx[j]);
2973 
2974  phasedata->grouped_cols[i] = cols;
2975  phasedata->gset_lengths[i] = current_length;
2976 
2977  ++i;
2978  }
2979 
2980  all_grouped_cols = bms_add_members(all_grouped_cols,
2981  phasedata->grouped_cols[0]);
2982  }
2983  else
2984  {
2985  Assert(phaseidx == 0);
2986 
2987  phasedata->gset_lengths = NULL;
2988  phasedata->grouped_cols = NULL;
2989  }
2990 
2991  /*
2992  * If we are grouping, precompute fmgr lookup data for inner loop.
2993  */
2994  if (aggnode->aggstrategy == AGG_SORTED)
2995  {
2996  Assert(aggnode->numCols > 0);
2997 
2998  phasedata->eqfunctions =
3000  aggnode->grpOperators);
3001  }
3002 
3003  phasedata->aggnode = aggnode;
3004  phasedata->aggstrategy = aggnode->aggstrategy;
3005  phasedata->sortnode = sortnode;
3006  }
3007  }
3008 
3009  /*
3010  * Convert all_grouped_cols to a descending-order list.
3011  */
3012  i = -1;
3013  while ((i = bms_next_member(all_grouped_cols, i)) >= 0)
3014  aggstate->all_grouped_cols = lcons_int(i, aggstate->all_grouped_cols);
3015 
3016  /*
3017  * Set up aggregate-result storage in the output expr context, and also
3018  * allocate my private per-agg working storage
3019  */
3020  econtext = aggstate->ss.ps.ps_ExprContext;
3021  econtext->ecxt_aggvalues = (Datum *) palloc0(sizeof(Datum) * numaggs);
3022  econtext->ecxt_aggnulls = (bool *) palloc0(sizeof(bool) * numaggs);
3023 
3024  peraggs = (AggStatePerAgg) palloc0(sizeof(AggStatePerAggData) * numaggs);
3025  pertransstates = (AggStatePerTrans) palloc0(sizeof(AggStatePerTransData) * numaggs);
3026 
3027  aggstate->peragg = peraggs;
3028  aggstate->pertrans = pertransstates;
3029 
3030  /*
3031  * Hashing can only appear in the initial phase.
3032  */
3033  if (use_hashing)
3034  {
3035  for (i = 0; i < numHashes; ++i)
3036  {
3037  aggstate->perhash[i].hashslot = ExecInitExtraTupleSlot(estate);
3038 
3039  execTuplesHashPrepare(aggstate->perhash[i].numCols,
3040  aggstate->perhash[i].aggnode->grpOperators,
3041  &aggstate->perhash[i].eqfunctions,
3042  &aggstate->perhash[i].hashfunctions);
3043  }
3044 
3045  /* this is an array of pointers, not structures */
3046  aggstate->hash_pergroup = palloc0(sizeof(AggStatePerGroup) * numHashes);
3047 
3048  find_hash_columns(aggstate);
3049  build_hash_table(aggstate);
3050  aggstate->table_filled = false;
3051  }
3052 
3053  if (node->aggstrategy != AGG_HASHED)
3054  {
3055  AggStatePerGroup pergroup;
3056 
3057  pergroup = (AggStatePerGroup) palloc0(sizeof(AggStatePerGroupData)
3058  * numaggs
3059  * numGroupingSets);
3060 
3061  aggstate->pergroup = pergroup;
3062  }
3063 
3064  /*
3065  * Initialize current phase-dependent values to initial phase. The initial
3066  * phase is 1 (first sort pass) for all strategies that use sorting (if
3067  * hashing is being done too, then phase 0 is processed last); but if only
3068  * hashing is being done, then phase 0 is all there is.
3069  */
3070  if (node->aggstrategy == AGG_HASHED)
3071  {
3072  aggstate->current_phase = 0;
3073  initialize_phase(aggstate, 0);
3074  select_current_set(aggstate, 0, true);
3075  }
3076  else
3077  {
3078  aggstate->current_phase = 1;
3079  initialize_phase(aggstate, 1);
3080  select_current_set(aggstate, 0, false);
3081  }
3082 
3083  /* -----------------
3084  * Perform lookups of aggregate function info, and initialize the
3085  * unchanging fields of the per-agg and per-trans data.
3086  *
3087  * We try to optimize by detecting duplicate aggregate functions so that
3088  * their state and final values are re-used, rather than needlessly being
3089  * re-calculated independently. We also detect aggregates that are not
3090  * the same, but which can share the same transition state.
3091  *
3092  * Scenarios:
3093  *
3094  * 1. Identical aggregate function calls appear in the query:
3095  *
3096  * SELECT SUM(x) FROM ... HAVING SUM(x) > 0
3097  *
3098  * Since these aggregates are identical, we only need to calculate
3099  * the value once. Both aggregates will share the same 'aggno' value.
3100  *
3101  * 2. Two different aggregate functions appear in the query, but the
3102  * aggregates have the same arguments, transition functions and
3103  * initial values (and, presumably, different final functions):
3104  *
3105  * SELECT AVG(x), STDDEV(x) FROM ...
3106  *
3107  * In this case we must create a new peragg for the varying aggregate,
3108  * and we need to call the final functions separately, but we need
3109  * only run the transition function once. (This requires that the
3110  * final functions be nondestructive of the transition state, but
3111  * that's required anyway for other reasons.)
3112  *
3113  * For either of these optimizations to be valid, all aggregate properties
3114  * used in the transition phase must be the same, including any modifiers
3115  * such as ORDER BY, DISTINCT and FILTER, and the arguments mustn't
3116  * contain any volatile functions.
3117  * -----------------
3118  */
3119  aggno = -1;
3120  transno = -1;
3121  foreach(l, aggstate->aggs)
3122  {
3123  AggrefExprState *aggrefstate = (AggrefExprState *) lfirst(l);
3124  Aggref *aggref = aggrefstate->aggref;
3125  AggStatePerAgg peragg;
3126  AggStatePerTrans pertrans;
3127  int existing_aggno;
3128  int existing_transno;
3129  List *same_input_transnos;
3130  Oid inputTypes[FUNC_MAX_ARGS];
3131  int numArguments;
3132  int numDirectArgs;
3133  HeapTuple aggTuple;
3134  Form_pg_aggregate aggform;
3135  AclResult aclresult;
3136  Oid transfn_oid,
3137  finalfn_oid;
3138  bool sharable;
3139  Oid serialfn_oid,
3141  Expr *finalfnexpr;
3142  Oid aggtranstype;
3143  Datum textInitVal;
3144  Datum initValue;
3145  bool initValueIsNull;
3146 
3147  /* Planner should have assigned aggregate to correct level */
3148  Assert(aggref->agglevelsup == 0);
3149  /* ... and the split mode should match */
3150  Assert(aggref->aggsplit == aggstate->aggsplit);
3151 
3152  /* 1. Check for already processed aggs which can be re-used */
3153  existing_aggno = find_compatible_peragg(aggref, aggstate, aggno,
3154  &same_input_transnos);
3155  if (existing_aggno != -1)
3156  {
3157  /*
3158  * Existing compatible agg found. so just point the Aggref to the
3159  * same per-agg struct.
3160  */
3161  aggrefstate->aggno = existing_aggno;
3162  continue;
3163  }
3164 
3165  /* Mark Aggref state node with assigned index in the result array */
3166  peragg = &peraggs[++aggno];
3167  peragg->aggref = aggref;
3168  aggrefstate->aggno = aggno;
3169 
3170  /* Fetch the pg_aggregate row */
3171  aggTuple = SearchSysCache1(AGGFNOID,
3172  ObjectIdGetDatum(aggref->aggfnoid));
3173  if (!HeapTupleIsValid(aggTuple))
3174  elog(ERROR, "cache lookup failed for aggregate %u",
3175  aggref->aggfnoid);
3176  aggform = (Form_pg_aggregate) GETSTRUCT(aggTuple);
3177 
3178  /* Check permission to call aggregate function */
3179  aclresult = pg_proc_aclcheck(aggref->aggfnoid, GetUserId(),
3180  ACL_EXECUTE);
3181  if (aclresult != ACLCHECK_OK)
3182  aclcheck_error(aclresult, ACL_KIND_PROC,
3183  get_func_name(aggref->aggfnoid));
3185 
3186  /* planner recorded transition state type in the Aggref itself */
3187  aggtranstype = aggref->aggtranstype;
3188  Assert(OidIsValid(aggtranstype));
3189 
3190  /*
3191  * If this aggregation is performing state combines, then instead of
3192  * using the transition function, we'll use the combine function
3193  */
3194  if (DO_AGGSPLIT_COMBINE(aggstate->aggsplit))
3195  {
3196  transfn_oid = aggform->aggcombinefn;
3197 
3198  /* If not set then the planner messed up */
3199  if (!OidIsValid(transfn_oid))
3200  elog(ERROR, "combinefn not set for aggregate function");
3201  }
3202  else
3203  transfn_oid = aggform->aggtransfn;
3204 
3205  /* Final function only required if we're finalizing the aggregates */
3206  if (DO_AGGSPLIT_SKIPFINAL(aggstate->aggsplit))
3207  peragg->finalfn_oid = finalfn_oid = InvalidOid;
3208  else
3209  peragg->finalfn_oid = finalfn_oid = aggform->aggfinalfn;
3210 
3211  /*
3212  * If finalfn is marked read-write, we can't share transition states;
3213  * but it is okay to share states for AGGMODIFY_SHARABLE aggs. Also,
3214  * if we're not executing the finalfn here, we can share regardless.
3215  */
3216  sharable = (aggform->aggfinalmodify != AGGMODIFY_READ_WRITE) ||
3217  (finalfn_oid == InvalidOid);
3218  peragg->sharable = sharable;
3219 
3220  serialfn_oid = InvalidOid;
3221  deserialfn_oid = InvalidOid;
3222 
3223  /*
3224  * Check if serialization/deserialization is required. We only do it
3225  * for aggregates that have transtype INTERNAL.
3226  */
3227  if (aggtranstype == INTERNALOID)
3228  {
3229  /*
3230  * The planner should only have generated a serialize agg node if
3231  * every aggregate with an INTERNAL state has a serialization
3232  * function. Verify that.
3233  */
3234  if (DO_AGGSPLIT_SERIALIZE(aggstate->aggsplit))
3235  {
3236  /* serialization only valid when not running finalfn */
3237  Assert(DO_AGGSPLIT_SKIPFINAL(aggstate->aggsplit));
3238 
3239  if (!OidIsValid(aggform->aggserialfn))
3240  elog(ERROR, "serialfunc not provided for serialization aggregation");
3241  serialfn_oid = aggform->aggserialfn;
3242  }
3243 
3244  /* Likewise for deserialization functions */
3245  if (DO_AGGSPLIT_DESERIALIZE(aggstate->aggsplit))
3246  {
3247  /* deserialization only valid when combining states */
3248  Assert(DO_AGGSPLIT_COMBINE(aggstate->aggsplit));
3249 
3250  if (!OidIsValid(aggform->aggdeserialfn))
3251  elog(ERROR, "deserialfunc not provided for deserialization aggregation");
3252  deserialfn_oid = aggform->aggdeserialfn;
3253  }
3254  }
3255 
3256  /* Check that aggregate owner has permission to call component fns */
3257  {
3258  HeapTuple procTuple;
3259  Oid aggOwner;
3260 
3261  procTuple = SearchSysCache1(PROCOID,
3262  ObjectIdGetDatum(aggref->aggfnoid));
3263  if (!HeapTupleIsValid(procTuple))
3264  elog(ERROR, "cache lookup failed for function %u",
3265  aggref->aggfnoid);
3266  aggOwner = ((Form_pg_proc) GETSTRUCT(procTuple))->proowner;
3267  ReleaseSysCache(procTuple);
3268 
3269  aclresult = pg_proc_aclcheck(transfn_oid, aggOwner,
3270  ACL_EXECUTE);
3271  if (aclresult != ACLCHECK_OK)
3272  aclcheck_error(aclresult, ACL_KIND_PROC,
3273  get_func_name(transfn_oid));
3274  InvokeFunctionExecuteHook(transfn_oid);
3275  if (OidIsValid(finalfn_oid))
3276  {
3277  aclresult = pg_proc_aclcheck(finalfn_oid, aggOwner,
3278  ACL_EXECUTE);
3279  if (aclresult != ACLCHECK_OK)
3280  aclcheck_error(aclresult, ACL_KIND_PROC,
3281  get_func_name(finalfn_oid));
3282  InvokeFunctionExecuteHook(finalfn_oid);
3283  }
3284  if (OidIsValid(serialfn_oid))
3285  {
3286  aclresult = pg_proc_aclcheck(serialfn_oid, aggOwner,
3287  ACL_EXECUTE);
3288  if (aclresult != ACLCHECK_OK)
3289  aclcheck_error(aclresult, ACL_KIND_PROC,
3290  get_func_name(serialfn_oid));
3291  InvokeFunctionExecuteHook(serialfn_oid);
3292  }
3293  if (OidIsValid(deserialfn_oid))
3294  {
3295  aclresult = pg_proc_aclcheck(deserialfn_oid, aggOwner,
3296  ACL_EXECUTE);
3297  if (aclresult != ACLCHECK_OK)
3298  aclcheck_error(aclresult, ACL_KIND_PROC,
3299  get_func_name(deserialfn_oid));
3300  InvokeFunctionExecuteHook(deserialfn_oid);
3301  }
3302  }
3303 
3304  /*
3305  * Get actual datatypes of the (nominal) aggregate inputs. These
3306  * could be different from the agg's declared input types, when the
3307  * agg accepts ANY or a polymorphic type.
3308  */
3309  numArguments = get_aggregate_argtypes(aggref, inputTypes);
3310 
3311  /* Count the "direct" arguments, if any */
3312  numDirectArgs = list_length(aggref->aggdirectargs);
3313 
3314  /* Detect how many arguments to pass to the finalfn */
3315  if (aggform->aggfinalextra)
3316  peragg->numFinalArgs = numArguments + 1;
3317  else
3318  peragg->numFinalArgs = numDirectArgs + 1;
3319 
3320  /* Initialize any direct-argument expressions */
3321  peragg->aggdirectargs = ExecInitExprList(aggref->aggdirectargs,
3322  (PlanState *) aggstate);
3323 
3324  /*
3325  * build expression trees using actual argument & result types for the
3326  * finalfn, if it exists and is required.
3327  */
3328  if (OidIsValid(finalfn_oid))
3329  {
3330  build_aggregate_finalfn_expr(inputTypes,
3331  peragg->numFinalArgs,
3332  aggtranstype,
3333  aggref->aggtype,
3334  aggref->inputcollid,
3335  finalfn_oid,
3336  &finalfnexpr);
3337  fmgr_info(finalfn_oid, &peragg->finalfn);
3338  fmgr_info_set_expr((Node *) finalfnexpr, &peragg->finalfn);
3339  }
3340 
3341  /* get info about the output value's datatype */
3342  get_typlenbyval(aggref->aggtype,
3343  &peragg->resulttypeLen,
3344  &peragg->resulttypeByVal);
3345 
3346  /*
3347  * initval is potentially null, so don't try to access it as a struct
3348  * field. Must do it the hard way with SysCacheGetAttr.
3349  */
3350  textInitVal = SysCacheGetAttr(AGGFNOID, aggTuple,
3352  &initValueIsNull);
3353  if (initValueIsNull)
3354  initValue = (Datum) 0;
3355  else
3356  initValue = GetAggInitVal(textInitVal, aggtranstype);
3357 
3358  /*
3359  * 2. Build working state for invoking the transition function, or
3360  * look up previously initialized working state, if we can share it.
3361  *
3362  * find_compatible_peragg() already collected a list of sharable
3363  * per-Trans's with the same inputs. Check if any of them have the
3364  * same transition function and initial value.
3365  */
3366  existing_transno = find_compatible_pertrans(aggstate, aggref,
3367  sharable,
3368  transfn_oid, aggtranstype,
3369  serialfn_oid, deserialfn_oid,
3370  initValue, initValueIsNull,
3371  same_input_transnos);
3372  if (existing_transno != -1)
3373  {
3374  /*
3375  * Existing compatible trans found, so just point the 'peragg' to
3376  * the same per-trans struct, and mark the trans state as shared.
3377  */
3378  pertrans = &pertransstates[existing_transno];
3379  pertrans->aggshared = true;
3380  peragg->transno = existing_transno;
3381  }
3382  else
3383  {
3384  pertrans = &pertransstates[++transno];
3385  build_pertrans_for_aggref(pertrans, aggstate, estate,
3386  aggref, transfn_oid, aggtranstype,
3387  serialfn_oid, deserialfn_oid,
3388  initValue, initValueIsNull,
3389  inputTypes, numArguments);
3390  peragg->transno = transno;
3391  }
3392  ReleaseSysCache(aggTuple);
3393  }
3394 
3395  /*
3396  * Update aggstate->numaggs to be the number of unique aggregates found.
3397  * Also set numstates to the number of unique transition states found.
3398  */
3399  aggstate->numaggs = aggno + 1;
3400  aggstate->numtrans = transno + 1;
3401 
3402  /*
3403  * Build a single projection computing the required arguments for all
3404  * aggregates at once; if there's more than one, that's considerably
3405  * faster than doing it separately for each.
3406  *
3407  * First create a targetlist representing the values to compute.
3408  */
3409  combined_inputeval = NIL;
3410  column_offset = 0;
3411  for (transno = 0; transno < aggstate->numtrans; transno++)
3412  {
3413  AggStatePerTrans pertrans = &pertransstates[transno];
3414 
3415  /*
3416  * Mark this per-trans state with its starting column in the combined
3417  * slot.
3418  */
3419  pertrans->inputoff = column_offset;
3420 
3421  /*
3422  * If the aggregate has a FILTER, we can only evaluate the filter
3423  * expression, not the actual input expressions, during the combined
3424  * eval step --- unless we're ignoring the filter because this node is
3425  * running combinefns not transfns.
3426  */
3427  if (pertrans->aggref->aggfilter &&
3428  !DO_AGGSPLIT_COMBINE(aggstate->aggsplit))
3429  {
3430  TargetEntry *tle;
3431 
3432  tle = makeTargetEntry(pertrans->aggref->aggfilter,
3433  column_offset + 1, NULL, false);
3434  combined_inputeval = lappend(combined_inputeval, tle);
3435  column_offset++;
3436 
3437  /*
3438  * We'll need separate projection machinery for the real args.
3439  * Arrange to evaluate them into the sortslot previously created.
3440  */
3441  Assert(pertrans->sortslot);
3442  pertrans->evalproj = ExecBuildProjectionInfo(pertrans->aggref->args,
3443  aggstate->tmpcontext,
3444  pertrans->sortslot,
3445  &aggstate->ss.ps,
3446  NULL);
3447  }
3448  else
3449  {
3450  /*
3451  * Add agg's input expressions to combined_inputeval, adjusting
3452  * resnos in the copied target entries to match the combined slot.
3453  */
3454  ListCell *arg;
3455 
3456  foreach(arg, pertrans->aggref->args)
3457  {
3458  TargetEntry *source_tle = lfirst_node(TargetEntry, arg);
3459  TargetEntry *tle;
3460 
3461  tle = flatCopyTargetEntry(source_tle);
3462  tle->resno += column_offset;
3463 
3464  combined_inputeval = lappend(combined_inputeval, tle);
3465  }
3466 
3467  column_offset += list_length(pertrans->aggref->args);
3468  }
3469  }
3470 
3471  /* Now create a projection for the combined targetlist */
3472  combineddesc = ExecTypeFromTL(combined_inputeval, false);
3473  combinedslot = ExecInitExtraTupleSlot(estate);
3474  ExecSetSlotDescriptor(combinedslot, combineddesc);
3475  aggstate->combinedproj = ExecBuildProjectionInfo(combined_inputeval,
3476  aggstate->tmpcontext,
3477  combinedslot,
3478  &aggstate->ss.ps,
3479  NULL);
3480 
3481  /*
3482  * Last, check whether any more aggregates got added onto the node while
3483  * we processed the expressions for the aggregate arguments (including not
3484  * only the regular arguments and FILTER expressions handled immediately
3485  * above, but any direct arguments we might've handled earlier). If so,
3486  * we have nested aggregate functions, which is semantically nonsensical,
3487  * so complain. (This should have been caught by the parser, so we don't
3488  * need to work hard on a helpful error message; but we defend against it
3489  * here anyway, just to be sure.)
3490  */
3491  if (numaggs != list_length(aggstate->aggs))
3492  ereport(ERROR,
3493  (errcode(ERRCODE_GROUPING_ERROR),
3494  errmsg("aggregate function calls cannot be nested")));
3495 
3496  return aggstate;
3497 }
3498 
3499 /*
3500  * Build the state needed to calculate a state value for an aggregate.
3501  *
3502  * This initializes all the fields in 'pertrans'. 'aggref' is the aggregate
3503  * to initialize the state for. 'aggtransfn', 'aggtranstype', and the rest
3504  * of the arguments could be calculated from 'aggref', but the caller has
3505  * calculated them already, so might as well pass them.
3506  */
3507 static void
3509  AggState *aggstate, EState *estate,
3510  Aggref *aggref,
3511  Oid aggtransfn, Oid aggtranstype,
3512  Oid aggserialfn, Oid aggdeserialfn,
3514  Oid *inputTypes, int numArguments)
3515 {
3516  int numGroupingSets = Max(aggstate->maxsets, 1);
3517  Expr *serialfnexpr = NULL;
3518  Expr *deserialfnexpr = NULL;
3519  ListCell *lc;
3520  int numInputs;
3521  int numDirectArgs;
3522  List *sortlist;
3523  int numSortCols;
3524  int numDistinctCols;
3525  int i;
3526 
3527  /* Begin filling in the pertrans data */
3528  pertrans->aggref = aggref;
3529  pertrans->aggshared = false;
3530  pertrans->aggCollation = aggref->inputcollid;
3531  pertrans->transfn_oid = aggtransfn;
3532  pertrans->serialfn_oid = aggserialfn;
3533  pertrans->deserialfn_oid = aggdeserialfn;
3534  pertrans->initValue = initValue;
3535  pertrans->initValueIsNull = initValueIsNull;
3536 
3537  /* Count the "direct" arguments, if any */
3538  numDirectArgs = list_length(aggref->aggdirectargs);
3539 
3540  /* Count the number of aggregated input columns */
3541  pertrans->numInputs = numInputs = list_length(aggref->args);
3542 
3543  pertrans->aggtranstype = aggtranstype;
3544 
3545  /* Detect how many arguments to pass to the transfn */
3546  if (AGGKIND_IS_ORDERED_SET(aggref->aggkind))
3547  pertrans->numTransInputs = numInputs;
3548  else
3549  pertrans->numTransInputs = numArguments;
3550 
3551  /* inputoff and evalproj will be set up later, in ExecInitAgg */
3552 
3553  /*
3554  * When combining states, we have no use at all for the aggregate
3555  * function's transfn. Instead we use the combinefn. In this case, the
3556  * transfn and transfn_oid fields of pertrans refer to the combine
3557  * function rather than the transition function.
3558  */
3559  if (DO_AGGSPLIT_COMBINE(aggstate->aggsplit))
3560  {
3561  Expr *combinefnexpr;
3562 
3563  build_aggregate_combinefn_expr(aggtranstype,
3564  aggref->inputcollid,
3565  aggtransfn,
3566  &combinefnexpr);
3567  fmgr_info(aggtransfn, &pertrans->transfn);
3568  fmgr_info_set_expr((Node *) combinefnexpr, &pertrans->transfn);
3569 
3571  &pertrans->transfn,
3572  2,
3573  pertrans->aggCollation,
3574  (void *) aggstate, NULL);
3575 
3576  /*
3577  * Ensure that a combine function to combine INTERNAL states is not
3578  * strict. This should have been checked during CREATE AGGREGATE, but
3579  * the strict property could have been changed since then.
3580  */
3581  if (pertrans->transfn.fn_strict && aggtranstype == INTERNALOID)
3582  ereport(ERROR,
3583  (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
3584  errmsg("combine function for aggregate %u must be declared as STRICT",
3585  aggref->aggfnoid)));
3586  }
3587  else
3588  {
3589  Expr *transfnexpr;
3590 
3591  /*
3592  * Set up infrastructure for calling the transfn. Note that invtrans
3593  * is not needed here.
3594  */
3595  build_aggregate_transfn_expr(inputTypes,
3596  numArguments,
3597  numDirectArgs,
3598  aggref->aggvariadic,
3599  aggtranstype,
3600  aggref->inputcollid,
3601  aggtransfn,
3602  InvalidOid,
3603  &transfnexpr,
3604  NULL);
3605  fmgr_info(aggtransfn, &pertrans->transfn);
3606  fmgr_info_set_expr((Node *) transfnexpr, &pertrans->transfn);
3607 
3609  &pertrans->transfn,
3610  pertrans->numTransInputs + 1,
3611  pertrans->aggCollation,
3612  (void *) aggstate, NULL);
3613 
3614  /*
3615  * If the transfn is strict and the initval is NULL, make sure input
3616  * type and transtype are the same (or at least binary-compatible), so
3617  * that it's OK to use the first aggregated input value as the initial
3618  * transValue. This should have been checked at agg definition time,
3619  * but we must check again in case the transfn's strictness property
3620  * has been changed.
3621  */
3622  if (pertrans->transfn.fn_strict && pertrans->initValueIsNull)
3623  {
3624  if (numArguments <= numDirectArgs ||
3625  !IsBinaryCoercible(inputTypes[numDirectArgs],
3626  aggtranstype))
3627  ereport(ERROR,
3628  (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
3629  errmsg("aggregate %u needs to have compatible input type and transition type",
3630  aggref->aggfnoid)));
3631  }
3632  }
3633 
3634  /* get info about the state value's datatype */
3635  get_typlenbyval(aggtranstype,
3636  &pertrans->transtypeLen,
3637  &pertrans->transtypeByVal);
3638 
3639  if (OidIsValid(aggserialfn))
3640  {
3641  build_aggregate_serialfn_expr(aggserialfn,
3642  &serialfnexpr);
3643  fmgr_info(aggserialfn, &pertrans->serialfn);
3644  fmgr_info_set_expr((Node *) serialfnexpr, &pertrans->serialfn);
3645 
3647  &pertrans->serialfn,
3648  1,
3649  InvalidOid,
3650  (void *) aggstate, NULL);
3651  }
3652 
3653  if (OidIsValid(aggdeserialfn))
3654  {
3655  build_aggregate_deserialfn_expr(aggdeserialfn,
3656  &deserialfnexpr);
3657  fmgr_info(aggdeserialfn, &pertrans->deserialfn);
3658  fmgr_info_set_expr((Node *) deserialfnexpr, &pertrans->deserialfn);
3659 
3661  &pertrans->deserialfn,
3662  2,
3663  InvalidOid,
3664  (void *) aggstate, NULL);
3665 
3666  }
3667 
3668  /*
3669  * If we're doing either DISTINCT or ORDER BY for a plain agg, then we
3670  * have a list of SortGroupClause nodes; fish out the data in them and
3671  * stick them into arrays. We ignore ORDER BY for an ordered-set agg,
3672  * however; the agg's transfn and finalfn are responsible for that.
3673  *
3674  * Note that by construction, if there is a DISTINCT clause then the ORDER
3675  * BY clause is a prefix of it (see transformDistinctClause).
3676  */
3677  if (AGGKIND_IS_ORDERED_SET(aggref->aggkind))
3678  {
3679  sortlist = NIL;
3680  numSortCols = numDistinctCols = 0;
3681  }
3682  else if (aggref->aggdistinct)
3683  {
3684  sortlist = aggref->aggdistinct;
3685  numSortCols = numDistinctCols = list_length(sortlist);
3686  Assert(numSortCols >= list_length(aggref->aggorder));
3687  }
3688  else
3689  {
3690  sortlist = aggref->aggorder;
3691  numSortCols = list_length(sortlist);
3692  numDistinctCols = 0;
3693  }
3694 
3695  pertrans->numSortCols = numSortCols;
3696  pertrans->numDistinctCols = numDistinctCols;
3697 
3698  /*
3699  * If we have either sorting or filtering to do, create a tupledesc and
3700  * slot corresponding to the aggregated inputs (including sort
3701  * expressions) of the agg.
3702  */
3703  if (numSortCols > 0 || aggref->aggfilter)
3704  {
3705  pertrans->sortdesc = ExecTypeFromTL(aggref->args, false);
3706  pertrans->sortslot = ExecInitExtraTupleSlot(estate);
3707  ExecSetSlotDescriptor(pertrans->sortslot, pertrans->sortdesc);
3708  }
3709 
3710  if (numSortCols > 0)
3711  {
3712  /*
3713  * We don't implement DISTINCT or ORDER BY aggs in the HASHED case
3714  * (yet)
3715  */
3716  Assert(aggstate->aggstrategy != AGG_HASHED && aggstate->aggstrategy != AGG_MIXED);
3717 
3718  /* If we have only one input, we need its len/byval info. */
3719  if (numInputs == 1)
3720  {
3721  get_typlenbyval(inputTypes[numDirectArgs],
3722  &pertrans->inputtypeLen,
3723  &pertrans->inputtypeByVal);
3724  }
3725  else if (numDistinctCols > 0)
3726  {
3727  /* we will need an extra slot to store prior values */
3728  pertrans->uniqslot = ExecInitExtraTupleSlot(estate);
3729  ExecSetSlotDescriptor(pertrans->uniqslot,
3730  pertrans->sortdesc);
3731  }
3732 
3733  /* Extract the sort information for use later */
3734  pertrans->sortColIdx =
3735  (AttrNumber *) palloc(numSortCols * sizeof(AttrNumber));
3736  pertrans->sortOperators =
3737  (Oid *) palloc(numSortCols * sizeof(Oid));
3738  pertrans->sortCollations =
3739  (Oid *) palloc(numSortCols * sizeof(Oid));
3740  pertrans->sortNullsFirst =
3741  (bool *) palloc(numSortCols * sizeof(bool));
3742 
3743  i = 0;
3744  foreach(lc, sortlist)
3745  {
3746  SortGroupClause *sortcl = (SortGroupClause *) lfirst(lc);
3747  TargetEntry *tle = get_sortgroupclause_tle(sortcl, aggref->args);
3748 
3749  /* the parser should have made sure of this */
3750  Assert(OidIsValid(sortcl->sortop));
3751 
3752  pertrans->sortColIdx[i] = tle->resno;
3753  pertrans->sortOperators[i] = sortcl->sortop;
3754  pertrans->sortCollations[i] = exprCollation((Node *) tle->expr);
3755  pertrans->sortNullsFirst[i] = sortcl->nulls_first;
3756  i++;
3757  }
3758  Assert(i == numSortCols);
3759  }
3760 
3761  if (aggref->aggdistinct)
3762  {
3763  Assert(numArguments > 0);
3764 
3765  /*
3766  * We need the equal function for each DISTINCT comparison we will
3767  * make.
3768  */
3769  pertrans->equalfns =
3770  (FmgrInfo *) palloc(numDistinctCols * sizeof(FmgrInfo));
3771 
3772  i = 0;
3773  foreach(lc, aggref->aggdistinct)
3774  {
3775  SortGroupClause *sortcl = (SortGroupClause *) lfirst(lc);
3776 
3777  fmgr_info(get_opcode(sortcl->eqop), &pertrans->equalfns[i]);
3778  i++;
3779  }
3780  Assert(i == numDistinctCols);
3781  }
3782 
3783  pertrans->sortstates = (Tuplesortstate **)
3784  palloc0(sizeof(Tuplesortstate *) * numGroupingSets);
3785 }
3786 
3787 
3788 static Datum
3789 GetAggInitVal(Datum textInitVal, Oid transtype)
3790 {
3791  Oid typinput,
3792  typioparam;
3793  char *strInitVal;
3794  Datum initVal;
3795 
3796  getTypeInputInfo(transtype, &typinput, &typioparam);
3797  strInitVal = TextDatumGetCString(textInitVal);
3798  initVal = OidInputFunctionCall(typinput, strInitVal,
3799  typioparam, -1);
3800  pfree(strInitVal);
3801  return initVal;
3802 }
3803 
3804 /*
3805  * find_compatible_peragg - search for a previously initialized per-Agg struct
3806  *
3807  * Searches the previously looked at aggregates to find one which is compatible
3808  * with this one, with the same input parameters. If no compatible aggregate
3809  * can be found, returns -1.
3810  *
3811  * As a side-effect, this also collects a list of existing, sharable per-Trans
3812  * structs with matching inputs. If no identical Aggref is found, the list is
3813  * passed later to find_compatible_pertrans, to see if we can at least reuse
3814  * the state value of another aggregate.
3815  */
3816 static int
3818  int lastaggno, List **same_input_transnos)
3819 {
3820  int aggno;
3821  AggStatePerAgg peraggs;
3822 
3823  *same_input_transnos = NIL;
3824 
3825  /* we mustn't reuse the aggref if it contains volatile function calls */
3826  if (contain_volatile_functions((Node *) newagg))
3827  return -1;
3828 
3829  peraggs = aggstate->peragg;
3830 
3831  /*
3832  * Search through the list of already seen aggregates. If we find an
3833  * existing identical aggregate call, then we can re-use that one. While
3834  * searching, we'll also collect a list of Aggrefs with the same input
3835  * parameters. If no matching Aggref is found, the caller can potentially
3836  * still re-use the transition state of one of them. (At this stage we
3837  * just compare the parsetrees; whether different aggregates share the
3838  * same transition function will be checked later.)
3839  */
3840  for (aggno = 0; aggno <= lastaggno; aggno++)
3841  {
3842  AggStatePerAgg peragg;
3843  Aggref *existingRef;
3844 
3845  peragg = &peraggs[aggno];
3846  existingRef = peragg->aggref;
3847 
3848  /* all of the following must be the same or it's no match */
3849  if (newagg->inputcollid != existingRef->inputcollid ||
3850  newagg->aggtranstype != existingRef->aggtranstype ||
3851  newagg->aggstar != existingRef->aggstar ||
3852  newagg->aggvariadic != existingRef->aggvariadic ||
3853  newagg->aggkind != existingRef->aggkind ||
3854  !equal(newagg->args, existingRef->args) ||
3855  !equal(newagg->aggorder, existingRef->aggorder) ||
3856  !equal(newagg->aggdistinct, existingRef->aggdistinct) ||
3857  !equal(newagg->aggfilter, existingRef->aggfilter))
3858  continue;
3859 
3860  /* if it's the same aggregate function then report exact match */
3861  if (newagg->aggfnoid == existingRef->aggfnoid &&
3862  newagg->aggtype == existingRef->aggtype &&
3863  newagg->aggcollid == existingRef->aggcollid &&
3864  equal(newagg->aggdirectargs, existingRef->aggdirectargs))
3865  {
3866  list_free(*same_input_transnos);
3867  *same_input_transnos = NIL;
3868  return aggno;
3869  }
3870 
3871  /*
3872  * Not identical, but it had the same inputs. If the final function
3873  * permits sharing, return its transno to the caller, in case we can
3874  * re-use its per-trans state. (If there's already sharing going on,
3875  * we might report a transno more than once. find_compatible_pertrans
3876  * is cheap enough that it's not worth spending cycles to avoid that.)
3877  */
3878  if (peragg->sharable)
3879  *same_input_transnos = lappend_int(*same_input_transnos,
3880  peragg->transno);
3881  }
3882 
3883  return -1;
3884 }
3885 
3886 /*
3887  * find_compatible_pertrans - search for a previously initialized per-Trans
3888  * struct
3889  *
3890  * Searches the list of transnos for a per-Trans struct with the same
3891  * transition function and initial condition. (The inputs have already been
3892  * verified to match.)
3893  */
3894 static int
3895 find_compatible_pertrans(AggState *aggstate, Aggref *newagg, bool sharable,
3896  Oid aggtransfn, Oid aggtranstype,
3897  Oid aggserialfn, Oid aggdeserialfn,
3899  List *transnos)
3900 {
3901  ListCell *lc;
3902 
3903  /* If this aggregate can't share transition states, give up */
3904  if (!sharable)
3905  return -1;
3906 
3907  foreach(lc, transnos)
3908  {
3909  int transno = lfirst_int(lc);
3910  AggStatePerTrans pertrans = &aggstate->pertrans[transno];
3911 
3912  /*
3913  * if the transfns or transition state types are not the same then the
3914  * state can't be shared.
3915  */
3916  if (aggtransfn != pertrans->transfn_oid ||
3917  aggtranstype != pertrans->aggtranstype)
3918  continue;
3919 
3920  /*
3921  * The serialization and deserialization functions must match, if
3922  * present, as we're unable to share the trans state for aggregates
3923  * which will serialize or deserialize into different formats.
3924  * Remember that these will be InvalidOid if they're not required for
3925  * this agg node.
3926  */
3927  if (aggserialfn != pertrans->serialfn_oid ||
3928  aggdeserialfn != pertrans->deserialfn_oid)
3929  continue;
3930 
3931  /*
3932  * Check that the initial condition matches, too.
3933  */
3934  if (initValueIsNull && pertrans->initValueIsNull)
3935  return transno;
3936 
3937  if (!initValueIsNull && !pertrans->initValueIsNull &&
3938  datumIsEqual(initValue, pertrans->initValue,
3939  pertrans->transtypeByVal, pertrans->transtypeLen))
3940  return transno;
3941  }
3942  return -1;
3943 }
3944 
3945 void
3947 {
3949  int transno;
3950  int numGroupingSets = Max(node->maxsets, 1);
3951  int setno;
3952 
3953  /* Make sure we have closed any open tuplesorts */
3954 
3955  if (node->sort_in)
3956  tuplesort_end(node->sort_in);
3957  if (node->sort_out)
3958  tuplesort_end(node->sort_out);
3959 
3960  for (transno = 0; transno < node->numtrans; transno++)
3961  {
3962  AggStatePerTrans pertrans = &node->pertrans[transno];
3963 
3964  for (setno = 0; setno < numGroupingSets; setno++)
3965  {
3966  if (pertrans->sortstates[setno])
3967  tuplesort_end(pertrans->sortstates[setno]);
3968  }
3969  }
3970 
3971  /* And ensure any agg shutdown callbacks have been called */
3972  for (setno = 0; setno < numGroupingSets; setno++)
3973  ReScanExprContext(node->aggcontexts[setno]);
3974  if (node->hashcontext)
3976 
3977  /*
3978  * We don't actually free any ExprContexts here (see comment in
3979  * ExecFreeExprContext), just unlinking the output one from the plan node
3980  * suffices.
3981  */
3982  ExecFreeExprContext(&node->ss.ps);
3983 
3984  /* clean up tuple table */
3986 
3987  outerPlan = outerPlanState(node);
3988  ExecEndNode(outerPlan);
3989 }
3990 
3991 void
3993 {
3994  ExprContext *econtext = node->ss.ps.ps_ExprContext;
3996  Agg *aggnode = (Agg *) node->ss.ps.plan;
3997  int transno;
3998  int numGroupingSets = Max(node->maxsets, 1);
3999  int setno;
4000 
4001  node->agg_done = false;
4002 
4003  if (node->aggstrategy == AGG_HASHED)
4004  {
4005  /*
4006  * In the hashed case, if we haven't yet built the hash table then we
4007  * can just return; nothing done yet, so nothing to undo. If subnode's
4008  * chgParam is not NULL then it will be re-scanned by ExecProcNode,
4009  * else no reason to re-scan it at all.
4010  */
4011  if (!node->table_filled)
4012  return;
4013 
4014  /*
4015  * If we do have the hash table, and the subplan does not have any
4016  * parameter changes, and none of our own parameter changes affect
4017  * input expressions of the aggregated functions, then we can just
4018  * rescan the existing hash table; no need to build it again.
4019  */
4020  if (outerPlan->chgParam == NULL &&
4021  !bms_overlap(node->ss.ps.chgParam, aggnode->aggParams))
4022  {
4024  &node->perhash[0].hashiter);
4025  select_current_set(node, 0, true);
4026  return;
4027  }
4028  }
4029 
4030  /* Make sure we have closed any open tuplesorts */
4031  for (transno = 0; transno < node->numtrans; transno++)
4032  {
4033  for (setno = 0; setno < numGroupingSets; setno++)
4034  {
4035  AggStatePerTrans pertrans = &node->pertrans[transno];
4036 
4037  if (pertrans->sortstates[setno])
4038  {
4039  tuplesort_end(pertrans->sortstates[setno]);
4040  pertrans->sortstates[setno] = NULL;
4041  }
4042  }
4043  }
4044 
4045  /*
4046  * We don't need to ReScanExprContext the output tuple context here;
4047  * ExecReScan already did it. But we do need to reset our per-grouping-set
4048  * contexts, which may have transvalues stored in them. (We use rescan
4049  * rather than just reset because transfns may have registered callbacks
4050  * that need to be run now.) For the AGG_HASHED case, see below.
4051  */
4052 
4053  for (setno = 0; setno < numGroupingSets; setno++)
4054  {
4055  ReScanExprContext(node->aggcontexts[setno]);
4056  }
4057 
4058  /* Release first tuple of group, if we have made a copy */
4059  if (node->grp_firstTuple != NULL)
4060  {
4062  node->grp_firstTuple = NULL;
4063  }
4065 
4066  /* Forget current agg values */
4067  MemSet(econtext->ecxt_aggvalues, 0, sizeof(Datum) * node->numaggs);
4068  MemSet(econtext->ecxt_aggnulls, 0, sizeof(bool) * node->numaggs);
4069 
4070  /*
4071  * With AGG_HASHED/MIXED, the hash table is allocated in a sub-context of
4072  * the hashcontext. This used to be an issue, but now, resetting a context
4073  * automatically deletes sub-contexts too.
4074  */
4075  if (node->aggstrategy == AGG_HASHED || node->aggstrategy == AGG_MIXED)
4076  {
4078  /* Rebuild an empty hash table */
4079  build_hash_table(node);
4080  node->table_filled = false;
4081  /* iterator will be reset when the table is filled */
4082  }
4083 
4084  if (node->aggstrategy != AGG_HASHED)
4085  {
4086  /*
4087  * Reset the per-group state (in particular, mark transvalues null)
4088  */
4089  MemSet(node->pergroup, 0,
4090  sizeof(AggStatePerGroupData) * node->numaggs * numGroupingSets);
4091 
4092  /* reset to phase 1 */
4093  initialize_phase(node, 1);
4094 
4095  node->input_done = false;
4096  node->projected_set = -1;
4097  }
4098 
4099  if (outerPlan->chgParam == NULL)
4100  ExecReScan(outerPlan);
4101 }
4102 
4103 
4104 /***********************************************************************
4105  * API exposed to aggregate functions
4106  ***********************************************************************/
4107 
4108 
4109 /*
4110  * AggCheckCallContext - test if a SQL function is being called as an aggregate
4111  *
4112  * The transition and/or final functions of an aggregate may want to verify
4113  * that they are being called as aggregates, rather than as plain SQL
4114  * functions. They should use this function to do so. The return value
4115  * is nonzero if being called as an aggregate, or zero if not. (Specific
4116  * nonzero values are AGG_CONTEXT_AGGREGATE or AGG_CONTEXT_WINDOW, but more
4117  * values could conceivably appear in future.)
4118  *
4119  * If aggcontext isn't NULL, the function also stores at *aggcontext the
4120  * identity of the memory context that aggregate transition values are being
4121  * stored in. Note that the same aggregate call site (flinfo) may be called
4122  * interleaved on different transition values in different contexts, so it's
4123  * not kosher to cache aggcontext under fn_extra. It is, however, kosher to
4124  * cache it in the transvalue itself (for internal-type transvalues).
4125  */
4126 int
4128 {
4129  if (fcinfo->context && IsA(fcinfo->context, AggState))
4130  {
4131  if (aggcontext)
4132  {
4133  AggState *aggstate = ((AggState *) fcinfo->context);
4134  ExprContext *cxt = aggstate->curaggcontext;
4135 
4136  *aggcontext = cxt->ecxt_per_tuple_memory;
4137  }
4138  return AGG_CONTEXT_AGGREGATE;
4139  }
4140  if (fcinfo->context && IsA(fcinfo->context, WindowAggState))
4141  {
4142  if (aggcontext)
4143  *aggcontext = ((WindowAggState *) fcinfo->context)->curaggcontext;
4144  return AGG_CONTEXT_WINDOW;
4145  }
4146 
4147  /* this is just to prevent "uninitialized variable" warnings */
4148  if (aggcontext)
4149  *aggcontext = NULL;
4150  return 0;
4151 }
4152 
4153 /*
4154  * AggGetAggref - allow an aggregate support function to get its Aggref
4155  *
4156  * If the function is being called as an aggregate support function,
4157  * return the Aggref node for the aggregate call. Otherwise, return NULL.
4158  *
4159  * Aggregates sharing the same inputs and transition functions can get
4160  * merged into a single transition calculation. If the transition function
4161  * calls AggGetAggref, it will get some one of the Aggrefs for which it is
4162  * executing. It must therefore not pay attention to the Aggref fields that
4163  * relate to the final function, as those are indeterminate. But if a final
4164  * function calls AggGetAggref, it will get a precise result.
4165  *
4166  * Note that if an aggregate is being used as a window function, this will
4167  * return NULL. We could provide a similar function to return the relevant
4168  * WindowFunc node in such cases, but it's not needed yet.
4169  */
4170 Aggref *
4172 {
4173  if (fcinfo->context && IsA(fcinfo->context, AggState))
4174  {
4175  AggState *aggstate = (AggState *) fcinfo->context;
4176  AggStatePerAgg curperagg;
4177  AggStatePerTrans curpertrans;
4178 
4179  /* check curperagg (valid when in a final function) */
4180  curperagg = aggstate->curperagg;
4181 
4182  if (curperagg)
4183  return curperagg->aggref;
4184 
4185  /* check curpertrans (valid when in a transition function) */
4186  curpertrans = aggstate->curpertrans;
4187 
4188  if (curpertrans)
4189  return curpertrans->aggref;
4190  }
4191  return NULL;
4192 }
4193 
4194 /*
4195  * AggGetTempMemoryContext - fetch short-term memory context for aggregates
4196  *
4197  * This is useful in agg final functions; the context returned is one that
4198  * the final function can safely reset as desired. This isn't useful for
4199  * transition functions, since the context returned MAY (we don't promise)
4200  * be the same as the context those are called in.
4201  *
4202  * As above, this is currently not useful for aggs called as window functions.
4203  */
4206 {
4207  if (fcinfo->context && IsA(fcinfo->context, AggState))
4208  {
4209  AggState *aggstate = (AggState *) fcinfo->context;
4210 
4211  return aggstate->tmpcontext->ecxt_per_tuple_memory;
4212  }
4213  return NULL;
4214 }
4215 
4216 /*
4217  * AggStateIsShared - find out whether transition state is shared
4218  *
4219  * If the function is being called as an aggregate support function,
4220  * return true if the aggregate's transition state is shared across
4221  * multiple aggregates, false if it is not.
4222  *
4223  * Returns true if not called as an aggregate support function.
4224  * This is intended as a conservative answer, ie "no you'd better not
4225  * scribble on your input". In particular, will return true if the
4226  * aggregate is being used as a window function, which is a scenario
4227  * in which changing the transition state is a bad idea. We might
4228  * want to refine the behavior for the window case in future.
4229  */
4230 bool
4232 {
4233  if (fcinfo->context && IsA(fcinfo->context, AggState))
4234  {
4235  AggState *aggstate = (AggState *) fcinfo->context;
4236  AggStatePerAgg curperagg;
4237  AggStatePerTrans curpertrans;
4238 
4239  /* check curperagg (valid when in a final function) */
4240  curperagg = aggstate->curperagg;
4241 
4242  if (curperagg)
4243  return aggstate->pertrans[curperagg->transno].aggshared;
4244 
4245  /* check curpertrans (valid when in a transition function) */
4246  curpertrans = aggstate->curpertrans;
4247 
4248  if (curpertrans)
4249  return curpertrans->aggshared;
4250  }
4251  return true;
4252 }
4253 
4254 /*
4255  * AggRegisterCallback - register a cleanup callback for an aggregate
4256  *
4257  * This is useful for aggs to register shutdown callbacks, which will ensure
4258  * that non-memory resources are freed. The callback will occur just before
4259  * the associated aggcontext (as returned by AggCheckCallContext) is reset,
4260  * either between groups or as a result of rescanning the query. The callback
4261  * will NOT be called on error paths. The typical use-case is for freeing of
4262  * tuplestores or tuplesorts maintained in aggcontext, or pins held by slots
4263  * created by the agg functions. (The callback will not be called until after
4264  * the result of the finalfn is no longer needed, so it's safe for the finalfn
4265  * to return data that will be freed by the callback.)
4266  *
4267  * As above, this is currently not useful for aggs called as window functions.
4268  */
4269 void
4272  Datum arg)
4273 {
4274  if (fcinfo->context && IsA(fcinfo->context, AggState))
4275  {
4276  AggState *aggstate = (AggState *) fcinfo->context;
4277  ExprContext *cxt = aggstate->curaggcontext;
4278 
4279  RegisterExprContextCallback(cxt, func, arg);
4280 
4281  return;
4282  }
4283  elog(ERROR, "aggregate function cannot register a callback in this context");
4284 }
4285 
4286 
4287 /*
4288  * aggregate_dummy - dummy execution routine for aggregate functions
4289  *
4290  * This function is listed as the implementation (prosrc field) of pg_proc
4291  * entries for aggregate functions. Its only purpose is to throw an error
4292  * if someone mistakenly executes such a function in the normal way.
4293  *
4294  * Perhaps someday we could assign real meaning to the prosrc field of
4295  * an aggregate?
4296  */
4297 Datum
4299 {
4300  elog(ERROR, "aggregate function %u called as normal function",
4301  fcinfo->flinfo->fn_oid);
4302  return (Datum) 0; /* keep compiler quiet */
4303 }
FmgrInfo * eqfunctions
Definition: nodeAgg.c:521
List * aggdistinct
Definition: primnodes.h:303
signed short int16
Definition: c.h:283
struct AggStatePerTransData * AggStatePerTrans
Definition: execnodes.h:1809
AggStatePerGroup * hash_pergroup
Definition: execnodes.h:1852
#define NIL
Definition: pg_list.h:69
static TupleTableSlot * fetch_input_tuple(AggState *aggstate)
Definition: nodeAgg.c:685
TupleTableSlot * ExecStoreTuple(HeapTuple tuple, TupleTableSlot *slot, Buffer buffer, bool shouldFree)
Definition: execTuples.c:320
struct AggStatePerGroupData * AggStatePerGroup
Definition: execnodes.h:1810
#define ScanTupleHashTable(htable, iter)
Definition: execnodes.h:637
static void select_current_set(AggState *aggstate, int setno, bool is_hash)
Definition: nodeAgg.c:597
int numCols
Definition: plannodes.h:786
Definition: fmgr.h:56
List * qual
Definition: plannodes.h:145
bool tuplesort_getdatum(Tuplesortstate *state, bool forward, Datum *val, bool *isNull, Datum *abbrev)
Definition: tuplesort.c:2081
Datum aggregate_dummy(PG_FUNCTION_ARGS)
Definition: nodeAgg.c:4298
bool aggvariadic
Definition: primnodes.h:306
bool tts_isempty
Definition: tuptable.h:116
int bms_first_member(Bitmapset *a)
Definition: bitmapset.c:957
AggStatePerPhase phases
Definition: execnodes.h:1841
#define IsA(nodeptr, _type_)
Definition: nodes.h:563
void tuplesort_performsort(Tuplesortstate *state)
Definition: tuplesort.c:1655
AttrNumber * hashGrpColIdxInput
Definition: nodeAgg.c:525
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate)
Definition: execTuples.c:852
Datum * ecxt_aggvalues
Definition: execnodes.h:214
TupleTableSlot * ExecStoreMinimalTuple(MinimalTuple mtup, TupleTableSlot *slot, bool shouldFree)
Definition: execTuples.c:384
Index varlevelsup
Definition: primnodes.h:173
TargetEntry * get_sortgroupclause_tle(SortGroupClause *sgClause, List *targetList)
Definition: tlist.c:370
void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate)
Definition: execTuples.c:842
#define AGGMODIFY_READ_WRITE
Definition: pg_aggregate.h:145
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
Bitmapset * bms_copy(const Bitmapset *a)
Definition: bitmapset.c:111
void tuplesort_putdatum(Tuplesortstate *state, Datum val, bool isNull)
Definition: tuplesort.c:1422
AttrNumber * grpColIdx
Definition: plannodes.h:787
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:885
#define Anum_pg_aggregate_agginitval
Definition: pg_aggregate.h:117
static void agg_fill_hash_table(AggState *aggstate)
Definition: nodeAgg.c:2534
List * lcons_int(int datum, List *list)
Definition: list.c:277
MemoryContext MemoryContextGetParent(MemoryContext context)
Definition: mcxt.c:402
TupleTableSlot * ExecStoreAllNullTuple(TupleTableSlot *slot)
Definition: execTuples.c:512
bool equal(const void *a, const void *b)
Definition: equalfuncs.c:2984
int numaggs
Definition: execnodes.h:1818
Oid GetUserId(void)
Definition: miscinit.c:284
bool agg_done
Definition: execnodes.h:1834
#define castNode(_type_, nodeptr)
Definition: nodes.h:581
void ExecEndNode(PlanState *node)
Definition: execProcnode.c:523
fmNodePtr context
Definition: fmgr.h:80
#define PointerGetDatum(X)
Definition: postgres.h:562
TupleTableSlot * sort_slot
Definition: execnodes.h:1844
List * all_grouped_cols
Definition: execnodes.h:1838
Tuplesortstate * sort_out
Definition: execnodes.h:1843
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:90
static void finalize_partialaggregate(AggState *aggstate, AggStatePerAgg peragg, AggStatePerGroup pergroupstate, Datum *resultVal, bool *resultIsNull)
Definition: nodeAgg.c:1632
ScanState ss
Definition: execnodes.h:1816
ExprContext * ps_ExprContext
Definition: execnodes.h:884
MinimalTuple firstTuple
Definition: execnodes.h:592
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:204
tuplehash_iterator TupleHashIterator
Definition: execnodes.h:624
static TupleHashEntryData * lookup_hash_entry(AggState *aggstate)
Definition: nodeAgg.c:2071
void ExecReScan(PlanState *node)
Definition: execAmi.c:76
int bms_next_member(const Bitmapset *a, int prevbit)
Definition: bitmapset.c:1009
bool datumIsEqual(Datum value1, Datum value2, bool typByVal, int typLen)
Definition: datum.c:219
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:439
FmgrInfo * eqfunctions
Definition: nodeAgg.c:503
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define FunctionCall2(flinfo, arg1, arg2)
Definition: fmgr.h:605
Oid inputcollid
Definition: primnodes.h:297
#define InvalidBuffer
Definition: buf.h:25
int current_phase
Definition: execnodes.h:1824
Definition: nodes.h:512
bool execTuplesMatch(TupleTableSlot *slot1, TupleTableSlot *slot2, int numCols, AttrNumber *matchColIdx, FmgrInfo *eqfunctions, MemoryContext evalContext)
Definition: execGrouping.c:69
AggSplit aggsplit
Definition: execnodes.h:1821
static TupleTableSlot * ExecAgg(PlanState *pstate)
Definition: nodeAgg.c:2145
bool * nullsFirst
Definition: plannodes.h:750
int errcode(int sqlerrcode)
Definition: elog.c:575
List * args
Definition: primnodes.h:301
#define MemSet(start, val, len)
Definition: c.h:853
AttrNumber varattno
Definition: primnodes.h:168
Datum * tts_values
Definition: tuptable.h:125
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1116
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:135
void build_aggregate_deserialfn_expr(Oid deserialfn_oid, Expr **deserialfnexpr)
Definition: parse_agg.c:2006
static void finalize_aggregate(AggState *aggstate, AggStatePerAgg peragg, AggStatePerGroup pergroupstate, Datum *resultVal, bool *resultIsNull)
Definition: nodeAgg.c:1530
void build_aggregate_finalfn_expr(Oid *agg_input_types, int num_finalfn_inputs, Oid agg_state_type, Oid agg_result_type, Oid agg_input_collation, Oid finalfn_oid, Expr **finalfnexpr)
Definition: parse_agg.c:2030
bool contain_volatile_functions(Node *clause)
Definition: clauses.c:957
AggStatePerTrans pertrans
Definition: execnodes.h:1826
EState * state
Definition: execnodes.h:852
int projected_set
Definition: execnodes.h:1835
bool aggstar
Definition: primnodes.h:305
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1373
unsigned int Oid
Definition: postgres_ext.h:31
static bool ExecQual(ExprState *state, ExprContext *econtext)
Definition: executor.h:356
HeapTuple grp_firstTuple
Definition: execnodes.h:1847
Definition: primnodes.h:163
Aggref * aggref
Definition: nodeAgg.c:415
static TupleTableSlot * project_aggregates(AggState *aggstate)
Definition: nodeAgg.c:1818
int current_set
Definition: execnodes.h:1836
#define OidIsValid(objectId)
Definition: c.h:576
#define DO_AGGSPLIT_COMBINE(as)
Definition: nodes.h:771
int natts
Definition: tupdesc.h:79
void ExecFreeExprContext(PlanState *planstate)
Definition: execUtils.c:603
int numtrans
Definition: execnodes.h:1819
TupleDesc sortdesc
Definition: nodeAgg.c:366
Oid * sortOperators
Definition: plannodes.h:748
void execTuplesHashPrepare(int numCols, Oid *eqOperators, FmgrInfo **eqFunctions, FmgrInfo **hashFunctions)
Definition: execGrouping.c:233
ExprState * ExecInitQual(List *qual, PlanState *parent)
Definition: execExpr.c:160
void ExecAssignResultTypeFromTL(PlanState *planstate)
Definition: execUtils.c:448
ExprContext * tmpcontext
Definition: execnodes.h:1829
FmgrInfo transfn
Definition: nodeAgg.c:302
static void prepare_projection_slot(AggState *aggstate, TupleTableSlot *slot, int currentSet)
Definition: nodeAgg.c:1710
FunctionCallInfoData transfn_fcinfo
Definition: nodeAgg.c:390
#define FUNC_MAX_ARGS
void slot_getsomeattrs(TupleTableSlot *slot, int attnum)
Definition: heaptuple.c:1282
#define linitial_int(l)
Definition: pg_list.h:112
Bitmapset ** grouped_cols
Definition: nodeAgg.c:502
PlanState ps
Definition: execnodes.h:1113
#define AGGKIND_IS_ORDERED_SET(kind)
Definition: pg_aggregate.h:133
int maxsets
Definition: execnodes.h:1840
FmgrInfo * flinfo
Definition: fmgr.h:79
#define DO_AGGSPLIT_SERIALIZE(as)
Definition: nodes.h:773
static AggStatePerGroup * lookup_hash_entries(AggState *aggstate)
Definition: nodeAgg.c:2116
static void initialize_aggregates(AggState *aggstate, AggStatePerGroup pergroup, int numReset)
Definition: nodeAgg.c:802
void pfree(void *pointer)
Definition: mcxt.c:949
AggStrategy aggstrategy
Definition: plannodes.h:784
AggState * ExecInitAgg(Agg *node, EState *estate, int eflags)
Definition: nodeAgg.c:2708
bool table_filled
Definition: execnodes.h:1849
AggStrategy aggstrategy
Definition: execnodes.h:1820
static TupleTableSlot * agg_retrieve_hash_table(AggState *aggstate)
Definition: nodeAgg.c:2581
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
bool fn_strict
Definition: fmgr.h:61
#define lfirst_int(lc)
Definition: pg_list.h:107
char * get_func_name(Oid funcid)
Definition: lsyscache.c:1412
void ExecInitResultTupleSlot(EState *estate, PlanState *planstate)
Definition: execTuples.c:832
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition: fmgr.c:122
static TupleTableSlot * agg_retrieve_direct(AggState *aggstate)
Definition: nodeAgg.c:2181
#define AGG_CONTEXT_AGGREGATE
Definition: fmgr.h:694
struct TupleHashEntryData TupleHashEntryData
static void find_hash_columns(AggState *aggstate)
Definition: nodeAgg.c:1948
struct AggStatePerTransData AggStatePerTransData
Tuplesortstate * sort_in
Definition: execnodes.h:1842
#define EXEC_FLAG_BACKWARD
Definition: executor.h:60
#define lfirst_node(type, lc)
Definition: pg_list.h:109
#define outerPlanState(node)
Definition: execnodes.h:896
bool tuplesort_gettupleslot(Tuplesortstate *state, bool forward, bool copy, TupleTableSlot *slot, Datum *abbrev)
Definition: tuplesort.c:1995
int bms_num_members(const Bitmapset *a)
Definition: bitmapset.c:605
static void finalize_aggregates(AggState *aggstate, AggStatePerAgg peragg, AggStatePerGroup pergroup)
Definition: nodeAgg.c:1755
Tuplesortstate * tuplesort_begin_datum(Oid datumType, Oid sortOperator, Oid sortCollation, bool nullsFirstFlag, int workMem, bool randomAccess)
Definition: tuplesort.c:975
bool AggStateIsShared(FunctionCallInfo fcinfo)
Definition: nodeAgg.c:4231
Aggref * aggref
Definition: execnodes.h:660
#define list_nth_node(type, list, n)
Definition: pg_list.h:227
Tuplesortstate ** sortstates
Definition: nodeAgg.c:382
void * list_nth(const List *list, int n)
Definition: list.c:410
#define FunctionCallInvoke(fcinfo)
Definition: fmgr.h:137
Bitmapset * aggParams
Definition: plannodes.h:790
MemoryContext tablecxt
Definition: execnodes.h:613
void ExecAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc)
Definition: execUtils.c:495
bool * tts_isnull
Definition: tuptable.h:126
static Datum ExecEvalExpr(ExprState *state, ExprContext *econtext, bool *isNull)
Definition: executor.h:276
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3457
static void process_ordered_aggregate_multi(AggState *aggstate, AggStatePerTrans pertrans, AggStatePerGroup pergroupstate)
Definition: nodeAgg.c:1437
List * aggorder
Definition: primnodes.h:302
static void build_hash_table(AggState *aggstate)
Definition: nodeAgg.c:1899
#define fmgr_info_set_expr(expr, finfo)
Definition: fmgr.h:104
AttrNumber resno
Definition: primnodes.h:1376
#define DatumGetBool(X)
Definition: postgres.h:399
List * ExecInitExprList(List *nodes, PlanState *parent)
Definition: execExpr.c:266
#define MakeExpandedObjectReadOnly(d, isnull, typlen)
Index agglevelsup
Definition: primnodes.h:309
#define TupIsNull(slot)
Definition: tuptable.h:138
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
List * aggdirectargs
Definition: primnodes.h:300
static Datum GetAggInitVal(Datum textInitVal, Oid transtype)
Definition: nodeAgg.c:3789
AggStatePerAgg curperagg
Definition: execnodes.h:1831
AttrNumber * sortColIdx
Definition: nodeAgg.c:321
static bool find_unaggregated_cols_walker(Node *node, Bitmapset **colnos)
Definition: nodeAgg.c:1859
AggStatePerHash perhash
Definition: execnodes.h:1851
bool argnull[FUNC_MAX_ARGS]
Definition: fmgr.h:86
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
TargetEntry * flatCopyTargetEntry(TargetEntry *src_tle)
Definition: makefuncs.c:270
TupleHashEntry LookupTupleHashEntry(TupleHashTable hashtable, TupleTableSlot *slot, bool *isnew)
Definition: execGrouping.c:351
AggStrategy aggstrategy
Definition: nodeAgg.c:499
#define InstrCountFiltered1(node, delta)
Definition: execnodes.h:899
#define EXEC_FLAG_REWIND
Definition: executor.h:59
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
Definition: lsyscache.c:2632
#define ereport(elevel, rest)
Definition: elog.h:122
void build_aggregate_combinefn_expr(Oid agg_state_type, Oid agg_input_collation, Oid combinefn_oid, Expr **combinefnexpr)
Definition: parse_agg.c:1954
TargetEntry * makeTargetEntry(Expr *expr, AttrNumber resno, char *resname, bool resjunk)
Definition: makefuncs.c:237
Bitmapset * grouped_cols
Definition: execnodes.h:1837
void slot_getallattrs(TupleTableSlot *slot)
Definition: heaptuple.c:1238
Datum datumCopy(Datum value, bool typByVal, int typLen)
Definition: datum.c:128
MemoryContext AggGetTempMemoryContext(FunctionCallInfo fcinfo)
Definition: nodeAgg.c:4205
List * lappend_int(List *list, int datum)
Definition: list.c:146
Bitmapset * chgParam
Definition: execnodes.h:878
TupleDesc ExecTypeFromTL(List *targetList, bool hasoid)
Definition: execTuples.c:888
#define InvokeFunctionExecuteHook(objectId)
Definition: objectaccess.h:179
bool IsBinaryCoercible(Oid srctype, Oid targettype)
#define outerPlan(node)
Definition: plannodes.h:174
List * lappend(List *list, void *datum)
Definition: list.c:128
ExpandedObjectHeader * DatumGetEOHP(Datum d)
Definition: expandeddatum.c:29
HeapTuple ExecCopySlotTuple(TupleTableSlot *slot)
Definition: execTuples.c:545
TupleHashIterator hashiter
Definition: nodeAgg.c:518
int numCols
Definition: plannodes.h:746
Index varno
Definition: primnodes.h:166
static void initialize_aggregate(AggState *aggstate, AggStatePerTrans pertrans, AggStatePerGroup pergroupstate)
Definition: nodeAgg.c:716
int num_hashes
Definition: execnodes.h:1850
Plan plan
Definition: plannodes.h:783
AttrNumber * hashGrpColIdxHash
Definition: nodeAgg.c:526
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
bool input_done
Definition: execnodes.h:1833
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:121
ProjectionInfo * combinedproj
Definition: execnodes.h:1854
ExprContext * curaggcontext
Definition: execnodes.h:1830
ExprContext * hashcontext
Definition: execnodes.h:1827
bool * ecxt_aggnulls
Definition: execnodes.h:215
static void advance_combine_function(AggState *aggstate, AggStatePerTrans pertrans, AggStatePerGroup pergroupstate)
Definition: nodeAgg.c:1212
#define TextDatumGetCString(d)
Definition: builtins.h:92
static int find_compatible_peragg(Aggref *newagg, AggState *aggstate, int lastaggno, List **same_input_transnos)
Definition: nodeAgg.c:3817
AggStatePerPhase phase
Definition: execnodes.h:1822
void * palloc0(Size size)
Definition: mcxt.c:877
ExecProcNodeMtd ExecProcNode
Definition: execnodes.h:856
AclResult
Definition: acl.h:178
uintptr_t Datum
Definition: postgres.h:372
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
void ExecSetSlotDescriptor(TupleTableSlot *slot, TupleDesc tupdesc)
Definition: execTuples.c:247
static TupleTableSlot * ExecProcNode(PlanState *node)
Definition: executor.h:236
FunctionCallInfoData serialfn_fcinfo
Definition: nodeAgg.c:393
AggStatePerGroup pergroup
Definition: execnodes.h:1846
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1368
FmgrInfo deserialfn
Definition: nodeAgg.c:308
int work_mem
Definition: globals.c:113
List * groupingSets
Definition: plannodes.h:792
int16 resulttypeLen
Definition: nodeAgg.c:444
static void initialize_phase(AggState *aggstate, int newphase)
Definition: nodeAgg.c:615
struct AggStatePerGroupData AggStatePerGroupData
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:83
Plan * plan
Definition: execnodes.h:850
void DeleteExpandedObject(Datum d)
#define InvalidOid
Definition: postgres_ext.h:36
RegProcedure get_opcode(Oid opno)
Definition: lsyscache.c:1094
Oid aggfnoid
Definition: primnodes.h:294
#define INTERNALOID
Definition: pg_type.h:698
#define ResetTupleHashIterator(htable, iter)
Definition: execnodes.h:635
static void advance_aggregates(AggState *aggstate, AggStatePerGroup pergroup, AggStatePerGroup *pergroups)
Definition: nodeAgg.c:979
static void advance_transition_function(AggState *aggstate, AggStatePerTrans pertrans, AggStatePerGroup pergroupstate)
Definition: nodeAgg.c:855
Datum arg[FUNC_MAX_ARGS]
Definition: fmgr.h:85
void bms_free(Bitmapset *a)
Definition: bitmapset.c:201
#define Max(x, y)
Definition: c.h:796
ExprContext ** aggcontexts
Definition: execnodes.h:1828
#define makeNode(_type_)
Definition: nodes.h:560
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:200
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
FmgrInfo * hashfunctions
Definition: nodeAgg.c:520
#define Assert(condition)
Definition: c.h:670
#define lfirst(lc)
Definition: pg_list.h:106
void RegisterExprContextCallback(ExprContext *econtext, ExprContextCallbackFunction function, Datum arg)
Definition: execUtils.c:819
FmgrInfo serialfn
Definition: nodeAgg.c:305
#define EXEC_FLAG_MARK
Definition: executor.h:61
AggSplit aggsplit
Definition: plannodes.h:785
struct AggStatePerAggData * AggStatePerAgg
Definition: execnodes.h:1808
void ExecReScanAgg(AggState *node)
Definition: nodeAgg.c:3992
#define DatumIsReadWriteExpandedObject(d, isnull, typlen)
void build_aggregate_serialfn_expr(Oid serialfn_oid, Expr **serialfnexpr)
Definition: parse_agg.c:1983
FormData_pg_aggregate * Form_pg_aggregate
Definition: pg_aggregate.h:89
Expr * expr
Definition: primnodes.h:1375
AggSplit aggsplit
Definition: primnodes.h:310
bool MemoryContextContains(MemoryContext context, void *pointer)
Definition: mcxt.c:566
void(* ExprContextCallbackFunction)(Datum arg)
Definition: execnodes.h:161
void build_aggregate_transfn_expr(Oid *agg_input_types, int agg_num_inputs, int agg_num_direct_inputs, bool agg_variadic, Oid agg_state_type, Oid agg_input_collation, Oid transfn_oid, Oid invtransfn_oid, Expr **transfnexpr, Expr **invtransfnexpr)
Definition: parse_agg.c:1893
ProjectionInfo * evalproj
Definition: nodeAgg.c:357
size_t Size
Definition: c.h:404
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:426
#define AGG_CONTEXT_WINDOW
Definition: fmgr.h:695
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)
Definition: fmgr.h:120
bool expression_tree_walker(Node *node, bool(*walker)(), void *context)
Definition: nodeFuncs.c:1834
static int list_length(const List *l)
Definition: pg_list.h:89
Size hash_agg_entry_size(int numAggs)
Definition: nodeAgg.c:2050
long numGroups
Definition: plannodes.h:789
Oid exprCollation(const Node *expr)
Definition: nodeFuncs.c:720
#define DO_AGGSPLIT_SKIPFINAL(as)
Definition: nodes.h:772
void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
Definition: lsyscache.c:2020
Expr * aggfilter
Definition: primnodes.h:304
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4127
#define MAXALIGN(LEN)
Definition: c.h:623
void ReScanExprContext(ExprContext *econtext)
Definition: execUtils.c:384
static Bitmapset * find_unaggregated_cols(AggState *aggstate)
Definition: nodeAgg.c:1845
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:698
#define DO_AGGSPLIT_DESERIALIZE(as)
Definition: nodes.h:774
TupleHashTable BuildTupleHashTable(int numCols, AttrNumber *keyColIdx, FmgrInfo *eqfunctions, FmgrInfo *hashfunctions, long nbuckets, Size additionalsize, MemoryContext tablecxt, MemoryContext tempcxt, bool use_variable_hash_iv)
Definition: execGrouping.c:290
struct Plan * lefttree
Definition: plannodes.h:146
TupleTableSlot * uniqslot
Definition: nodeAgg.c:365
int numphases
Definition: execnodes.h:1823
TupleDesc ExecGetResultType(PlanState *planstate)
Definition: execUtils.c:477
List * targetlist
Definition: plannodes.h:144
ExprState * qual
Definition: execnodes.h:868
#define DatumGetPointer(X)
Definition: postgres.h:555
AttrNumber * sortColIdx
Definition: plannodes.h:747
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:443
void AggRegisterCallback(FunctionCallInfo fcinfo, ExprContextCallbackFunction func, Datum arg)
Definition: nodeAgg.c:4270
AggStrategy
Definition: nodes.h:738
Tuplesortstate * tuplesort_begin_heap(TupleDesc tupDesc, int nkeys, AttrNumber *attNums, Oid *sortOperators, Oid *sortCollations, bool *nullsFirstFlags, int workMem, bool randomAccess)
Definition: tuplesort.c:693
void ExecAssignScanTypeFromOuterPlan(ScanState *scanstate)
Definition: execUtils.c:639
Oid * grpOperators
Definition: plannodes.h:788
void * palloc(Size size)
Definition: mcxt.c:848
ProjectionInfo * ExecBuildProjectionInfo(List *targetList, ExprContext *econtext, TupleTableSlot *slot, PlanState *parent, TupleDesc inputDesc)
Definition: execExpr.c:301
int errmsg(const char *fmt,...)
Definition: elog.c:797
Oid aggcollid
Definition: primnodes.h:296
List * chain
Definition: plannodes.h:793
AggStatePerAgg peragg
Definition: execnodes.h:1825
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:706
#define ACL_EXECUTE
Definition: parsenodes.h:79
void list_free(List *list)
Definition: list.c:1133
AclResult pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4504
int i
List * aggdirectargs
Definition: nodeAgg.c:438
struct AggStatePerPhaseData AggStatePerPhaseData
Oid aggtranstype
Definition: primnodes.h:298
static int find_compatible_pertrans(AggState *aggstate, Aggref *newagg, bool sharable, Oid aggtransfn, Oid aggtranstype, Oid aggserialfn, Oid aggdeserialfn, Datum initValue, bool initValueIsNull, List *transnos)
Definition: nodeAgg.c:3895
void * arg
AggStatePerTrans curpertrans
Definition: execnodes.h:1832
Oid aggtype
Definition: primnodes.h:295
FmgrInfo * equalfns
Definition: nodeAgg.c:331
static void process_ordered_aggregate_single(AggState *aggstate, AggStatePerTrans pertrans, AggStatePerGroup pergroupstate)
Definition: nodeAgg.c:1344
#define PG_FUNCTION_ARGS
Definition: fmgr.h:158
bool resulttypeByVal
Definition: nodeAgg.c:445
static void combine_aggregates(AggState *aggstate, AggStatePerGroup pergroup)
Definition: nodeAgg.c:1136
char aggkind
Definition: primnodes.h:308
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:98
Definition: plannodes.h:781
#define elog
Definition: elog.h:219
struct AggStatePerHashData AggStatePerHashData
List * aggs
Definition: execnodes.h:1817
struct AggStatePerAggData AggStatePerAggData
TupleTableSlot * sortslot
Definition: nodeAgg.c:364
void tuplesort_end(Tuplesortstate *state)
Definition: tuplesort.c:1104
FmgrInfo * execTuplesMatchPrepare(int numCols, Oid *eqOperators)
Definition: execGrouping.c:204
TupleTableSlot * hashslot
Definition: nodeAgg.c:519
Oid * collations
Definition: plannodes.h:749
int get_aggregate_argtypes(Aggref *aggref, Oid *inputTypes)
Definition: parse_agg.c:1812
static void build_pertrans_for_aggref(AggStatePerTrans pertrans, AggState *aggstate, EState *estate, Aggref *aggref, Oid aggtransfn, Oid aggtranstype, Oid aggserialfn, Oid aggdeserialfn, Datum initValue, bool initValueIsNull, Oid *inputTypes, int numArguments)
Definition: nodeAgg.c:3508
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
Definition: execProcnode.c:139
Bitmapset * bms_del_member(Bitmapset *a, int x)
Definition: bitmapset.c:735
FunctionCallInfoData deserialfn_fcinfo
Definition: nodeAgg.c:395
Definition: pg_list.h:45
bool bms_is_member(int x, const Bitmapset *a)
Definition: bitmapset.c:420
Datum OidInputFunctionCall(Oid functionId, char *str, Oid typioparam, int32 typmod)
Definition: fmgr.c:1733
TupleHashTable hashtable
Definition: nodeAgg.c:517
int16 AttrNumber
Definition: attnum.h:21
void ExecEndAgg(AggState *node)
Definition: nodeAgg.c:3946
#define OUTER_VAR
Definition: primnodes.h:154
FmgrInfo finalfn
Definition: nodeAgg.c:427
Bitmapset * bms_add_members(Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:755
static TupleTableSlot * ExecProject(ProjectionInfo *projInfo)
Definition: executor.h:319
#define ResetExprContext(econtext)
Definition: executor.h:461
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
Definition: execTuples.c:488
void tuplesort_puttupleslot(Tuplesortstate *state, TupleTableSlot *slot)
Definition: tuplesort.c:1301
Aggref * AggGetAggref(FunctionCallInfo fcinfo)
Definition: nodeAgg.c:4171
bool * sortNullsFirst
Definition: nodeAgg.c:324