PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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,
580  Datum initValue, bool initValueIsNull,
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,
588  Datum initValue, bool initValueIsNull,
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 
1251  /* We run the combine functions in per-input-tuple memory context */
1252  oldContext = MemoryContextSwitchTo(aggstate->tmpcontext->ecxt_per_tuple_memory);
1253 
1254  /* set up aggstate->curpertrans for AggGetAggref() */
1255  aggstate->curpertrans = pertrans;
1256 
1257  /*
1258  * OK to call the combine function
1259  */
1260  fcinfo->arg[0] = pergroupstate->transValue;
1261  fcinfo->argnull[0] = pergroupstate->transValueIsNull;
1262  fcinfo->isnull = false; /* just in case combine func doesn't set it */
1263 
1264  newVal = FunctionCallInvoke(fcinfo);
1265 
1266  aggstate->curpertrans = NULL;
1267 
1268  /*
1269  * If pass-by-ref datatype, must copy the new value into aggcontext and
1270  * free the prior transValue. But if the combine function returned a
1271  * pointer to its first input, we don't need to do anything. Also, if the
1272  * combine function returned a pointer to a R/W expanded object that is
1273  * already a child of the aggcontext, assume we can adopt that value
1274  * without copying it.
1275  */
1276  if (!pertrans->transtypeByVal &&
1277  DatumGetPointer(newVal) != DatumGetPointer(pergroupstate->transValue))
1278  {
1279  if (!fcinfo->isnull)
1280  {
1282  if (DatumIsReadWriteExpandedObject(newVal,
1283  false,
1284  pertrans->transtypeLen) &&
1285  MemoryContextGetParent(DatumGetEOHP(newVal)->eoh_context) == CurrentMemoryContext)
1286  /* do nothing */ ;
1287  else
1288  newVal = datumCopy(newVal,
1289  pertrans->transtypeByVal,
1290  pertrans->transtypeLen);
1291  }
1292  if (!pergroupstate->transValueIsNull)
1293  {
1294  if (DatumIsReadWriteExpandedObject(pergroupstate->transValue,
1295  false,
1296  pertrans->transtypeLen))
1297  DeleteExpandedObject(pergroupstate->transValue);
1298  else
1299  pfree(DatumGetPointer(pergroupstate->transValue));
1300  }
1301  }
1302 
1303  pergroupstate->transValue = newVal;
1304  pergroupstate->transValueIsNull = fcinfo->isnull;
1305 
1306  MemoryContextSwitchTo(oldContext);
1307 }
1308 
1309 
1310 /*
1311  * Run the transition function for a DISTINCT or ORDER BY aggregate
1312  * with only one input. This is called after we have completed
1313  * entering all the input values into the sort object. We complete the
1314  * sort, read out the values in sorted order, and run the transition
1315  * function on each value (applying DISTINCT if appropriate).
1316  *
1317  * Note that the strictness of the transition function was checked when
1318  * entering the values into the sort, so we don't check it again here;
1319  * we just apply standard SQL DISTINCT logic.
1320  *
1321  * The one-input case is handled separately from the multi-input case
1322  * for performance reasons: for single by-value inputs, such as the
1323  * common case of count(distinct id), the tuplesort_getdatum code path
1324  * is around 300% faster. (The speedup for by-reference types is less
1325  * but still noticeable.)
1326  *
1327  * This function handles only one grouping set (already set in
1328  * aggstate->current_set).
1329  *
1330  * When called, CurrentMemoryContext should be the per-query context.
1331  */
1332 static void
1334  AggStatePerTrans pertrans,
1335  AggStatePerGroup pergroupstate)
1336 {
1337  Datum oldVal = (Datum) 0;
1338  bool oldIsNull = true;
1339  bool haveOldVal = false;
1340  MemoryContext workcontext = aggstate->tmpcontext->ecxt_per_tuple_memory;
1341  MemoryContext oldContext;
1342  bool isDistinct = (pertrans->numDistinctCols > 0);
1343  Datum newAbbrevVal = (Datum) 0;
1344  Datum oldAbbrevVal = (Datum) 0;
1345  FunctionCallInfo fcinfo = &pertrans->transfn_fcinfo;
1346  Datum *newVal;
1347  bool *isNull;
1348 
1349  Assert(pertrans->numDistinctCols < 2);
1350 
1351  tuplesort_performsort(pertrans->sortstates[aggstate->current_set]);
1352 
1353  /* Load the column into argument 1 (arg 0 will be transition value) */
1354  newVal = fcinfo->arg + 1;
1355  isNull = fcinfo->argnull + 1;
1356 
1357  /*
1358  * Note: if input type is pass-by-ref, the datums returned by the sort are
1359  * freshly palloc'd in the per-query context, so we must be careful to
1360  * pfree them when they are no longer needed.
1361  */
1362 
1363  while (tuplesort_getdatum(pertrans->sortstates[aggstate->current_set],
1364  true, newVal, isNull, &newAbbrevVal))
1365  {
1366  /*
1367  * Clear and select the working context for evaluation of the equality
1368  * function and transition function.
1369  */
1370  MemoryContextReset(workcontext);
1371  oldContext = MemoryContextSwitchTo(workcontext);
1372 
1373  /*
1374  * If DISTINCT mode, and not distinct from prior, skip it.
1375  *
1376  * Note: we assume equality functions don't care about collation.
1377  */
1378  if (isDistinct &&
1379  haveOldVal &&
1380  ((oldIsNull && *isNull) ||
1381  (!oldIsNull && !*isNull &&
1382  oldAbbrevVal == newAbbrevVal &&
1383  DatumGetBool(FunctionCall2(&pertrans->equalfns[0],
1384  oldVal, *newVal)))))
1385  {
1386  /* equal to prior, so forget this one */
1387  if (!pertrans->inputtypeByVal && !*isNull)
1388  pfree(DatumGetPointer(*newVal));
1389  }
1390  else
1391  {
1392  advance_transition_function(aggstate, pertrans, pergroupstate);
1393  /* forget the old value, if any */
1394  if (!oldIsNull && !pertrans->inputtypeByVal)
1395  pfree(DatumGetPointer(oldVal));
1396  /* and remember the new one for subsequent equality checks */
1397  oldVal = *newVal;
1398  oldAbbrevVal = newAbbrevVal;
1399  oldIsNull = *isNull;
1400  haveOldVal = true;
1401  }
1402 
1403  MemoryContextSwitchTo(oldContext);
1404  }
1405 
1406  if (!oldIsNull && !pertrans->inputtypeByVal)
1407  pfree(DatumGetPointer(oldVal));
1408 
1409  tuplesort_end(pertrans->sortstates[aggstate->current_set]);
1410  pertrans->sortstates[aggstate->current_set] = NULL;
1411 }
1412 
1413 /*
1414  * Run the transition function for a DISTINCT or ORDER BY aggregate
1415  * with more than one input. This is called after we have completed
1416  * entering all the input values into the sort object. We complete the
1417  * sort, read out the values in sorted order, and run the transition
1418  * function on each value (applying DISTINCT if appropriate).
1419  *
1420  * This function handles only one grouping set (already set in
1421  * aggstate->current_set).
1422  *
1423  * When called, CurrentMemoryContext should be the per-query context.
1424  */
1425 static void
1427  AggStatePerTrans pertrans,
1428  AggStatePerGroup pergroupstate)
1429 {
1430  MemoryContext workcontext = aggstate->tmpcontext->ecxt_per_tuple_memory;
1431  FunctionCallInfo fcinfo = &pertrans->transfn_fcinfo;
1432  TupleTableSlot *slot1 = pertrans->sortslot;
1433  TupleTableSlot *slot2 = pertrans->uniqslot;
1434  int numTransInputs = pertrans->numTransInputs;
1435  int numDistinctCols = pertrans->numDistinctCols;
1436  Datum newAbbrevVal = (Datum) 0;
1437  Datum oldAbbrevVal = (Datum) 0;
1438  bool haveOldValue = false;
1439  int i;
1440 
1441  tuplesort_performsort(pertrans->sortstates[aggstate->current_set]);
1442 
1443  ExecClearTuple(slot1);
1444  if (slot2)
1445  ExecClearTuple(slot2);
1446 
1447  while (tuplesort_gettupleslot(pertrans->sortstates[aggstate->current_set],
1448  true, true, slot1, &newAbbrevVal))
1449  {
1451 
1452  /*
1453  * Extract the first numTransInputs columns as datums to pass to the
1454  * transfn. (This will help execTuplesMatch too, so we do it
1455  * immediately.)
1456  */
1457  slot_getsomeattrs(slot1, numTransInputs);
1458 
1459  if (numDistinctCols == 0 ||
1460  !haveOldValue ||
1461  newAbbrevVal != oldAbbrevVal ||
1462  !execTuplesMatch(slot1, slot2,
1463  numDistinctCols,
1464  pertrans->sortColIdx,
1465  pertrans->equalfns,
1466  workcontext))
1467  {
1468  /* Load values into fcinfo */
1469  /* Start from 1, since the 0th arg will be the transition value */
1470  for (i = 0; i < numTransInputs; i++)
1471  {
1472  fcinfo->arg[i + 1] = slot1->tts_values[i];
1473  fcinfo->argnull[i + 1] = slot1->tts_isnull[i];
1474  }
1475 
1476  advance_transition_function(aggstate, pertrans, pergroupstate);
1477 
1478  if (numDistinctCols > 0)
1479  {
1480  /* swap the slot pointers to retain the current tuple */
1481  TupleTableSlot *tmpslot = slot2;
1482 
1483  slot2 = slot1;
1484  slot1 = tmpslot;
1485  /* avoid execTuplesMatch() calls by reusing abbreviated keys */
1486  oldAbbrevVal = newAbbrevVal;
1487  haveOldValue = true;
1488  }
1489  }
1490 
1491  /* Reset context each time, unless execTuplesMatch did it for us */
1492  if (numDistinctCols == 0)
1493  MemoryContextReset(workcontext);
1494 
1495  ExecClearTuple(slot1);
1496  }
1497 
1498  if (slot2)
1499  ExecClearTuple(slot2);
1500 
1501  tuplesort_end(pertrans->sortstates[aggstate->current_set]);
1502  pertrans->sortstates[aggstate->current_set] = NULL;
1503 }
1504 
1505 /*
1506  * Compute the final value of one aggregate.
1507  *
1508  * This function handles only one grouping set (already set in
1509  * aggstate->current_set).
1510  *
1511  * The finalfunction will be run, and the result delivered, in the
1512  * output-tuple context; caller's CurrentMemoryContext does not matter.
1513  *
1514  * The finalfn uses the state as set in the transno. This also might be
1515  * being used by another aggregate function, so it's important that we do
1516  * nothing destructive here.
1517  */
1518 static void
1520  AggStatePerAgg peragg,
1521  AggStatePerGroup pergroupstate,
1522  Datum *resultVal, bool *resultIsNull)
1523 {
1524  FunctionCallInfoData fcinfo;
1525  bool anynull = false;
1526  MemoryContext oldContext;
1527  int i;
1528  ListCell *lc;
1529  AggStatePerTrans pertrans = &aggstate->pertrans[peragg->transno];
1530 
1532 
1533  /*
1534  * Evaluate any direct arguments. We do this even if there's no finalfn
1535  * (which is unlikely anyway), so that side-effects happen as expected.
1536  * The direct arguments go into arg positions 1 and up, leaving position 0
1537  * for the transition state value.
1538  */
1539  i = 1;
1540  foreach(lc, peragg->aggdirectargs)
1541  {
1542  ExprState *expr = (ExprState *) lfirst(lc);
1543 
1544  fcinfo.arg[i] = ExecEvalExpr(expr,
1545  aggstate->ss.ps.ps_ExprContext,
1546  &fcinfo.argnull[i]);
1547  anynull |= fcinfo.argnull[i];
1548  i++;
1549  }
1550 
1551  /*
1552  * Apply the agg's finalfn if one is provided, else return transValue.
1553  */
1554  if (OidIsValid(peragg->finalfn_oid))
1555  {
1556  int numFinalArgs = peragg->numFinalArgs;
1557 
1558  /* set up aggstate->curperagg for AggGetAggref() */
1559  aggstate->curperagg = peragg;
1560 
1561  InitFunctionCallInfoData(fcinfo, &peragg->finalfn,
1562  numFinalArgs,
1563  pertrans->aggCollation,
1564  (void *) aggstate, NULL);
1565 
1566  /* Fill in the transition state value */
1567  fcinfo.arg[0] = MakeExpandedObjectReadOnly(pergroupstate->transValue,
1568  pergroupstate->transValueIsNull,
1569  pertrans->transtypeLen);
1570  fcinfo.argnull[0] = pergroupstate->transValueIsNull;
1571  anynull |= pergroupstate->transValueIsNull;
1572 
1573  /* Fill any remaining argument positions with nulls */
1574  for (; i < numFinalArgs; i++)
1575  {
1576  fcinfo.arg[i] = (Datum) 0;
1577  fcinfo.argnull[i] = true;
1578  anynull = true;
1579  }
1580 
1581  if (fcinfo.flinfo->fn_strict && anynull)
1582  {
1583  /* don't call a strict function with NULL inputs */
1584  *resultVal = (Datum) 0;
1585  *resultIsNull = true;
1586  }
1587  else
1588  {
1589  *resultVal = FunctionCallInvoke(&fcinfo);
1590  *resultIsNull = fcinfo.isnull;
1591  }
1592  aggstate->curperagg = NULL;
1593  }
1594  else
1595  {
1596  /* Don't need MakeExpandedObjectReadOnly; datumCopy will copy it */
1597  *resultVal = pergroupstate->transValue;
1598  *resultIsNull = pergroupstate->transValueIsNull;
1599  }
1600 
1601  /*
1602  * If result is pass-by-ref, make sure it is in the right context.
1603  */
1604  if (!peragg->resulttypeByVal && !*resultIsNull &&
1606  DatumGetPointer(*resultVal)))
1607  *resultVal = datumCopy(*resultVal,
1608  peragg->resulttypeByVal,
1609  peragg->resulttypeLen);
1610 
1611  MemoryContextSwitchTo(oldContext);
1612 }
1613 
1614 /*
1615  * Compute the output value of one partial aggregate.
1616  *
1617  * The serialization function will be run, and the result delivered, in the
1618  * output-tuple context; caller's CurrentMemoryContext does not matter.
1619  */
1620 static void
1622  AggStatePerAgg peragg,
1623  AggStatePerGroup pergroupstate,
1624  Datum *resultVal, bool *resultIsNull)
1625 {
1626  AggStatePerTrans pertrans = &aggstate->pertrans[peragg->transno];
1627  MemoryContext oldContext;
1628 
1630 
1631  /*
1632  * serialfn_oid will be set if we must serialize the transvalue before
1633  * returning it
1634  */
1635  if (OidIsValid(pertrans->serialfn_oid))
1636  {
1637  /* Don't call a strict serialization function with NULL input. */
1638  if (pertrans->serialfn.fn_strict && pergroupstate->transValueIsNull)
1639  {
1640  *resultVal = (Datum) 0;
1641  *resultIsNull = true;
1642  }
1643  else
1644  {
1645  FunctionCallInfo fcinfo = &pertrans->serialfn_fcinfo;
1646 
1647  fcinfo->arg[0] = MakeExpandedObjectReadOnly(pergroupstate->transValue,
1648  pergroupstate->transValueIsNull,
1649  pertrans->transtypeLen);
1650  fcinfo->argnull[0] = pergroupstate->transValueIsNull;
1651 
1652  *resultVal = FunctionCallInvoke(fcinfo);
1653  *resultIsNull = fcinfo->isnull;
1654  }
1655  }
1656  else
1657  {
1658  /* Don't need MakeExpandedObjectReadOnly; datumCopy will copy it */
1659  *resultVal = pergroupstate->transValue;
1660  *resultIsNull = pergroupstate->transValueIsNull;
1661  }
1662 
1663  /* If result is pass-by-ref, make sure it is in the right context. */
1664  if (!peragg->resulttypeByVal && !*resultIsNull &&
1666  DatumGetPointer(*resultVal)))
1667  *resultVal = datumCopy(*resultVal,
1668  peragg->resulttypeByVal,
1669  peragg->resulttypeLen);
1670 
1671  MemoryContextSwitchTo(oldContext);
1672 }
1673 
1674 /*
1675  * Prepare to finalize and project based on the specified representative tuple
1676  * slot and grouping set.
1677  *
1678  * In the specified tuple slot, force to null all attributes that should be
1679  * read as null in the context of the current grouping set. Also stash the
1680  * current group bitmap where GroupingExpr can get at it.
1681  *
1682  * This relies on three conditions:
1683  *
1684  * 1) Nothing is ever going to try and extract the whole tuple from this slot,
1685  * only reference it in evaluations, which will only access individual
1686  * attributes.
1687  *
1688  * 2) No system columns are going to need to be nulled. (If a system column is
1689  * referenced in a group clause, it is actually projected in the outer plan
1690  * tlist.)
1691  *
1692  * 3) Within a given phase, we never need to recover the value of an attribute
1693  * once it has been set to null.
1694  *
1695  * Poking into the slot this way is a bit ugly, but the consensus is that the
1696  * alternative was worse.
1697  */
1698 static void
1699 prepare_projection_slot(AggState *aggstate, TupleTableSlot *slot, int currentSet)
1700 {
1701  if (aggstate->phase->grouped_cols)
1702  {
1703  Bitmapset *grouped_cols = aggstate->phase->grouped_cols[currentSet];
1704 
1705  aggstate->grouped_cols = grouped_cols;
1706 
1707  if (slot->tts_isempty)
1708  {
1709  /*
1710  * Force all values to be NULL if working on an empty input tuple
1711  * (i.e. an empty grouping set for which no input rows were
1712  * supplied).
1713  */
1714  ExecStoreAllNullTuple(slot);
1715  }
1716  else if (aggstate->all_grouped_cols)
1717  {
1718  ListCell *lc;
1719 
1720  /* all_grouped_cols is arranged in desc order */
1722 
1723  foreach(lc, aggstate->all_grouped_cols)
1724  {
1725  int attnum = lfirst_int(lc);
1726 
1727  if (!bms_is_member(attnum, grouped_cols))
1728  slot->tts_isnull[attnum - 1] = true;
1729  }
1730  }
1731  }
1732 }
1733 
1734 /*
1735  * Compute the final value of all aggregates for one group.
1736  *
1737  * This function handles only one grouping set at a time, which the caller must
1738  * have selected. It's also the caller's responsibility to adjust the supplied
1739  * pergroup parameter to point to the current set's transvalues.
1740  *
1741  * Results are stored in the output econtext aggvalues/aggnulls.
1742  */
1743 static void
1745  AggStatePerAgg peraggs,
1746  AggStatePerGroup pergroup)
1747 {
1748  ExprContext *econtext = aggstate->ss.ps.ps_ExprContext;
1749  Datum *aggvalues = econtext->ecxt_aggvalues;
1750  bool *aggnulls = econtext->ecxt_aggnulls;
1751  int aggno;
1752  int transno;
1753 
1754  /*
1755  * If there were any DISTINCT and/or ORDER BY aggregates, sort their
1756  * inputs and run the transition functions.
1757  */
1758  for (transno = 0; transno < aggstate->numtrans; transno++)
1759  {
1760  AggStatePerTrans pertrans = &aggstate->pertrans[transno];
1761  AggStatePerGroup pergroupstate;
1762 
1763  pergroupstate = &pergroup[transno];
1764 
1765  if (pertrans->numSortCols > 0)
1766  {
1767  Assert(aggstate->aggstrategy != AGG_HASHED &&
1768  aggstate->aggstrategy != AGG_MIXED);
1769 
1770  if (pertrans->numInputs == 1)
1772  pertrans,
1773  pergroupstate);
1774  else
1776  pertrans,
1777  pergroupstate);
1778  }
1779  }
1780 
1781  /*
1782  * Run the final functions.
1783  */
1784  for (aggno = 0; aggno < aggstate->numaggs; aggno++)
1785  {
1786  AggStatePerAgg peragg = &peraggs[aggno];
1787  int transno = peragg->transno;
1788  AggStatePerGroup pergroupstate;
1789 
1790  pergroupstate = &pergroup[transno];
1791 
1792  if (DO_AGGSPLIT_SKIPFINAL(aggstate->aggsplit))
1793  finalize_partialaggregate(aggstate, peragg, pergroupstate,
1794  &aggvalues[aggno], &aggnulls[aggno]);
1795  else
1796  finalize_aggregate(aggstate, peragg, pergroupstate,
1797  &aggvalues[aggno], &aggnulls[aggno]);
1798  }
1799 }
1800 
1801 /*
1802  * Project the result of a group (whose aggs have already been calculated by
1803  * finalize_aggregates). Returns the result slot, or NULL if no row is
1804  * projected (suppressed by qual).
1805  */
1806 static TupleTableSlot *
1808 {
1809  ExprContext *econtext = aggstate->ss.ps.ps_ExprContext;
1810 
1811  /*
1812  * Check the qual (HAVING clause); if the group does not match, ignore it.
1813  */
1814  if (ExecQual(aggstate->ss.ps.qual, econtext))
1815  {
1816  /*
1817  * Form and return projection tuple using the aggregate results and
1818  * the representative input tuple.
1819  */
1820  return ExecProject(aggstate->ss.ps.ps_ProjInfo);
1821  }
1822  else
1823  InstrCountFiltered1(aggstate, 1);
1824 
1825  return NULL;
1826 }
1827 
1828 /*
1829  * find_unaggregated_cols
1830  * Construct a bitmapset of the column numbers of un-aggregated Vars
1831  * appearing in our targetlist and qual (HAVING clause)
1832  */
1833 static Bitmapset *
1835 {
1836  Agg *node = (Agg *) aggstate->ss.ps.plan;
1837  Bitmapset *colnos;
1838 
1839  colnos = NULL;
1841  &colnos);
1842  (void) find_unaggregated_cols_walker((Node *) node->plan.qual,
1843  &colnos);
1844  return colnos;
1845 }
1846 
1847 static bool
1849 {
1850  if (node == NULL)
1851  return false;
1852  if (IsA(node, Var))
1853  {
1854  Var *var = (Var *) node;
1855 
1856  /* setrefs.c should have set the varno to OUTER_VAR */
1857  Assert(var->varno == OUTER_VAR);
1858  Assert(var->varlevelsup == 0);
1859  *colnos = bms_add_member(*colnos, var->varattno);
1860  return false;
1861  }
1862  if (IsA(node, Aggref) ||IsA(node, GroupingFunc))
1863  {
1864  /* do not descend into aggregate exprs */
1865  return false;
1866  }
1868  (void *) colnos);
1869 }
1870 
1871 /*
1872  * Initialize the hash table(s) to empty.
1873  *
1874  * To implement hashed aggregation, we need a hashtable that stores a
1875  * representative tuple and an array of AggStatePerGroup structs for each
1876  * distinct set of GROUP BY column values. We compute the hash key from the
1877  * GROUP BY columns. The per-group data is allocated in lookup_hash_entry(),
1878  * for each entry.
1879  *
1880  * We have a separate hashtable and associated perhash data structure for each
1881  * grouping set for which we're doing hashing.
1882  *
1883  * The hash tables always live in the hashcontext's per-tuple memory context
1884  * (there is only one of these for all tables together, since they are all
1885  * reset at the same time).
1886  */
1887 static void
1889 {
1890  MemoryContext tmpmem = aggstate->tmpcontext->ecxt_per_tuple_memory;
1891  Size additionalsize;
1892  int i;
1893 
1894  Assert(aggstate->aggstrategy == AGG_HASHED || aggstate->aggstrategy == AGG_MIXED);
1895 
1896  additionalsize = aggstate->numtrans * sizeof(AggStatePerGroupData);
1897 
1898  for (i = 0; i < aggstate->num_hashes; ++i)
1899  {
1900  AggStatePerHash perhash = &aggstate->perhash[i];
1901 
1902  Assert(perhash->aggnode->numGroups > 0);
1903 
1904  perhash->hashtable = BuildTupleHashTable(perhash->numCols,
1905  perhash->hashGrpColIdxHash,
1906  perhash->eqfunctions,
1907  perhash->hashfunctions,
1908  perhash->aggnode->numGroups,
1909  additionalsize,
1911  tmpmem,
1912  DO_AGGSPLIT_SKIPFINAL(aggstate->aggsplit));
1913  }
1914 }
1915 
1916 /*
1917  * Compute columns that actually need to be stored in hashtable entries. The
1918  * incoming tuples from the child plan node will contain grouping columns,
1919  * other columns referenced in our targetlist and qual, columns used to
1920  * compute the aggregate functions, and perhaps just junk columns we don't use
1921  * at all. Only columns of the first two types need to be stored in the
1922  * hashtable, and getting rid of the others can make the table entries
1923  * significantly smaller. The hashtable only contains the relevant columns,
1924  * and is packed/unpacked in lookup_hash_entry() / agg_retrieve_hash_table()
1925  * into the format of the normal input descriptor.
1926  *
1927  * Additional columns, in addition to the columns grouped by, come from two
1928  * sources: Firstly functionally dependent columns that we don't need to group
1929  * by themselves, and secondly ctids for row-marks.
1930  *
1931  * To eliminate duplicates, we build a bitmapset of the needed columns, and
1932  * then build an array of the columns included in the hashtable. Note that
1933  * the array is preserved over ExecReScanAgg, so we allocate it in the
1934  * per-query context (unlike the hash table itself).
1935  */
1936 static void
1938 {
1939  Bitmapset *base_colnos;
1940  List *outerTlist = outerPlanState(aggstate)->plan->targetlist;
1941  int numHashes = aggstate->num_hashes;
1942  int j;
1943 
1944  /* Find Vars that will be needed in tlist and qual */
1945  base_colnos = find_unaggregated_cols(aggstate);
1946 
1947  for (j = 0; j < numHashes; ++j)
1948  {
1949  AggStatePerHash perhash = &aggstate->perhash[j];
1950  Bitmapset *colnos = bms_copy(base_colnos);
1951  AttrNumber *grpColIdx = perhash->aggnode->grpColIdx;
1952  List *hashTlist = NIL;
1953  TupleDesc hashDesc;
1954  int i;
1955 
1956  perhash->largestGrpColIdx = 0;
1957 
1958  /*
1959  * If we're doing grouping sets, then some Vars might be referenced in
1960  * tlist/qual for the benefit of other grouping sets, but not needed
1961  * when hashing; i.e. prepare_projection_slot will null them out, so
1962  * there'd be no point storing them. Use prepare_projection_slot's
1963  * logic to determine which.
1964  */
1965  if (aggstate->phases[0].grouped_cols)
1966  {
1967  Bitmapset *grouped_cols = aggstate->phases[0].grouped_cols[j];
1968  ListCell *lc;
1969 
1970  foreach(lc, aggstate->all_grouped_cols)
1971  {
1972  int attnum = lfirst_int(lc);
1973 
1974  if (!bms_is_member(attnum, grouped_cols))
1975  colnos = bms_del_member(colnos, attnum);
1976  }
1977  }
1978  /* Add in all the grouping columns */
1979  for (i = 0; i < perhash->numCols; i++)
1980  colnos = bms_add_member(colnos, grpColIdx[i]);
1981 
1982  perhash->hashGrpColIdxInput =
1983  palloc(bms_num_members(colnos) * sizeof(AttrNumber));
1984  perhash->hashGrpColIdxHash =
1985  palloc(perhash->numCols * sizeof(AttrNumber));
1986 
1987  /*
1988  * First build mapping for columns directly hashed. These are the
1989  * first, because they'll be accessed when computing hash values and
1990  * comparing tuples for exact matches. We also build simple mapping
1991  * for execGrouping, so it knows where to find the to-be-hashed /
1992  * compared columns in the input.
1993  */
1994  for (i = 0; i < perhash->numCols; i++)
1995  {
1996  perhash->hashGrpColIdxInput[i] = grpColIdx[i];
1997  perhash->hashGrpColIdxHash[i] = i + 1;
1998  perhash->numhashGrpCols++;
1999  /* delete already mapped columns */
2000  bms_del_member(colnos, grpColIdx[i]);
2001  }
2002 
2003  /* and add the remaining columns */
2004  while ((i = bms_first_member(colnos)) >= 0)
2005  {
2006  perhash->hashGrpColIdxInput[perhash->numhashGrpCols] = i;
2007  perhash->numhashGrpCols++;
2008  }
2009 
2010  /* and build a tuple descriptor for the hashtable */
2011  for (i = 0; i < perhash->numhashGrpCols; i++)
2012  {
2013  int varNumber = perhash->hashGrpColIdxInput[i] - 1;
2014 
2015  hashTlist = lappend(hashTlist, list_nth(outerTlist, varNumber));
2016  perhash->largestGrpColIdx =
2017  Max(varNumber + 1, perhash->largestGrpColIdx);
2018  }
2019 
2020  hashDesc = ExecTypeFromTL(hashTlist, false);
2021  ExecSetSlotDescriptor(perhash->hashslot, hashDesc);
2022 
2023  list_free(hashTlist);
2024  bms_free(colnos);
2025  }
2026 
2027  bms_free(base_colnos);
2028 }
2029 
2030 /*
2031  * Estimate per-hash-table-entry overhead for the planner.
2032  *
2033  * Note that the estimate does not include space for pass-by-reference
2034  * transition data values, nor for the representative tuple of each group.
2035  * Nor does this account of the target fill-factor and growth policy of the
2036  * hash table.
2037  */
2038 Size
2040 {
2041  Size entrysize;
2042 
2043  /* This must match build_hash_table */
2044  entrysize = sizeof(TupleHashEntryData) +
2045  numAggs * sizeof(AggStatePerGroupData);
2046  entrysize = MAXALIGN(entrysize);
2047 
2048  return entrysize;
2049 }
2050 
2051 /*
2052  * Find or create a hashtable entry for the tuple group containing the current
2053  * tuple (already set in tmpcontext's outertuple slot), in the current grouping
2054  * set (which the caller must have selected - note that initialize_aggregate
2055  * depends on this).
2056  *
2057  * When called, CurrentMemoryContext should be the per-query context.
2058  */
2059 static TupleHashEntryData *
2061 {
2062  TupleTableSlot *inputslot = aggstate->tmpcontext->ecxt_outertuple;
2063  AggStatePerHash perhash = &aggstate->perhash[aggstate->current_set];
2064  TupleTableSlot *hashslot = perhash->hashslot;
2065  TupleHashEntryData *entry;
2066  bool isnew;
2067  int i;
2068 
2069  /* transfer just the needed columns into hashslot */
2070  slot_getsomeattrs(inputslot, perhash->largestGrpColIdx);
2071  ExecClearTuple(hashslot);
2072 
2073  for (i = 0; i < perhash->numhashGrpCols; i++)
2074  {
2075  int varNumber = perhash->hashGrpColIdxInput[i] - 1;
2076 
2077  hashslot->tts_values[i] = inputslot->tts_values[varNumber];
2078  hashslot->tts_isnull[i] = inputslot->tts_isnull[varNumber];
2079  }
2080  ExecStoreVirtualTuple(hashslot);
2081 
2082  /* find or create the hashtable entry using the filtered tuple */
2083  entry = LookupTupleHashEntry(perhash->hashtable, hashslot, &isnew);
2084 
2085  if (isnew)
2086  {
2087  entry->additional = (AggStatePerGroup)
2089  sizeof(AggStatePerGroupData) * aggstate->numtrans);
2090  /* initialize aggregates for new tuple group */
2092  -1);
2093  }
2094 
2095  return entry;
2096 }
2097 
2098 /*
2099  * Look up hash entries for the current tuple in all hashed grouping sets,
2100  * returning an array of pergroup pointers suitable for advance_aggregates.
2101  *
2102  * Be aware that lookup_hash_entry can reset the tmpcontext.
2103  */
2104 static AggStatePerGroup *
2106 {
2107  int numHashes = aggstate->num_hashes;
2108  AggStatePerGroup *pergroup = aggstate->hash_pergroup;
2109  int setno;
2110 
2111  for (setno = 0; setno < numHashes; setno++)
2112  {
2113  select_current_set(aggstate, setno, true);
2114  pergroup[setno] = lookup_hash_entry(aggstate)->additional;
2115  }
2116 
2117  return pergroup;
2118 }
2119 
2120 /*
2121  * ExecAgg -
2122  *
2123  * ExecAgg receives tuples from its outer subplan and aggregates over
2124  * the appropriate attribute for each aggregate function use (Aggref
2125  * node) appearing in the targetlist or qual of the node. The number
2126  * of tuples to aggregate over depends on whether grouped or plain
2127  * aggregation is selected. In grouped aggregation, we produce a result
2128  * row for each group; in plain aggregation there's a single result row
2129  * for the whole query. In either case, the value of each aggregate is
2130  * stored in the expression context to be used when ExecProject evaluates
2131  * the result tuple.
2132  */
2133 static TupleTableSlot *
2135 {
2136  AggState *node = castNode(AggState, pstate);
2137  TupleTableSlot *result = NULL;
2138 
2140 
2141  if (!node->agg_done)
2142  {
2143  /* Dispatch based on strategy */
2144  switch (node->phase->aggstrategy)
2145  {
2146  case AGG_HASHED:
2147  if (!node->table_filled)
2148  agg_fill_hash_table(node);
2149  /* FALLTHROUGH */
2150  case AGG_MIXED:
2151  result = agg_retrieve_hash_table(node);
2152  break;
2153  case AGG_PLAIN:
2154  case AGG_SORTED:
2155  result = agg_retrieve_direct(node);
2156  break;
2157  }
2158 
2159  if (!TupIsNull(result))
2160  return result;
2161  }
2162 
2163  return NULL;
2164 }
2165 
2166 /*
2167  * ExecAgg for non-hashed case
2168  */
2169 static TupleTableSlot *
2171 {
2172  Agg *node = aggstate->phase->aggnode;
2173  ExprContext *econtext;
2174  ExprContext *tmpcontext;
2175  AggStatePerAgg peragg;
2176  AggStatePerGroup pergroup;
2177  AggStatePerGroup *hash_pergroups = NULL;
2178  TupleTableSlot *outerslot;
2179  TupleTableSlot *firstSlot;
2180  TupleTableSlot *result;
2181  bool hasGroupingSets = aggstate->phase->numsets > 0;
2182  int numGroupingSets = Max(aggstate->phase->numsets, 1);
2183  int currentSet;
2184  int nextSetSize;
2185  int numReset;
2186  int i;
2187 
2188  /*
2189  * get state info from node
2190  *
2191  * econtext is the per-output-tuple expression context
2192  *
2193  * tmpcontext is the per-input-tuple expression context
2194  */
2195  econtext = aggstate->ss.ps.ps_ExprContext;
2196  tmpcontext = aggstate->tmpcontext;
2197 
2198  peragg = aggstate->peragg;
2199  pergroup = aggstate->pergroup;
2200  firstSlot = aggstate->ss.ss_ScanTupleSlot;
2201 
2202  /*
2203  * We loop retrieving groups until we find one matching
2204  * aggstate->ss.ps.qual
2205  *
2206  * For grouping sets, we have the invariant that aggstate->projected_set
2207  * is either -1 (initial call) or the index (starting from 0) in
2208  * gset_lengths for the group we just completed (either by projecting a
2209  * row or by discarding it in the qual).
2210  */
2211  while (!aggstate->agg_done)
2212  {
2213  /*
2214  * Clear the per-output-tuple context for each group, as well as
2215  * aggcontext (which contains any pass-by-ref transvalues of the old
2216  * group). Some aggregate functions store working state in child
2217  * contexts; those now get reset automatically without us needing to
2218  * do anything special.
2219  *
2220  * We use ReScanExprContext not just ResetExprContext because we want
2221  * any registered shutdown callbacks to be called. That allows
2222  * aggregate functions to ensure they've cleaned up any non-memory
2223  * resources.
2224  */
2225  ReScanExprContext(econtext);
2226 
2227  /*
2228  * Determine how many grouping sets need to be reset at this boundary.
2229  */
2230  if (aggstate->projected_set >= 0 &&
2231  aggstate->projected_set < numGroupingSets)
2232  numReset = aggstate->projected_set + 1;
2233  else
2234  numReset = numGroupingSets;
2235 
2236  /*
2237  * numReset can change on a phase boundary, but that's OK; we want to
2238  * reset the contexts used in _this_ phase, and later, after possibly
2239  * changing phase, initialize the right number of aggregates for the
2240  * _new_ phase.
2241  */
2242 
2243  for (i = 0; i < numReset; i++)
2244  {
2245  ReScanExprContext(aggstate->aggcontexts[i]);
2246  }
2247 
2248  /*
2249  * Check if input is complete and there are no more groups to project
2250  * in this phase; move to next phase or mark as done.
2251  */
2252  if (aggstate->input_done == true &&
2253  aggstate->projected_set >= (numGroupingSets - 1))
2254  {
2255  if (aggstate->current_phase < aggstate->numphases - 1)
2256  {
2257  initialize_phase(aggstate, aggstate->current_phase + 1);
2258  aggstate->input_done = false;
2259  aggstate->projected_set = -1;
2260  numGroupingSets = Max(aggstate->phase->numsets, 1);
2261  node = aggstate->phase->aggnode;
2262  numReset = numGroupingSets;
2263  }
2264  else if (aggstate->aggstrategy == AGG_MIXED)
2265  {
2266  /*
2267  * Mixed mode; we've output all the grouped stuff and have
2268  * full hashtables, so switch to outputting those.
2269  */
2270  initialize_phase(aggstate, 0);
2271  aggstate->table_filled = true;
2273  &aggstate->perhash[0].hashiter);
2274  select_current_set(aggstate, 0, true);
2275  return agg_retrieve_hash_table(aggstate);
2276  }
2277  else
2278  {
2279  aggstate->agg_done = true;
2280  break;
2281  }
2282  }
2283 
2284  /*
2285  * Get the number of columns in the next grouping set after the last
2286  * projected one (if any). This is the number of columns to compare to
2287  * see if we reached the boundary of that set too.
2288  */
2289  if (aggstate->projected_set >= 0 &&
2290  aggstate->projected_set < (numGroupingSets - 1))
2291  nextSetSize = aggstate->phase->gset_lengths[aggstate->projected_set + 1];
2292  else
2293  nextSetSize = 0;
2294 
2295  /*----------
2296  * If a subgroup for the current grouping set is present, project it.
2297  *
2298  * We have a new group if:
2299  * - we're out of input but haven't projected all grouping sets
2300  * (checked above)
2301  * OR
2302  * - we already projected a row that wasn't from the last grouping
2303  * set
2304  * AND
2305  * - the next grouping set has at least one grouping column (since
2306  * empty grouping sets project only once input is exhausted)
2307  * AND
2308  * - the previous and pending rows differ on the grouping columns
2309  * of the next grouping set
2310  *----------
2311  */
2312  if (aggstate->input_done ||
2313  (node->aggstrategy != AGG_PLAIN &&
2314  aggstate->projected_set != -1 &&
2315  aggstate->projected_set < (numGroupingSets - 1) &&
2316  nextSetSize > 0 &&
2317  !execTuplesMatch(econtext->ecxt_outertuple,
2318  tmpcontext->ecxt_outertuple,
2319  nextSetSize,
2320  node->grpColIdx,
2321  aggstate->phase->eqfunctions,
2322  tmpcontext->ecxt_per_tuple_memory)))
2323  {
2324  aggstate->projected_set += 1;
2325 
2326  Assert(aggstate->projected_set < numGroupingSets);
2327  Assert(nextSetSize > 0 || aggstate->input_done);
2328  }
2329  else
2330  {
2331  /*
2332  * We no longer care what group we just projected, the next
2333  * projection will always be the first (or only) grouping set
2334  * (unless the input proves to be empty).
2335  */
2336  aggstate->projected_set = 0;
2337 
2338  /*
2339  * If we don't already have the first tuple of the new group,
2340  * fetch it from the outer plan.
2341  */
2342  if (aggstate->grp_firstTuple == NULL)
2343  {
2344  outerslot = fetch_input_tuple(aggstate);
2345  if (!TupIsNull(outerslot))
2346  {
2347  /*
2348  * Make a copy of the first input tuple; we will use this
2349  * for comparisons (in group mode) and for projection.
2350  */
2351  aggstate->grp_firstTuple = ExecCopySlotTuple(outerslot);
2352  }
2353  else
2354  {
2355  /* outer plan produced no tuples at all */
2356  if (hasGroupingSets)
2357  {
2358  /*
2359  * If there was no input at all, we need to project
2360  * rows only if there are grouping sets of size 0.
2361  * Note that this implies that there can't be any
2362  * references to ungrouped Vars, which would otherwise
2363  * cause issues with the empty output slot.
2364  *
2365  * XXX: This is no longer true, we currently deal with
2366  * this in finalize_aggregates().
2367  */
2368  aggstate->input_done = true;
2369 
2370  while (aggstate->phase->gset_lengths[aggstate->projected_set] > 0)
2371  {
2372  aggstate->projected_set += 1;
2373  if (aggstate->projected_set >= numGroupingSets)
2374  {
2375  /*
2376  * We can't set agg_done here because we might
2377  * have more phases to do, even though the
2378  * input is empty. So we need to restart the
2379  * whole outer loop.
2380  */
2381  break;
2382  }
2383  }
2384 
2385  if (aggstate->projected_set >= numGroupingSets)
2386  continue;
2387  }
2388  else
2389  {
2390  aggstate->agg_done = true;
2391  /* If we are grouping, we should produce no tuples too */
2392  if (node->aggstrategy != AGG_PLAIN)
2393  return NULL;
2394  }
2395  }
2396  }
2397 
2398  /*
2399  * Initialize working state for a new input tuple group.
2400  */
2401  initialize_aggregates(aggstate, pergroup, numReset);
2402 
2403  if (aggstate->grp_firstTuple != NULL)
2404  {
2405  /*
2406  * Store the copied first input tuple in the tuple table slot
2407  * reserved for it. The tuple will be deleted when it is
2408  * cleared from the slot.
2409  */
2410  ExecStoreTuple(aggstate->grp_firstTuple,
2411  firstSlot,
2412  InvalidBuffer,
2413  true);
2414  aggstate->grp_firstTuple = NULL; /* don't keep two pointers */
2415 
2416  /* set up for first advance_aggregates call */
2417  tmpcontext->ecxt_outertuple = firstSlot;
2418 
2419  /*
2420  * Process each outer-plan tuple, and then fetch the next one,
2421  * until we exhaust the outer plan or cross a group boundary.
2422  */
2423  for (;;)
2424  {
2425  /*
2426  * During phase 1 only of a mixed agg, we need to update
2427  * hashtables as well in advance_aggregates.
2428  */
2429  if (aggstate->aggstrategy == AGG_MIXED &&
2430  aggstate->current_phase == 1)
2431  {
2432  hash_pergroups = lookup_hash_entries(aggstate);
2433  }
2434  else
2435  hash_pergroups = NULL;
2436 
2437  if (DO_AGGSPLIT_COMBINE(aggstate->aggsplit))
2438  combine_aggregates(aggstate, pergroup);
2439  else
2440  advance_aggregates(aggstate, pergroup, hash_pergroups);
2441 
2442  /* Reset per-input-tuple context after each tuple */
2443  ResetExprContext(tmpcontext);
2444 
2445  outerslot = fetch_input_tuple(aggstate);
2446  if (TupIsNull(outerslot))
2447  {
2448  /* no more outer-plan tuples available */
2449  if (hasGroupingSets)
2450  {
2451  aggstate->input_done = true;
2452  break;
2453  }
2454  else
2455  {
2456  aggstate->agg_done = true;
2457  break;
2458  }
2459  }
2460  /* set up for next advance_aggregates call */
2461  tmpcontext->ecxt_outertuple = outerslot;
2462 
2463  /*
2464  * If we are grouping, check whether we've crossed a group
2465  * boundary.
2466  */
2467  if (node->aggstrategy != AGG_PLAIN)
2468  {
2469  if (!execTuplesMatch(firstSlot,
2470  outerslot,
2471  node->numCols,
2472  node->grpColIdx,
2473  aggstate->phase->eqfunctions,
2474  tmpcontext->ecxt_per_tuple_memory))
2475  {
2476  aggstate->grp_firstTuple = ExecCopySlotTuple(outerslot);
2477  break;
2478  }
2479  }
2480  }
2481  }
2482 
2483  /*
2484  * Use the representative input tuple for any references to
2485  * non-aggregated input columns in aggregate direct args, the node
2486  * qual, and the tlist. (If we are not grouping, and there are no
2487  * input rows at all, we will come here with an empty firstSlot
2488  * ... but if not grouping, there can't be any references to
2489  * non-aggregated input columns, so no problem.)
2490  */
2491  econtext->ecxt_outertuple = firstSlot;
2492  }
2493 
2494  Assert(aggstate->projected_set >= 0);
2495 
2496  currentSet = aggstate->projected_set;
2497 
2498  prepare_projection_slot(aggstate, econtext->ecxt_outertuple, currentSet);
2499 
2500  select_current_set(aggstate, currentSet, false);
2501 
2502  finalize_aggregates(aggstate,
2503  peragg,
2504  pergroup + (currentSet * aggstate->numtrans));
2505 
2506  /*
2507  * If there's no row to project right now, we must continue rather
2508  * than returning a null since there might be more groups.
2509  */
2510  result = project_aggregates(aggstate);
2511  if (result)
2512  return result;
2513  }
2514 
2515  /* No more groups */
2516  return NULL;
2517 }
2518 
2519 /*
2520  * ExecAgg for hashed case: read input and build hash table
2521  */
2522 static void
2524 {
2525  TupleTableSlot *outerslot;
2526  ExprContext *tmpcontext = aggstate->tmpcontext;
2527 
2528  /*
2529  * Process each outer-plan tuple, and then fetch the next one, until we
2530  * exhaust the outer plan.
2531  */
2532  for (;;)
2533  {
2534  AggStatePerGroup *pergroups;
2535 
2536  outerslot = fetch_input_tuple(aggstate);
2537  if (TupIsNull(outerslot))
2538  break;
2539 
2540  /* set up for lookup_hash_entries and advance_aggregates */
2541  tmpcontext->ecxt_outertuple = outerslot;
2542 
2543  /* Find or build hashtable entries */
2544  pergroups = lookup_hash_entries(aggstate);
2545 
2546  /* Advance the aggregates */
2547  if (DO_AGGSPLIT_COMBINE(aggstate->aggsplit))
2548  combine_aggregates(aggstate, pergroups[0]);
2549  else
2550  advance_aggregates(aggstate, NULL, pergroups);
2551 
2552  /*
2553  * Reset per-input-tuple context after each tuple, but note that the
2554  * hash lookups do this too
2555  */
2556  ResetExprContext(aggstate->tmpcontext);
2557  }
2558 
2559  aggstate->table_filled = true;
2560  /* Initialize to walk the first hash table */
2561  select_current_set(aggstate, 0, true);
2563  &aggstate->perhash[0].hashiter);
2564 }
2565 
2566 /*
2567  * ExecAgg for hashed case: retrieving groups from hash table
2568  */
2569 static TupleTableSlot *
2571 {
2572  ExprContext *econtext;
2573  AggStatePerAgg peragg;
2574  AggStatePerGroup pergroup;
2575  TupleHashEntryData *entry;
2576  TupleTableSlot *firstSlot;
2577  TupleTableSlot *result;
2578  AggStatePerHash perhash;
2579 
2580  /*
2581  * get state info from node.
2582  *
2583  * econtext is the per-output-tuple expression context.
2584  */
2585  econtext = aggstate->ss.ps.ps_ExprContext;
2586  peragg = aggstate->peragg;
2587  firstSlot = aggstate->ss.ss_ScanTupleSlot;
2588 
2589  /*
2590  * Note that perhash (and therefore anything accessed through it) can
2591  * change inside the loop, as we change between grouping sets.
2592  */
2593  perhash = &aggstate->perhash[aggstate->current_set];
2594 
2595  /*
2596  * We loop retrieving groups until we find one satisfying
2597  * aggstate->ss.ps.qual
2598  */
2599  while (!aggstate->agg_done)
2600  {
2601  TupleTableSlot *hashslot = perhash->hashslot;
2602  int i;
2603 
2605 
2606  /*
2607  * Find the next entry in the hash table
2608  */
2609  entry = ScanTupleHashTable(perhash->hashtable, &perhash->hashiter);
2610  if (entry == NULL)
2611  {
2612  int nextset = aggstate->current_set + 1;
2613 
2614  if (nextset < aggstate->num_hashes)
2615  {
2616  /*
2617  * Switch to next grouping set, reinitialize, and restart the
2618  * loop.
2619  */
2620  select_current_set(aggstate, nextset, true);
2621 
2622  perhash = &aggstate->perhash[aggstate->current_set];
2623 
2624  ResetTupleHashIterator(perhash->hashtable, &perhash->hashiter);
2625 
2626  continue;
2627  }
2628  else
2629  {
2630  /* No more hashtables, so done */
2631  aggstate->agg_done = TRUE;
2632  return NULL;
2633  }
2634  }
2635 
2636  /*
2637  * Clear the per-output-tuple context for each group
2638  *
2639  * We intentionally don't use ReScanExprContext here; if any aggs have
2640  * registered shutdown callbacks, they mustn't be called yet, since we
2641  * might not be done with that agg.
2642  */
2643  ResetExprContext(econtext);
2644 
2645  /*
2646  * Transform representative tuple back into one with the right
2647  * columns.
2648  */
2649  ExecStoreMinimalTuple(entry->firstTuple, hashslot, false);
2650  slot_getallattrs(hashslot);
2651 
2652  ExecClearTuple(firstSlot);
2653  memset(firstSlot->tts_isnull, true,
2654  firstSlot->tts_tupleDescriptor->natts * sizeof(bool));
2655 
2656  for (i = 0; i < perhash->numhashGrpCols; i++)
2657  {
2658  int varNumber = perhash->hashGrpColIdxInput[i] - 1;
2659 
2660  firstSlot->tts_values[varNumber] = hashslot->tts_values[i];
2661  firstSlot->tts_isnull[varNumber] = hashslot->tts_isnull[i];
2662  }
2663  ExecStoreVirtualTuple(firstSlot);
2664 
2665  pergroup = (AggStatePerGroup) entry->additional;
2666 
2667  /*
2668  * Use the representative input tuple for any references to
2669  * non-aggregated input columns in the qual and tlist.
2670  */
2671  econtext->ecxt_outertuple = firstSlot;
2672 
2673  prepare_projection_slot(aggstate,
2674  econtext->ecxt_outertuple,
2675  aggstate->current_set);
2676 
2677  finalize_aggregates(aggstate, peragg, pergroup);
2678 
2679  result = project_aggregates(aggstate);
2680  if (result)
2681  return result;
2682  }
2683 
2684  /* No more groups */
2685  return NULL;
2686 }
2687 
2688 /* -----------------
2689  * ExecInitAgg
2690  *
2691  * Creates the run-time information for the agg node produced by the
2692  * planner and initializes its outer subtree.
2693  *
2694  * -----------------
2695  */
2696 AggState *
2697 ExecInitAgg(Agg *node, EState *estate, int eflags)
2698 {
2699  AggState *aggstate;
2700  AggStatePerAgg peraggs;
2701  AggStatePerTrans pertransstates;
2702  Plan *outerPlan;
2703  ExprContext *econtext;
2704  int numaggs,
2705  transno,
2706  aggno;
2707  int phase;
2708  int phaseidx;
2709  List *combined_inputeval;
2710  TupleDesc combineddesc;
2711  TupleTableSlot *combinedslot;
2712  ListCell *l;
2713  Bitmapset *all_grouped_cols = NULL;
2714  int numGroupingSets = 1;
2715  int numPhases;
2716  int numHashes;
2717  int column_offset;
2718  int i = 0;
2719  int j = 0;
2720  bool use_hashing = (node->aggstrategy == AGG_HASHED ||
2721  node->aggstrategy == AGG_MIXED);
2722 
2723  /* check for unsupported flags */
2724  Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
2725 
2726  /*
2727  * create state structure
2728  */
2729  aggstate = makeNode(AggState);
2730  aggstate->ss.ps.plan = (Plan *) node;
2731  aggstate->ss.ps.state = estate;
2732  aggstate->ss.ps.ExecProcNode = ExecAgg;
2733 
2734  aggstate->aggs = NIL;
2735  aggstate->numaggs = 0;
2736  aggstate->numtrans = 0;
2737  aggstate->aggstrategy = node->aggstrategy;
2738  aggstate->aggsplit = node->aggsplit;
2739  aggstate->maxsets = 0;
2740  aggstate->projected_set = -1;
2741  aggstate->current_set = 0;
2742  aggstate->peragg = NULL;
2743  aggstate->pertrans = NULL;
2744  aggstate->curperagg = NULL;
2745  aggstate->curpertrans = NULL;
2746  aggstate->input_done = false;
2747  aggstate->agg_done = false;
2748  aggstate->pergroup = NULL;
2749  aggstate->grp_firstTuple = NULL;
2750  aggstate->sort_in = NULL;
2751  aggstate->sort_out = NULL;
2752 
2753  /*
2754  * phases[0] always exists, but is dummy in sorted/plain mode
2755  */
2756  numPhases = (use_hashing ? 1 : 2);
2757  numHashes = (use_hashing ? 1 : 0);
2758 
2759  /*
2760  * Calculate the maximum number of grouping sets in any phase; this
2761  * determines the size of some allocations. Also calculate the number of
2762  * phases, since all hashed/mixed nodes contribute to only a single phase.
2763  */
2764  if (node->groupingSets)
2765  {
2766  numGroupingSets = list_length(node->groupingSets);
2767 
2768  foreach(l, node->chain)
2769  {
2770  Agg *agg = lfirst(l);
2771 
2772  numGroupingSets = Max(numGroupingSets,
2773  list_length(agg->groupingSets));
2774 
2775  /*
2776  * additional AGG_HASHED aggs become part of phase 0, but all
2777  * others add an extra phase.
2778  */
2779  if (agg->aggstrategy != AGG_HASHED)
2780  ++numPhases;
2781  else
2782  ++numHashes;
2783  }
2784  }
2785 
2786  aggstate->maxsets = numGroupingSets;
2787  aggstate->numphases = numPhases;
2788 
2789  aggstate->aggcontexts = (ExprContext **)
2790  palloc0(sizeof(ExprContext *) * numGroupingSets);
2791 
2792  /*
2793  * Create expression contexts. We need three or more, one for
2794  * per-input-tuple processing, one for per-output-tuple processing, one
2795  * for all the hashtables, and one for each grouping set. The per-tuple
2796  * memory context of the per-grouping-set ExprContexts (aggcontexts)
2797  * replaces the standalone memory context formerly used to hold transition
2798  * values. We cheat a little by using ExecAssignExprContext() to build
2799  * all of them.
2800  *
2801  * NOTE: the details of what is stored in aggcontexts and what is stored
2802  * in the regular per-query memory context are driven by a simple
2803  * decision: we want to reset the aggcontext at group boundaries (if not
2804  * hashing) and in ExecReScanAgg to recover no-longer-wanted space.
2805  */
2806  ExecAssignExprContext(estate, &aggstate->ss.ps);
2807  aggstate->tmpcontext = aggstate->ss.ps.ps_ExprContext;
2808 
2809  for (i = 0; i < numGroupingSets; ++i)
2810  {
2811  ExecAssignExprContext(estate, &aggstate->ss.ps);
2812  aggstate->aggcontexts[i] = aggstate->ss.ps.ps_ExprContext;
2813  }
2814 
2815  if (use_hashing)
2816  {
2817  ExecAssignExprContext(estate, &aggstate->ss.ps);
2818  aggstate->hashcontext = aggstate->ss.ps.ps_ExprContext;
2819  }
2820 
2821  ExecAssignExprContext(estate, &aggstate->ss.ps);
2822 
2823  /*
2824  * tuple table initialization.
2825  *
2826  * For hashtables, we create some additional slots below.
2827  */
2828  ExecInitScanTupleSlot(estate, &aggstate->ss);
2829  ExecInitResultTupleSlot(estate, &aggstate->ss.ps);
2830  aggstate->sort_slot = ExecInitExtraTupleSlot(estate);
2831 
2832  /*
2833  * initialize child expressions
2834  *
2835  * We expect the parser to have checked that no aggs contain other agg
2836  * calls in their arguments (and just to be sure, we verify it again while
2837  * initializing the plan node). This would make no sense under SQL
2838  * semantics, and it's forbidden by the spec. Because it is true, we
2839  * don't need to worry about evaluating the aggs in any particular order.
2840  *
2841  * Note: execExpr.c finds Aggrefs for us, and adds their AggrefExprState
2842  * nodes to aggstate->aggs. Aggrefs in the qual are found here; Aggrefs
2843  * in the targetlist are found during ExecAssignProjectionInfo, below.
2844  */
2845  aggstate->ss.ps.qual =
2846  ExecInitQual(node->plan.qual, (PlanState *) aggstate);
2847 
2848  /*
2849  * Initialize child nodes.
2850  *
2851  * If we are doing a hashed aggregation then the child plan does not need
2852  * to handle REWIND efficiently; see ExecReScanAgg.
2853  */
2854  if (node->aggstrategy == AGG_HASHED)
2855  eflags &= ~EXEC_FLAG_REWIND;
2856  outerPlan = outerPlan(node);
2857  outerPlanState(aggstate) = ExecInitNode(outerPlan, estate, eflags);
2858 
2859  /*
2860  * initialize source tuple type.
2861  */
2862  ExecAssignScanTypeFromOuterPlan(&aggstate->ss);
2863  if (node->chain)
2864  ExecSetSlotDescriptor(aggstate->sort_slot,
2866 
2867  /*
2868  * Initialize result tuple type and projection info.
2869  */
2870  ExecAssignResultTypeFromTL(&aggstate->ss.ps);
2871  ExecAssignProjectionInfo(&aggstate->ss.ps, NULL);
2872 
2873  /*
2874  * We should now have found all Aggrefs in the targetlist and quals.
2875  */
2876  numaggs = aggstate->numaggs;
2877  Assert(numaggs == list_length(aggstate->aggs));
2878 
2879  /*
2880  * For each phase, prepare grouping set data and fmgr lookup data for
2881  * compare functions. Accumulate all_grouped_cols in passing.
2882  */
2883  aggstate->phases = palloc0(numPhases * sizeof(AggStatePerPhaseData));
2884 
2885  aggstate->num_hashes = numHashes;
2886  if (numHashes)
2887  {
2888  aggstate->perhash = palloc0(sizeof(AggStatePerHashData) * numHashes);
2889  aggstate->phases[0].numsets = 0;
2890  aggstate->phases[0].gset_lengths = palloc(numHashes * sizeof(int));
2891  aggstate->phases[0].grouped_cols = palloc(numHashes * sizeof(Bitmapset *));
2892  }
2893 
2894  phase = 0;
2895  for (phaseidx = 0; phaseidx <= list_length(node->chain); ++phaseidx)
2896  {
2897  Agg *aggnode;
2898  Sort *sortnode;
2899 
2900  if (phaseidx > 0)
2901  {
2902  aggnode = list_nth_node(Agg, node->chain, phaseidx - 1);
2903  sortnode = castNode(Sort, aggnode->plan.lefttree);
2904  }
2905  else
2906  {
2907  aggnode = node;
2908  sortnode = NULL;
2909  }
2910 
2911  Assert(phase <= 1 || sortnode);
2912 
2913  if (aggnode->aggstrategy == AGG_HASHED
2914  || aggnode->aggstrategy == AGG_MIXED)
2915  {
2916  AggStatePerPhase phasedata = &aggstate->phases[0];
2917  AggStatePerHash perhash;
2918  Bitmapset *cols = NULL;
2919 
2920  Assert(phase == 0);
2921  i = phasedata->numsets++;
2922  perhash = &aggstate->perhash[i];
2923 
2924  /* phase 0 always points to the "real" Agg in the hash case */
2925  phasedata->aggnode = node;
2926  phasedata->aggstrategy = node->aggstrategy;
2927 
2928  /* but the actual Agg node representing this hash is saved here */
2929  perhash->aggnode = aggnode;
2930 
2931  phasedata->gset_lengths[i] = perhash->numCols = aggnode->numCols;
2932 
2933  for (j = 0; j < aggnode->numCols; ++j)
2934  cols = bms_add_member(cols, aggnode->grpColIdx[j]);
2935 
2936  phasedata->grouped_cols[i] = cols;
2937 
2938  all_grouped_cols = bms_add_members(all_grouped_cols, cols);
2939  continue;
2940  }
2941  else
2942  {
2943  AggStatePerPhase phasedata = &aggstate->phases[++phase];
2944  int num_sets;
2945 
2946  phasedata->numsets = num_sets = list_length(aggnode->groupingSets);
2947 
2948  if (num_sets)
2949  {
2950  phasedata->gset_lengths = palloc(num_sets * sizeof(int));
2951  phasedata->grouped_cols = palloc(num_sets * sizeof(Bitmapset *));
2952 
2953  i = 0;
2954  foreach(l, aggnode->groupingSets)
2955  {
2956  int current_length = list_length(lfirst(l));
2957  Bitmapset *cols = NULL;
2958 
2959  /* planner forces this to be correct */
2960  for (j = 0; j < current_length; ++j)
2961  cols = bms_add_member(cols, aggnode->grpColIdx[j]);
2962 
2963  phasedata->grouped_cols[i] = cols;
2964  phasedata->gset_lengths[i] = current_length;
2965 
2966  ++i;
2967  }
2968 
2969  all_grouped_cols = bms_add_members(all_grouped_cols,
2970  phasedata->grouped_cols[0]);
2971  }
2972  else
2973  {
2974  Assert(phaseidx == 0);
2975 
2976  phasedata->gset_lengths = NULL;
2977  phasedata->grouped_cols = NULL;
2978  }
2979 
2980  /*
2981  * If we are grouping, precompute fmgr lookup data for inner loop.
2982  */
2983  if (aggnode->aggstrategy == AGG_SORTED)
2984  {
2985  Assert(aggnode->numCols > 0);
2986 
2987  phasedata->eqfunctions =
2989  aggnode->grpOperators);
2990  }
2991 
2992  phasedata->aggnode = aggnode;
2993  phasedata->aggstrategy = aggnode->aggstrategy;
2994  phasedata->sortnode = sortnode;
2995  }
2996  }
2997 
2998  /*
2999  * Convert all_grouped_cols to a descending-order list.
3000  */
3001  i = -1;
3002  while ((i = bms_next_member(all_grouped_cols, i)) >= 0)
3003  aggstate->all_grouped_cols = lcons_int(i, aggstate->all_grouped_cols);
3004 
3005  /*
3006  * Set up aggregate-result storage in the output expr context, and also
3007  * allocate my private per-agg working storage
3008  */
3009  econtext = aggstate->ss.ps.ps_ExprContext;
3010  econtext->ecxt_aggvalues = (Datum *) palloc0(sizeof(Datum) * numaggs);
3011  econtext->ecxt_aggnulls = (bool *) palloc0(sizeof(bool) * numaggs);
3012 
3013  peraggs = (AggStatePerAgg) palloc0(sizeof(AggStatePerAggData) * numaggs);
3014  pertransstates = (AggStatePerTrans) palloc0(sizeof(AggStatePerTransData) * numaggs);
3015 
3016  aggstate->peragg = peraggs;
3017  aggstate->pertrans = pertransstates;
3018 
3019  /*
3020  * Hashing can only appear in the initial phase.
3021  */
3022  if (use_hashing)
3023  {
3024  for (i = 0; i < numHashes; ++i)
3025  {
3026  aggstate->perhash[i].hashslot = ExecInitExtraTupleSlot(estate);
3027 
3028  execTuplesHashPrepare(aggstate->perhash[i].numCols,
3029  aggstate->perhash[i].aggnode->grpOperators,
3030  &aggstate->perhash[i].eqfunctions,
3031  &aggstate->perhash[i].hashfunctions);
3032  }
3033 
3034  /* this is an array of pointers, not structures */
3035  aggstate->hash_pergroup = palloc0(sizeof(AggStatePerGroup) * numHashes);
3036 
3037  find_hash_columns(aggstate);
3038  build_hash_table(aggstate);
3039  aggstate->table_filled = false;
3040  }
3041 
3042  if (node->aggstrategy != AGG_HASHED)
3043  {
3044  AggStatePerGroup pergroup;
3045 
3046  pergroup = (AggStatePerGroup) palloc0(sizeof(AggStatePerGroupData)
3047  * numaggs
3048  * numGroupingSets);
3049 
3050  aggstate->pergroup = pergroup;
3051  }
3052 
3053  /*
3054  * Initialize current phase-dependent values to initial phase. The initial
3055  * phase is 1 (first sort pass) for all strategies that use sorting (if
3056  * hashing is being done too, then phase 0 is processed last); but if only
3057  * hashing is being done, then phase 0 is all there is.
3058  */
3059  if (node->aggstrategy == AGG_HASHED)
3060  {
3061  aggstate->current_phase = 0;
3062  initialize_phase(aggstate, 0);
3063  select_current_set(aggstate, 0, true);
3064  }
3065  else
3066  {
3067  aggstate->current_phase = 1;
3068  initialize_phase(aggstate, 1);
3069  select_current_set(aggstate, 0, false);
3070  }
3071 
3072  /* -----------------
3073  * Perform lookups of aggregate function info, and initialize the
3074  * unchanging fields of the per-agg and per-trans data.
3075  *
3076  * We try to optimize by detecting duplicate aggregate functions so that
3077  * their state and final values are re-used, rather than needlessly being
3078  * re-calculated independently. We also detect aggregates that are not
3079  * the same, but which can share the same transition state.
3080  *
3081  * Scenarios:
3082  *
3083  * 1. Identical aggregate function calls appear in the query:
3084  *
3085  * SELECT SUM(x) FROM ... HAVING SUM(x) > 0
3086  *
3087  * Since these aggregates are identical, we only need to calculate
3088  * the value once. Both aggregates will share the same 'aggno' value.
3089  *
3090  * 2. Two different aggregate functions appear in the query, but the
3091  * aggregates have the same arguments, transition functions and
3092  * initial values (and, presumably, different final functions):
3093  *
3094  * SELECT AVG(x), STDDEV(x) FROM ...
3095  *
3096  * In this case we must create a new peragg for the varying aggregate,
3097  * and we need to call the final functions separately, but we need
3098  * only run the transition function once. (This requires that the
3099  * final functions be nondestructive of the transition state, but
3100  * that's required anyway for other reasons.)
3101  *
3102  * For either of these optimizations to be valid, all aggregate properties
3103  * used in the transition phase must be the same, including any modifiers
3104  * such as ORDER BY, DISTINCT and FILTER, and the arguments mustn't
3105  * contain any volatile functions.
3106  * -----------------
3107  */
3108  aggno = -1;
3109  transno = -1;
3110  foreach(l, aggstate->aggs)
3111  {
3112  AggrefExprState *aggrefstate = (AggrefExprState *) lfirst(l);
3113  Aggref *aggref = aggrefstate->aggref;
3114  AggStatePerAgg peragg;
3115  AggStatePerTrans pertrans;
3116  int existing_aggno;
3117  int existing_transno;
3118  List *same_input_transnos;
3119  Oid inputTypes[FUNC_MAX_ARGS];
3120  int numArguments;
3121  int numDirectArgs;
3122  HeapTuple aggTuple;
3123  Form_pg_aggregate aggform;
3124  AclResult aclresult;
3125  Oid transfn_oid,
3126  finalfn_oid;
3127  bool sharable;
3128  Oid serialfn_oid,
3129  deserialfn_oid;
3130  Expr *finalfnexpr;
3131  Oid aggtranstype;
3132  Datum textInitVal;
3133  Datum initValue;
3134  bool initValueIsNull;
3135 
3136  /* Planner should have assigned aggregate to correct level */
3137  Assert(aggref->agglevelsup == 0);
3138  /* ... and the split mode should match */
3139  Assert(aggref->aggsplit == aggstate->aggsplit);
3140 
3141  /* 1. Check for already processed aggs which can be re-used */
3142  existing_aggno = find_compatible_peragg(aggref, aggstate, aggno,
3143  &same_input_transnos);
3144  if (existing_aggno != -1)
3145  {
3146  /*
3147  * Existing compatible agg found. so just point the Aggref to the
3148  * same per-agg struct.
3149  */
3150  aggrefstate->aggno = existing_aggno;
3151  continue;
3152  }
3153 
3154  /* Mark Aggref state node with assigned index in the result array */
3155  peragg = &peraggs[++aggno];
3156  peragg->aggref = aggref;
3157  aggrefstate->aggno = aggno;
3158 
3159  /* Fetch the pg_aggregate row */
3160  aggTuple = SearchSysCache1(AGGFNOID,
3161  ObjectIdGetDatum(aggref->aggfnoid));
3162  if (!HeapTupleIsValid(aggTuple))
3163  elog(ERROR, "cache lookup failed for aggregate %u",
3164  aggref->aggfnoid);
3165  aggform = (Form_pg_aggregate) GETSTRUCT(aggTuple);
3166 
3167  /* Check permission to call aggregate function */
3168  aclresult = pg_proc_aclcheck(aggref->aggfnoid, GetUserId(),
3169  ACL_EXECUTE);
3170  if (aclresult != ACLCHECK_OK)
3171  aclcheck_error(aclresult, ACL_KIND_PROC,
3172  get_func_name(aggref->aggfnoid));
3174 
3175  /* planner recorded transition state type in the Aggref itself */
3176  aggtranstype = aggref->aggtranstype;
3177  Assert(OidIsValid(aggtranstype));
3178 
3179  /*
3180  * If this aggregation is performing state combines, then instead of
3181  * using the transition function, we'll use the combine function
3182  */
3183  if (DO_AGGSPLIT_COMBINE(aggstate->aggsplit))
3184  {
3185  transfn_oid = aggform->aggcombinefn;
3186 
3187  /* If not set then the planner messed up */
3188  if (!OidIsValid(transfn_oid))
3189  elog(ERROR, "combinefn not set for aggregate function");
3190  }
3191  else
3192  transfn_oid = aggform->aggtransfn;
3193 
3194  /* Final function only required if we're finalizing the aggregates */
3195  if (DO_AGGSPLIT_SKIPFINAL(aggstate->aggsplit))
3196  peragg->finalfn_oid = finalfn_oid = InvalidOid;
3197  else
3198  peragg->finalfn_oid = finalfn_oid = aggform->aggfinalfn;
3199 
3200  /*
3201  * If finalfn is marked read-write, we can't share transition states;
3202  * but it is okay to share states for AGGMODIFY_SHARABLE aggs. Also,
3203  * if we're not executing the finalfn here, we can share regardless.
3204  */
3205  sharable = (aggform->aggfinalmodify != AGGMODIFY_READ_WRITE) ||
3206  (finalfn_oid == InvalidOid);
3207  peragg->sharable = sharable;
3208 
3209  serialfn_oid = InvalidOid;
3210  deserialfn_oid = InvalidOid;
3211 
3212  /*
3213  * Check if serialization/deserialization is required. We only do it
3214  * for aggregates that have transtype INTERNAL.
3215  */
3216  if (aggtranstype == INTERNALOID)
3217  {
3218  /*
3219  * The planner should only have generated a serialize agg node if
3220  * every aggregate with an INTERNAL state has a serialization
3221  * function. Verify that.
3222  */
3223  if (DO_AGGSPLIT_SERIALIZE(aggstate->aggsplit))
3224  {
3225  /* serialization only valid when not running finalfn */
3227 
3228  if (!OidIsValid(aggform->aggserialfn))
3229  elog(ERROR, "serialfunc not provided for serialization aggregation");
3230  serialfn_oid = aggform->aggserialfn;
3231  }
3232 
3233  /* Likewise for deserialization functions */
3234  if (DO_AGGSPLIT_DESERIALIZE(aggstate->aggsplit))
3235  {
3236  /* deserialization only valid when combining states */
3237  Assert(DO_AGGSPLIT_COMBINE(aggstate->aggsplit));
3238 
3239  if (!OidIsValid(aggform->aggdeserialfn))
3240  elog(ERROR, "deserialfunc not provided for deserialization aggregation");
3241  deserialfn_oid = aggform->aggdeserialfn;
3242  }
3243  }
3244 
3245  /* Check that aggregate owner has permission to call component fns */
3246  {
3247  HeapTuple procTuple;
3248  Oid aggOwner;
3249 
3250  procTuple = SearchSysCache1(PROCOID,
3251  ObjectIdGetDatum(aggref->aggfnoid));
3252  if (!HeapTupleIsValid(procTuple))
3253  elog(ERROR, "cache lookup failed for function %u",
3254  aggref->aggfnoid);
3255  aggOwner = ((Form_pg_proc) GETSTRUCT(procTuple))->proowner;
3256  ReleaseSysCache(procTuple);
3257 
3258  aclresult = pg_proc_aclcheck(transfn_oid, aggOwner,
3259  ACL_EXECUTE);
3260  if (aclresult != ACLCHECK_OK)
3261  aclcheck_error(aclresult, ACL_KIND_PROC,
3262  get_func_name(transfn_oid));
3263  InvokeFunctionExecuteHook(transfn_oid);
3264  if (OidIsValid(finalfn_oid))
3265  {
3266  aclresult = pg_proc_aclcheck(finalfn_oid, aggOwner,
3267  ACL_EXECUTE);
3268  if (aclresult != ACLCHECK_OK)
3269  aclcheck_error(aclresult, ACL_KIND_PROC,
3270  get_func_name(finalfn_oid));
3271  InvokeFunctionExecuteHook(finalfn_oid);
3272  }
3273  if (OidIsValid(serialfn_oid))
3274  {
3275  aclresult = pg_proc_aclcheck(serialfn_oid, aggOwner,
3276  ACL_EXECUTE);
3277  if (aclresult != ACLCHECK_OK)
3278  aclcheck_error(aclresult, ACL_KIND_PROC,
3279  get_func_name(serialfn_oid));
3280  InvokeFunctionExecuteHook(serialfn_oid);
3281  }
3282  if (OidIsValid(deserialfn_oid))
3283  {
3284  aclresult = pg_proc_aclcheck(deserialfn_oid, aggOwner,
3285  ACL_EXECUTE);
3286  if (aclresult != ACLCHECK_OK)
3287  aclcheck_error(aclresult, ACL_KIND_PROC,
3288  get_func_name(deserialfn_oid));
3289  InvokeFunctionExecuteHook(deserialfn_oid);
3290  }
3291  }
3292 
3293  /*
3294  * Get actual datatypes of the (nominal) aggregate inputs. These
3295  * could be different from the agg's declared input types, when the
3296  * agg accepts ANY or a polymorphic type.
3297  */
3298  numArguments = get_aggregate_argtypes(aggref, inputTypes);
3299 
3300  /* Count the "direct" arguments, if any */
3301  numDirectArgs = list_length(aggref->aggdirectargs);
3302 
3303  /* Detect how many arguments to pass to the finalfn */
3304  if (aggform->aggfinalextra)
3305  peragg->numFinalArgs = numArguments + 1;
3306  else
3307  peragg->numFinalArgs = numDirectArgs + 1;
3308 
3309  /* Initialize any direct-argument expressions */
3310  peragg->aggdirectargs = ExecInitExprList(aggref->aggdirectargs,
3311  (PlanState *) aggstate);
3312 
3313  /*
3314  * build expression trees using actual argument & result types for the
3315  * finalfn, if it exists and is required.
3316  */
3317  if (OidIsValid(finalfn_oid))
3318  {
3319  build_aggregate_finalfn_expr(inputTypes,
3320  peragg->numFinalArgs,
3321  aggtranstype,
3322  aggref->aggtype,
3323  aggref->inputcollid,
3324  finalfn_oid,
3325  &finalfnexpr);
3326  fmgr_info(finalfn_oid, &peragg->finalfn);
3327  fmgr_info_set_expr((Node *) finalfnexpr, &peragg->finalfn);
3328  }
3329 
3330  /* get info about the output value's datatype */
3331  get_typlenbyval(aggref->aggtype,
3332  &peragg->resulttypeLen,
3333  &peragg->resulttypeByVal);
3334 
3335  /*
3336  * initval is potentially null, so don't try to access it as a struct
3337  * field. Must do it the hard way with SysCacheGetAttr.
3338  */
3339  textInitVal = SysCacheGetAttr(AGGFNOID, aggTuple,
3341  &initValueIsNull);
3342  if (initValueIsNull)
3343  initValue = (Datum) 0;
3344  else
3345  initValue = GetAggInitVal(textInitVal, aggtranstype);
3346 
3347  /*
3348  * 2. Build working state for invoking the transition function, or
3349  * look up previously initialized working state, if we can share it.
3350  *
3351  * find_compatible_peragg() already collected a list of sharable
3352  * per-Trans's with the same inputs. Check if any of them have the
3353  * same transition function and initial value.
3354  */
3355  existing_transno = find_compatible_pertrans(aggstate, aggref,
3356  sharable,
3357  transfn_oid, aggtranstype,
3358  serialfn_oid, deserialfn_oid,
3359  initValue, initValueIsNull,
3360  same_input_transnos);
3361  if (existing_transno != -1)
3362  {
3363  /*
3364  * Existing compatible trans found, so just point the 'peragg' to
3365  * the same per-trans struct, and mark the trans state as shared.
3366  */
3367  pertrans = &pertransstates[existing_transno];
3368  pertrans->aggshared = true;
3369  peragg->transno = existing_transno;
3370  }
3371  else
3372  {
3373  pertrans = &pertransstates[++transno];
3374  build_pertrans_for_aggref(pertrans, aggstate, estate,
3375  aggref, transfn_oid, aggtranstype,
3376  serialfn_oid, deserialfn_oid,
3377  initValue, initValueIsNull,
3378  inputTypes, numArguments);
3379  peragg->transno = transno;
3380  }
3381  ReleaseSysCache(aggTuple);
3382  }
3383 
3384  /*
3385  * Update aggstate->numaggs to be the number of unique aggregates found.
3386  * Also set numstates to the number of unique transition states found.
3387  */
3388  aggstate->numaggs = aggno + 1;
3389  aggstate->numtrans = transno + 1;
3390 
3391  /*
3392  * Build a single projection computing the required arguments for all
3393  * aggregates at once; if there's more than one, that's considerably
3394  * faster than doing it separately for each.
3395  *
3396  * First create a targetlist representing the values to compute.
3397  */
3398  combined_inputeval = NIL;
3399  column_offset = 0;
3400  for (transno = 0; transno < aggstate->numtrans; transno++)
3401  {
3402  AggStatePerTrans pertrans = &pertransstates[transno];
3403 
3404  /*
3405  * Mark this per-trans state with its starting column in the combined
3406  * slot.
3407  */
3408  pertrans->inputoff = column_offset;
3409 
3410  /*
3411  * If the aggregate has a FILTER, we can only evaluate the filter
3412  * expression, not the actual input expressions, during the combined
3413  * eval step --- unless we're ignoring the filter because this node is
3414  * running combinefns not transfns.
3415  */
3416  if (pertrans->aggref->aggfilter &&
3417  !DO_AGGSPLIT_COMBINE(aggstate->aggsplit))
3418  {
3419  TargetEntry *tle;
3420 
3421  tle = makeTargetEntry(pertrans->aggref->aggfilter,
3422  column_offset + 1, NULL, false);
3423  combined_inputeval = lappend(combined_inputeval, tle);
3424  column_offset++;
3425 
3426  /*
3427  * We'll need separate projection machinery for the real args.
3428  * Arrange to evaluate them into the sortslot previously created.
3429  */
3430  Assert(pertrans->sortslot);
3431  pertrans->evalproj = ExecBuildProjectionInfo(pertrans->aggref->args,
3432  aggstate->tmpcontext,
3433  pertrans->sortslot,
3434  &aggstate->ss.ps,
3435  NULL);
3436  }
3437  else
3438  {
3439  /*
3440  * Add agg's input expressions to combined_inputeval, adjusting
3441  * resnos in the copied target entries to match the combined slot.
3442  */
3443  ListCell *arg;
3444 
3445  foreach(arg, pertrans->aggref->args)
3446  {
3447  TargetEntry *source_tle = lfirst_node(TargetEntry, arg);
3448  TargetEntry *tle;
3449 
3450  tle = flatCopyTargetEntry(source_tle);
3451  tle->resno += column_offset;
3452 
3453  combined_inputeval = lappend(combined_inputeval, tle);
3454  }
3455 
3456  column_offset += list_length(pertrans->aggref->args);
3457  }
3458  }
3459 
3460  /* Now create a projection for the combined targetlist */
3461  combineddesc = ExecTypeFromTL(combined_inputeval, false);
3462  combinedslot = ExecInitExtraTupleSlot(estate);
3463  ExecSetSlotDescriptor(combinedslot, combineddesc);
3464  aggstate->combinedproj = ExecBuildProjectionInfo(combined_inputeval,
3465  aggstate->tmpcontext,
3466  combinedslot,
3467  &aggstate->ss.ps,
3468  NULL);
3469 
3470  /*
3471  * Last, check whether any more aggregates got added onto the node while
3472  * we processed the expressions for the aggregate arguments (including not
3473  * only the regular arguments and FILTER expressions handled immediately
3474  * above, but any direct arguments we might've handled earlier). If so,
3475  * we have nested aggregate functions, which is semantically nonsensical,
3476  * so complain. (This should have been caught by the parser, so we don't
3477  * need to work hard on a helpful error message; but we defend against it
3478  * here anyway, just to be sure.)
3479  */
3480  if (numaggs != list_length(aggstate->aggs))
3481  ereport(ERROR,
3482  (errcode(ERRCODE_GROUPING_ERROR),
3483  errmsg("aggregate function calls cannot be nested")));
3484 
3485  return aggstate;
3486 }
3487 
3488 /*
3489  * Build the state needed to calculate a state value for an aggregate.
3490  *
3491  * This initializes all the fields in 'pertrans'. 'aggref' is the aggregate
3492  * to initialize the state for. 'aggtransfn', 'aggtranstype', and the rest
3493  * of the arguments could be calculated from 'aggref', but the caller has
3494  * calculated them already, so might as well pass them.
3495  */
3496 static void
3498  AggState *aggstate, EState *estate,
3499  Aggref *aggref,
3500  Oid aggtransfn, Oid aggtranstype,
3501  Oid aggserialfn, Oid aggdeserialfn,
3502  Datum initValue, bool initValueIsNull,
3503  Oid *inputTypes, int numArguments)
3504 {
3505  int numGroupingSets = Max(aggstate->maxsets, 1);
3506  Expr *serialfnexpr = NULL;
3507  Expr *deserialfnexpr = NULL;
3508  ListCell *lc;
3509  int numInputs;
3510  int numDirectArgs;
3511  List *sortlist;
3512  int numSortCols;
3513  int numDistinctCols;
3514  int i;
3515 
3516  /* Begin filling in the pertrans data */
3517  pertrans->aggref = aggref;
3518  pertrans->aggshared = false;
3519  pertrans->aggCollation = aggref->inputcollid;
3520  pertrans->transfn_oid = aggtransfn;
3521  pertrans->serialfn_oid = aggserialfn;
3522  pertrans->deserialfn_oid = aggdeserialfn;
3523  pertrans->initValue = initValue;
3524  pertrans->initValueIsNull = initValueIsNull;
3525 
3526  /* Count the "direct" arguments, if any */
3527  numDirectArgs = list_length(aggref->aggdirectargs);
3528 
3529  /* Count the number of aggregated input columns */
3530  pertrans->numInputs = numInputs = list_length(aggref->args);
3531 
3532  pertrans->aggtranstype = aggtranstype;
3533 
3534  /* Detect how many arguments to pass to the transfn */
3535  if (AGGKIND_IS_ORDERED_SET(aggref->aggkind))
3536  pertrans->numTransInputs = numInputs;
3537  else
3538  pertrans->numTransInputs = numArguments;
3539 
3540  /* inputoff and evalproj will be set up later, in ExecInitAgg */
3541 
3542  /*
3543  * When combining states, we have no use at all for the aggregate
3544  * function's transfn. Instead we use the combinefn. In this case, the
3545  * transfn and transfn_oid fields of pertrans refer to the combine
3546  * function rather than the transition function.
3547  */
3548  if (DO_AGGSPLIT_COMBINE(aggstate->aggsplit))
3549  {
3550  Expr *combinefnexpr;
3551 
3552  build_aggregate_combinefn_expr(aggtranstype,
3553  aggref->inputcollid,
3554  aggtransfn,
3555  &combinefnexpr);
3556  fmgr_info(aggtransfn, &pertrans->transfn);
3557  fmgr_info_set_expr((Node *) combinefnexpr, &pertrans->transfn);
3558 
3560  &pertrans->transfn,
3561  2,
3562  pertrans->aggCollation,
3563  (void *) aggstate, NULL);
3564 
3565  /*
3566  * Ensure that a combine function to combine INTERNAL states is not
3567  * strict. This should have been checked during CREATE AGGREGATE, but
3568  * the strict property could have been changed since then.
3569  */
3570  if (pertrans->transfn.fn_strict && aggtranstype == INTERNALOID)
3571  ereport(ERROR,
3572  (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
3573  errmsg("combine function for aggregate %u must be declared as STRICT",
3574  aggref->aggfnoid)));
3575  }
3576  else
3577  {
3578  Expr *transfnexpr;
3579 
3580  /*
3581  * Set up infrastructure for calling the transfn. Note that invtrans
3582  * is not needed here.
3583  */
3584  build_aggregate_transfn_expr(inputTypes,
3585  numArguments,
3586  numDirectArgs,
3587  aggref->aggvariadic,
3588  aggtranstype,
3589  aggref->inputcollid,
3590  aggtransfn,
3591  InvalidOid,
3592  &transfnexpr,
3593  NULL);
3594  fmgr_info(aggtransfn, &pertrans->transfn);
3595  fmgr_info_set_expr((Node *) transfnexpr, &pertrans->transfn);
3596 
3598  &pertrans->transfn,
3599  pertrans->numTransInputs + 1,
3600  pertrans->aggCollation,
3601  (void *) aggstate, NULL);
3602 
3603  /*
3604  * If the transfn is strict and the initval is NULL, make sure input
3605  * type and transtype are the same (or at least binary-compatible), so
3606  * that it's OK to use the first aggregated input value as the initial
3607  * transValue. This should have been checked at agg definition time,
3608  * but we must check again in case the transfn's strictness property
3609  * has been changed.
3610  */
3611  if (pertrans->transfn.fn_strict && pertrans->initValueIsNull)
3612  {
3613  if (numArguments <= numDirectArgs ||
3614  !IsBinaryCoercible(inputTypes[numDirectArgs],
3615  aggtranstype))
3616  ereport(ERROR,
3617  (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
3618  errmsg("aggregate %u needs to have compatible input type and transition type",
3619  aggref->aggfnoid)));
3620  }
3621  }
3622 
3623  /* get info about the state value's datatype */
3624  get_typlenbyval(aggtranstype,
3625  &pertrans->transtypeLen,
3626  &pertrans->transtypeByVal);
3627 
3628  if (OidIsValid(aggserialfn))
3629  {
3630  build_aggregate_serialfn_expr(aggserialfn,
3631  &serialfnexpr);
3632  fmgr_info(aggserialfn, &pertrans->serialfn);
3633  fmgr_info_set_expr((Node *) serialfnexpr, &pertrans->serialfn);
3634 
3636  &pertrans->serialfn,
3637  1,
3638  InvalidOid,
3639  (void *) aggstate, NULL);
3640  }
3641 
3642  if (OidIsValid(aggdeserialfn))
3643  {
3644  build_aggregate_deserialfn_expr(aggdeserialfn,
3645  &deserialfnexpr);
3646  fmgr_info(aggdeserialfn, &pertrans->deserialfn);
3647  fmgr_info_set_expr((Node *) deserialfnexpr, &pertrans->deserialfn);
3648 
3650  &pertrans->deserialfn,
3651  2,
3652  InvalidOid,
3653  (void *) aggstate, NULL);
3654 
3655  }
3656 
3657  /*
3658  * If we're doing either DISTINCT or ORDER BY for a plain agg, then we
3659  * have a list of SortGroupClause nodes; fish out the data in them and
3660  * stick them into arrays. We ignore ORDER BY for an ordered-set agg,
3661  * however; the agg's transfn and finalfn are responsible for that.
3662  *
3663  * Note that by construction, if there is a DISTINCT clause then the ORDER
3664  * BY clause is a prefix of it (see transformDistinctClause).
3665  */
3666  if (AGGKIND_IS_ORDERED_SET(aggref->aggkind))
3667  {
3668  sortlist = NIL;
3669  numSortCols = numDistinctCols = 0;
3670  }
3671  else if (aggref->aggdistinct)
3672  {
3673  sortlist = aggref->aggdistinct;
3674  numSortCols = numDistinctCols = list_length(sortlist);
3675  Assert(numSortCols >= list_length(aggref->aggorder));
3676  }
3677  else
3678  {
3679  sortlist = aggref->aggorder;
3680  numSortCols = list_length(sortlist);
3681  numDistinctCols = 0;
3682  }
3683 
3684  pertrans->numSortCols = numSortCols;
3685  pertrans->numDistinctCols = numDistinctCols;
3686 
3687  /*
3688  * If we have either sorting or filtering to do, create a tupledesc and
3689  * slot corresponding to the aggregated inputs (including sort
3690  * expressions) of the agg.
3691  */
3692  if (numSortCols > 0 || aggref->aggfilter)
3693  {
3694  pertrans->sortdesc = ExecTypeFromTL(aggref->args, false);
3695  pertrans->sortslot = ExecInitExtraTupleSlot(estate);
3696  ExecSetSlotDescriptor(pertrans->sortslot, pertrans->sortdesc);
3697  }
3698 
3699  if (numSortCols > 0)
3700  {
3701  /*
3702  * We don't implement DISTINCT or ORDER BY aggs in the HASHED case
3703  * (yet)
3704  */
3705  Assert(aggstate->aggstrategy != AGG_HASHED && aggstate->aggstrategy != AGG_MIXED);
3706 
3707  /* If we have only one input, we need its len/byval info. */
3708  if (numInputs == 1)
3709  {
3710  get_typlenbyval(inputTypes[numDirectArgs],
3711  &pertrans->inputtypeLen,
3712  &pertrans->inputtypeByVal);
3713  }
3714  else if (numDistinctCols > 0)
3715  {
3716  /* we will need an extra slot to store prior values */
3717  pertrans->uniqslot = ExecInitExtraTupleSlot(estate);
3718  ExecSetSlotDescriptor(pertrans->uniqslot,
3719  pertrans->sortdesc);
3720  }
3721 
3722  /* Extract the sort information for use later */
3723  pertrans->sortColIdx =
3724  (AttrNumber *) palloc(numSortCols * sizeof(AttrNumber));
3725  pertrans->sortOperators =
3726  (Oid *) palloc(numSortCols * sizeof(Oid));
3727  pertrans->sortCollations =
3728  (Oid *) palloc(numSortCols * sizeof(Oid));
3729  pertrans->sortNullsFirst =
3730  (bool *) palloc(numSortCols * sizeof(bool));
3731 
3732  i = 0;
3733  foreach(lc, sortlist)
3734  {
3735  SortGroupClause *sortcl = (SortGroupClause *) lfirst(lc);
3736  TargetEntry *tle = get_sortgroupclause_tle(sortcl, aggref->args);
3737 
3738  /* the parser should have made sure of this */
3739  Assert(OidIsValid(sortcl->sortop));
3740 
3741  pertrans->sortColIdx[i] = tle->resno;
3742  pertrans->sortOperators[i] = sortcl->sortop;
3743  pertrans->sortCollations[i] = exprCollation((Node *) tle->expr);
3744  pertrans->sortNullsFirst[i] = sortcl->nulls_first;
3745  i++;
3746  }
3747  Assert(i == numSortCols);
3748  }
3749 
3750  if (aggref->aggdistinct)
3751  {
3752  Assert(numArguments > 0);
3753 
3754  /*
3755  * We need the equal function for each DISTINCT comparison we will
3756  * make.
3757  */
3758  pertrans->equalfns =
3759  (FmgrInfo *) palloc(numDistinctCols * sizeof(FmgrInfo));
3760 
3761  i = 0;
3762  foreach(lc, aggref->aggdistinct)
3763  {
3764  SortGroupClause *sortcl = (SortGroupClause *) lfirst(lc);
3765 
3766  fmgr_info(get_opcode(sortcl->eqop), &pertrans->equalfns[i]);
3767  i++;
3768  }
3769  Assert(i == numDistinctCols);
3770  }
3771 
3772  pertrans->sortstates = (Tuplesortstate **)
3773  palloc0(sizeof(Tuplesortstate *) * numGroupingSets);
3774 }
3775 
3776 
3777 static Datum
3778 GetAggInitVal(Datum textInitVal, Oid transtype)
3779 {
3780  Oid typinput,
3781  typioparam;
3782  char *strInitVal;
3783  Datum initVal;
3784 
3785  getTypeInputInfo(transtype, &typinput, &typioparam);
3786  strInitVal = TextDatumGetCString(textInitVal);
3787  initVal = OidInputFunctionCall(typinput, strInitVal,
3788  typioparam, -1);
3789  pfree(strInitVal);
3790  return initVal;
3791 }
3792 
3793 /*
3794  * find_compatible_peragg - search for a previously initialized per-Agg struct
3795  *
3796  * Searches the previously looked at aggregates to find one which is compatible
3797  * with this one, with the same input parameters. If no compatible aggregate
3798  * can be found, returns -1.
3799  *
3800  * As a side-effect, this also collects a list of existing, sharable per-Trans
3801  * structs with matching inputs. If no identical Aggref is found, the list is
3802  * passed later to find_compatible_pertrans, to see if we can at least reuse
3803  * the state value of another aggregate.
3804  */
3805 static int
3807  int lastaggno, List **same_input_transnos)
3808 {
3809  int aggno;
3810  AggStatePerAgg peraggs;
3811 
3812  *same_input_transnos = NIL;
3813 
3814  /* we mustn't reuse the aggref if it contains volatile function calls */
3815  if (contain_volatile_functions((Node *) newagg))
3816  return -1;
3817 
3818  peraggs = aggstate->peragg;
3819 
3820  /*
3821  * Search through the list of already seen aggregates. If we find an
3822  * existing identical aggregate call, then we can re-use that one. While
3823  * searching, we'll also collect a list of Aggrefs with the same input
3824  * parameters. If no matching Aggref is found, the caller can potentially
3825  * still re-use the transition state of one of them. (At this stage we
3826  * just compare the parsetrees; whether different aggregates share the
3827  * same transition function will be checked later.)
3828  */
3829  for (aggno = 0; aggno <= lastaggno; aggno++)
3830  {
3831  AggStatePerAgg peragg;
3832  Aggref *existingRef;
3833 
3834  peragg = &peraggs[aggno];
3835  existingRef = peragg->aggref;
3836 
3837  /* all of the following must be the same or it's no match */
3838  if (newagg->inputcollid != existingRef->inputcollid ||
3839  newagg->aggtranstype != existingRef->aggtranstype ||
3840  newagg->aggstar != existingRef->aggstar ||
3841  newagg->aggvariadic != existingRef->aggvariadic ||
3842  newagg->aggkind != existingRef->aggkind ||
3843  !equal(newagg->args, existingRef->args) ||
3844  !equal(newagg->aggorder, existingRef->aggorder) ||
3845  !equal(newagg->aggdistinct, existingRef->aggdistinct) ||
3846  !equal(newagg->aggfilter, existingRef->aggfilter))
3847  continue;
3848 
3849  /* if it's the same aggregate function then report exact match */
3850  if (newagg->aggfnoid == existingRef->aggfnoid &&
3851  newagg->aggtype == existingRef->aggtype &&
3852  newagg->aggcollid == existingRef->aggcollid &&
3853  equal(newagg->aggdirectargs, existingRef->aggdirectargs))
3854  {
3855  list_free(*same_input_transnos);
3856  *same_input_transnos = NIL;
3857  return aggno;
3858  }
3859 
3860  /*
3861  * Not identical, but it had the same inputs. If the final function
3862  * permits sharing, return its transno to the caller, in case we can
3863  * re-use its per-trans state. (If there's already sharing going on,
3864  * we might report a transno more than once. find_compatible_pertrans
3865  * is cheap enough that it's not worth spending cycles to avoid that.)
3866  */
3867  if (peragg->sharable)
3868  *same_input_transnos = lappend_int(*same_input_transnos,
3869  peragg->transno);
3870  }
3871 
3872  return -1;
3873 }
3874 
3875 /*
3876  * find_compatible_pertrans - search for a previously initialized per-Trans
3877  * struct
3878  *
3879  * Searches the list of transnos for a per-Trans struct with the same
3880  * transition function and initial condition. (The inputs have already been
3881  * verified to match.)
3882  */
3883 static int
3884 find_compatible_pertrans(AggState *aggstate, Aggref *newagg, bool sharable,
3885  Oid aggtransfn, Oid aggtranstype,
3886  Oid aggserialfn, Oid aggdeserialfn,
3887  Datum initValue, bool initValueIsNull,
3888  List *transnos)
3889 {
3890  ListCell *lc;
3891 
3892  /* If this aggregate can't share transition states, give up */
3893  if (!sharable)
3894  return -1;
3895 
3896  foreach(lc, transnos)
3897  {
3898  int transno = lfirst_int(lc);
3899  AggStatePerTrans pertrans = &aggstate->pertrans[transno];
3900 
3901  /*
3902  * if the transfns or transition state types are not the same then the
3903  * state can't be shared.
3904  */
3905  if (aggtransfn != pertrans->transfn_oid ||
3906  aggtranstype != pertrans->aggtranstype)
3907  continue;
3908 
3909  /*
3910  * The serialization and deserialization functions must match, if
3911  * present, as we're unable to share the trans state for aggregates
3912  * which will serialize or deserialize into different formats.
3913  * Remember that these will be InvalidOid if they're not required for
3914  * this agg node.
3915  */
3916  if (aggserialfn != pertrans->serialfn_oid ||
3917  aggdeserialfn != pertrans->deserialfn_oid)
3918  continue;
3919 
3920  /*
3921  * Check that the initial condition matches, too.
3922  */
3923  if (initValueIsNull && pertrans->initValueIsNull)
3924  return transno;
3925 
3926  if (!initValueIsNull && !pertrans->initValueIsNull &&
3927  datumIsEqual(initValue, pertrans->initValue,
3928  pertrans->transtypeByVal, pertrans->transtypeLen))
3929  return transno;
3930  }
3931  return -1;
3932 }
3933 
3934 void
3936 {
3938  int transno;
3939  int numGroupingSets = Max(node->maxsets, 1);
3940  int setno;
3941 
3942  /* Make sure we have closed any open tuplesorts */
3943 
3944  if (node->sort_in)
3945  tuplesort_end(node->sort_in);
3946  if (node->sort_out)
3947  tuplesort_end(node->sort_out);
3948 
3949  for (transno = 0; transno < node->numtrans; transno++)
3950  {
3951  AggStatePerTrans pertrans = &node->pertrans[transno];
3952 
3953  for (setno = 0; setno < numGroupingSets; setno++)
3954  {
3955  if (pertrans->sortstates[setno])
3956  tuplesort_end(pertrans->sortstates[setno]);
3957  }
3958  }
3959 
3960  /* And ensure any agg shutdown callbacks have been called */
3961  for (setno = 0; setno < numGroupingSets; setno++)
3962  ReScanExprContext(node->aggcontexts[setno]);
3963  if (node->hashcontext)
3965 
3966  /*
3967  * We don't actually free any ExprContexts here (see comment in
3968  * ExecFreeExprContext), just unlinking the output one from the plan node
3969  * suffices.
3970  */
3971  ExecFreeExprContext(&node->ss.ps);
3972 
3973  /* clean up tuple table */
3975 
3976  outerPlan = outerPlanState(node);
3977  ExecEndNode(outerPlan);
3978 }
3979 
3980 void
3982 {
3983  ExprContext *econtext = node->ss.ps.ps_ExprContext;
3985  Agg *aggnode = (Agg *) node->ss.ps.plan;
3986  int transno;
3987  int numGroupingSets = Max(node->maxsets, 1);
3988  int setno;
3989 
3990  node->agg_done = false;
3991 
3992  if (node->aggstrategy == AGG_HASHED)
3993  {
3994  /*
3995  * In the hashed case, if we haven't yet built the hash table then we
3996  * can just return; nothing done yet, so nothing to undo. If subnode's
3997  * chgParam is not NULL then it will be re-scanned by ExecProcNode,
3998  * else no reason to re-scan it at all.
3999  */
4000  if (!node->table_filled)
4001  return;
4002 
4003  /*
4004  * If we do have the hash table, and the subplan does not have any
4005  * parameter changes, and none of our own parameter changes affect
4006  * input expressions of the aggregated functions, then we can just
4007  * rescan the existing hash table; no need to build it again.
4008  */
4009  if (outerPlan->chgParam == NULL &&
4010  !bms_overlap(node->ss.ps.chgParam, aggnode->aggParams))
4011  {
4013  &node->perhash[0].hashiter);
4014  select_current_set(node, 0, true);
4015  return;
4016  }
4017  }
4018 
4019  /* Make sure we have closed any open tuplesorts */
4020  for (transno = 0; transno < node->numtrans; transno++)
4021  {
4022  for (setno = 0; setno < numGroupingSets; setno++)
4023  {
4024  AggStatePerTrans pertrans = &node->pertrans[transno];
4025 
4026  if (pertrans->sortstates[setno])
4027  {
4028  tuplesort_end(pertrans->sortstates[setno]);
4029  pertrans->sortstates[setno] = NULL;
4030  }
4031  }
4032  }
4033 
4034  /*
4035  * We don't need to ReScanExprContext the output tuple context here;
4036  * ExecReScan already did it. But we do need to reset our per-grouping-set
4037  * contexts, which may have transvalues stored in them. (We use rescan
4038  * rather than just reset because transfns may have registered callbacks
4039  * that need to be run now.) For the AGG_HASHED case, see below.
4040  */
4041 
4042  for (setno = 0; setno < numGroupingSets; setno++)
4043  {
4044  ReScanExprContext(node->aggcontexts[setno]);
4045  }
4046 
4047  /* Release first tuple of group, if we have made a copy */
4048  if (node->grp_firstTuple != NULL)
4049  {
4051  node->grp_firstTuple = NULL;
4052  }
4054 
4055  /* Forget current agg values */
4056  MemSet(econtext->ecxt_aggvalues, 0, sizeof(Datum) * node->numaggs);
4057  MemSet(econtext->ecxt_aggnulls, 0, sizeof(bool) * node->numaggs);
4058 
4059  /*
4060  * With AGG_HASHED/MIXED, the hash table is allocated in a sub-context of
4061  * the hashcontext. This used to be an issue, but now, resetting a context
4062  * automatically deletes sub-contexts too.
4063  */
4064  if (node->aggstrategy == AGG_HASHED || node->aggstrategy == AGG_MIXED)
4065  {
4067  /* Rebuild an empty hash table */
4068  build_hash_table(node);
4069  node->table_filled = false;
4070  /* iterator will be reset when the table is filled */
4071  }
4072 
4073  if (node->aggstrategy != AGG_HASHED)
4074  {
4075  /*
4076  * Reset the per-group state (in particular, mark transvalues null)
4077  */
4078  MemSet(node->pergroup, 0,
4079  sizeof(AggStatePerGroupData) * node->numaggs * numGroupingSets);
4080 
4081  /* reset to phase 1 */
4082  initialize_phase(node, 1);
4083 
4084  node->input_done = false;
4085  node->projected_set = -1;
4086  }
4087 
4088  if (outerPlan->chgParam == NULL)
4089  ExecReScan(outerPlan);
4090 }
4091 
4092 
4093 /***********************************************************************
4094  * API exposed to aggregate functions
4095  ***********************************************************************/
4096 
4097 
4098 /*
4099  * AggCheckCallContext - test if a SQL function is being called as an aggregate
4100  *
4101  * The transition and/or final functions of an aggregate may want to verify
4102  * that they are being called as aggregates, rather than as plain SQL
4103  * functions. They should use this function to do so. The return value
4104  * is nonzero if being called as an aggregate, or zero if not. (Specific
4105  * nonzero values are AGG_CONTEXT_AGGREGATE or AGG_CONTEXT_WINDOW, but more
4106  * values could conceivably appear in future.)
4107  *
4108  * If aggcontext isn't NULL, the function also stores at *aggcontext the
4109  * identity of the memory context that aggregate transition values are being
4110  * stored in. Note that the same aggregate call site (flinfo) may be called
4111  * interleaved on different transition values in different contexts, so it's
4112  * not kosher to cache aggcontext under fn_extra. It is, however, kosher to
4113  * cache it in the transvalue itself (for internal-type transvalues).
4114  */
4115 int
4117 {
4118  if (fcinfo->context && IsA(fcinfo->context, AggState))
4119  {
4120  if (aggcontext)
4121  {
4122  AggState *aggstate = ((AggState *) fcinfo->context);
4123  ExprContext *cxt = aggstate->curaggcontext;
4124 
4125  *aggcontext = cxt->ecxt_per_tuple_memory;
4126  }
4127  return AGG_CONTEXT_AGGREGATE;
4128  }
4129  if (fcinfo->context && IsA(fcinfo->context, WindowAggState))
4130  {
4131  if (aggcontext)
4132  *aggcontext = ((WindowAggState *) fcinfo->context)->curaggcontext;
4133  return AGG_CONTEXT_WINDOW;
4134  }
4135 
4136  /* this is just to prevent "uninitialized variable" warnings */
4137  if (aggcontext)
4138  *aggcontext = NULL;
4139  return 0;
4140 }
4141 
4142 /*
4143  * AggGetAggref - allow an aggregate support function to get its Aggref
4144  *
4145  * If the function is being called as an aggregate support function,
4146  * return the Aggref node for the aggregate call. Otherwise, return NULL.
4147  *
4148  * Aggregates sharing the same inputs and transition functions can get
4149  * merged into a single transition calculation. If the transition function
4150  * calls AggGetAggref, it will get some one of the Aggrefs for which it is
4151  * executing. It must therefore not pay attention to the Aggref fields that
4152  * relate to the final function, as those are indeterminate. But if a final
4153  * function calls AggGetAggref, it will get a precise result.
4154  *
4155  * Note that if an aggregate is being used as a window function, this will
4156  * return NULL. We could provide a similar function to return the relevant
4157  * WindowFunc node in such cases, but it's not needed yet.
4158  */
4159 Aggref *
4161 {
4162  if (fcinfo->context && IsA(fcinfo->context, AggState))
4163  {
4164  AggState *aggstate = (AggState *) fcinfo->context;
4165  AggStatePerAgg curperagg;
4166  AggStatePerTrans curpertrans;
4167 
4168  /* check curperagg (valid when in a final function) */
4169  curperagg = aggstate->curperagg;
4170 
4171  if (curperagg)
4172  return curperagg->aggref;
4173 
4174  /* check curpertrans (valid when in a transition function) */
4175  curpertrans = aggstate->curpertrans;
4176 
4177  if (curpertrans)
4178  return curpertrans->aggref;
4179  }
4180  return NULL;
4181 }
4182 
4183 /*
4184  * AggGetTempMemoryContext - fetch short-term memory context for aggregates
4185  *
4186  * This is useful in agg final functions; the context returned is one that
4187  * the final function can safely reset as desired. This isn't useful for
4188  * transition functions, since the context returned MAY (we don't promise)
4189  * be the same as the context those are called in.
4190  *
4191  * As above, this is currently not useful for aggs called as window functions.
4192  */
4195 {
4196  if (fcinfo->context && IsA(fcinfo->context, AggState))
4197  {
4198  AggState *aggstate = (AggState *) fcinfo->context;
4199 
4200  return aggstate->tmpcontext->ecxt_per_tuple_memory;
4201  }
4202  return NULL;
4203 }
4204 
4205 /*
4206  * AggStateIsShared - find out whether transition state is shared
4207  *
4208  * If the function is being called as an aggregate support function,
4209  * return TRUE if the aggregate's transition state is shared across
4210  * multiple aggregates, FALSE if it is not.
4211  *
4212  * Returns TRUE if not called as an aggregate support function.
4213  * This is intended as a conservative answer, ie "no you'd better not
4214  * scribble on your input". In particular, will return TRUE if the
4215  * aggregate is being used as a window function, which is a scenario
4216  * in which changing the transition state is a bad idea. We might
4217  * want to refine the behavior for the window case in future.
4218  */
4219 bool
4221 {
4222  if (fcinfo->context && IsA(fcinfo->context, AggState))
4223  {
4224  AggState *aggstate = (AggState *) fcinfo->context;
4225  AggStatePerAgg curperagg;
4226  AggStatePerTrans curpertrans;
4227 
4228  /* check curperagg (valid when in a final function) */
4229  curperagg = aggstate->curperagg;
4230 
4231  if (curperagg)
4232  return aggstate->pertrans[curperagg->transno].aggshared;
4233 
4234  /* check curpertrans (valid when in a transition function) */
4235  curpertrans = aggstate->curpertrans;
4236 
4237  if (curpertrans)
4238  return curpertrans->aggshared;
4239  }
4240  return true;
4241 }
4242 
4243 /*
4244  * AggRegisterCallback - register a cleanup callback for an aggregate
4245  *
4246  * This is useful for aggs to register shutdown callbacks, which will ensure
4247  * that non-memory resources are freed. The callback will occur just before
4248  * the associated aggcontext (as returned by AggCheckCallContext) is reset,
4249  * either between groups or as a result of rescanning the query. The callback
4250  * will NOT be called on error paths. The typical use-case is for freeing of
4251  * tuplestores or tuplesorts maintained in aggcontext, or pins held by slots
4252  * created by the agg functions. (The callback will not be called until after
4253  * the result of the finalfn is no longer needed, so it's safe for the finalfn
4254  * to return data that will be freed by the callback.)
4255  *
4256  * As above, this is currently not useful for aggs called as window functions.
4257  */
4258 void
4261  Datum arg)
4262 {
4263  if (fcinfo->context && IsA(fcinfo->context, AggState))
4264  {
4265  AggState *aggstate = (AggState *) fcinfo->context;
4266  ExprContext *cxt = aggstate->curaggcontext;
4267 
4268  RegisterExprContextCallback(cxt, func, arg);
4269 
4270  return;
4271  }
4272  elog(ERROR, "aggregate function cannot register a callback in this context");
4273 }
4274 
4275 
4276 /*
4277  * aggregate_dummy - dummy execution routine for aggregate functions
4278  *
4279  * This function is listed as the implementation (prosrc field) of pg_proc
4280  * entries for aggregate functions. Its only purpose is to throw an error
4281  * if someone mistakenly executes such a function in the normal way.
4282  *
4283  * Perhaps someday we could assign real meaning to the prosrc field of
4284  * an aggregate?
4285  */
4286 Datum
4288 {
4289  elog(ERROR, "aggregate function %u called as normal function",
4290  fcinfo->flinfo->fn_oid);
4291  return (Datum) 0; /* keep compiler quiet */
4292 }
FmgrInfo * eqfunctions
Definition: nodeAgg.c:521
List * aggdistinct
Definition: primnodes.h:303
signed short int16
Definition: c.h:245
struct AggStatePerTransData * AggStatePerTrans
Definition: execnodes.h:1789
AggStatePerGroup * hash_pergroup
Definition: execnodes.h:1832
#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:1790
#define ScanTupleHashTable(htable, iter)
Definition: execnodes.h:634
static void select_current_set(AggState *aggstate, int setno, bool is_hash)
Definition: nodeAgg.c:597
int numCols
Definition: plannodes.h:785
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:2082
Datum aggregate_dummy(PG_FUNCTION_ARGS)
Definition: nodeAgg.c:4287
bool aggvariadic
Definition: primnodes.h:306
bool tts_isempty
Definition: tuptable.h:116
int bms_first_member(Bitmapset *a)
Definition: bitmapset.c:885
AggStatePerPhase phases
Definition: execnodes.h:1821
#define IsA(nodeptr, _type_)
Definition: nodes.h:561
void tuplesort_performsort(Tuplesortstate *state)
Definition: tuplesort.c:1656
AttrNumber * hashGrpColIdxInput
Definition: nodeAgg.c:525
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate)
Definition: execTuples.c:852
Datum * ecxt_aggvalues
Definition: execnodes.h:213
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:656
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:786
ProjectionInfo * ps_ProjInfo
Definition: execnodes.h:882
#define Anum_pg_aggregate_agginitval
Definition: pg_aggregate.h:117
static void agg_fill_hash_table(AggState *aggstate)
Definition: nodeAgg.c:2523
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:2972
int numaggs
Definition: execnodes.h:1798
Oid GetUserId(void)
Definition: miscinit.c:284
bool agg_done
Definition: execnodes.h:1814
#define castNode(_type_, nodeptr)
Definition: nodes.h:579
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:1824
List * all_grouped_cols
Definition: execnodes.h:1818
Tuplesortstate * sort_out
Definition: execnodes.h:1823
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:84
static void finalize_partialaggregate(AggState *aggstate, AggStatePerAgg peragg, AggStatePerGroup pergroupstate, Datum *resultVal, bool *resultIsNull)
Definition: nodeAgg.c:1621
ScanState ss
Definition: execnodes.h:1796
ExprContext * ps_ExprContext
Definition: execnodes.h:881
MinimalTuple firstTuple
Definition: execnodes.h:589
MemoryContext ecxt_per_tuple_memory
Definition: execnodes.h:203
tuplehash_iterator TupleHashIterator
Definition: execnodes.h:621
static TupleHashEntryData * lookup_hash_entry(AggState *aggstate)
Definition: nodeAgg.c:2060
void ExecReScan(PlanState *node)
Definition: execAmi.c:76
int bms_next_member(const Bitmapset *a, int prevbit)
Definition: bitmapset.c:937
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:1804
Definition: nodes.h:510
bool execTuplesMatch(TupleTableSlot *slot1, TupleTableSlot *slot2, int numCols, AttrNumber *matchColIdx, FmgrInfo *eqfunctions, MemoryContext evalContext)
Definition: execGrouping.c:69
AggSplit aggsplit
Definition: execnodes.h:1801
static TupleTableSlot * ExecAgg(PlanState *pstate)
Definition: nodeAgg.c:2134
bool * nullsFirst
Definition: plannodes.h:749
int errcode(int sqlerrcode)
Definition: elog.c:575
List * args
Definition: primnodes.h:301
#define MemSet(start, val, len)
Definition: c.h:863
AttrNumber varattno
Definition: primnodes.h:168
Datum * tts_values
Definition: tuptable.h:125
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1104
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:135
void build_aggregate_deserialfn_expr(Oid deserialfn_oid, Expr **deserialfnexpr)
Definition: parse_agg.c:1995
static void finalize_aggregate(AggState *aggstate, AggStatePerAgg peragg, AggStatePerGroup pergroupstate, Datum *resultVal, bool *resultIsNull)
Definition: nodeAgg.c:1519
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:2019
bool contain_volatile_functions(Node *clause)
Definition: clauses.c:957
AggStatePerTrans pertrans
Definition: execnodes.h:1806
EState * state
Definition: execnodes.h:849
int projected_set
Definition: execnodes.h:1815
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:366
HeapTuple grp_firstTuple
Definition: execnodes.h:1827
Definition: primnodes.h:163
Aggref * aggref
Definition: nodeAgg.c:415
static TupleTableSlot * project_aggregates(AggState *aggstate)
Definition: nodeAgg.c:1807
int current_set
Definition: execnodes.h:1816
#define OidIsValid(objectId)
Definition: c.h:532
#define DO_AGGSPLIT_COMBINE(as)
Definition: nodes.h:769
int natts
Definition: tupdesc.h:73
void ExecFreeExprContext(PlanState *planstate)
Definition: execUtils.c:521
int numtrans
Definition: execnodes.h:1799
TupleDesc sortdesc
Definition: nodeAgg.c:366
Oid * sortOperators
Definition: plannodes.h:747
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:445
ExprContext * tmpcontext
Definition: execnodes.h:1809
FmgrInfo transfn
Definition: nodeAgg.c:302
static void prepare_projection_slot(AggState *aggstate, TupleTableSlot *slot, int currentSet)
Definition: nodeAgg.c:1699
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:1101
#define AGGKIND_IS_ORDERED_SET(kind)
Definition: pg_aggregate.h:133
int maxsets
Definition: execnodes.h:1820
FmgrInfo * flinfo
Definition: fmgr.h:79
#define DO_AGGSPLIT_SERIALIZE(as)
Definition: nodes.h:771
static AggStatePerGroup * lookup_hash_entries(AggState *aggstate)
Definition: nodeAgg.c:2105
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:783
AggState * ExecInitAgg(Agg *node, EState *estate, int eflags)
Definition: nodeAgg.c:2697
bool table_filled
Definition: execnodes.h:1829
AggStrategy aggstrategy
Definition: execnodes.h:1800
static TupleTableSlot * agg_retrieve_hash_table(AggState *aggstate)
Definition: nodeAgg.c:2570
#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:2170
#define AGG_CONTEXT_AGGREGATE
Definition: fmgr.h:694
struct TupleHashEntryData TupleHashEntryData
static void find_hash_columns(AggState *aggstate)
Definition: nodeAgg.c:1937
struct AggStatePerTransData AggStatePerTransData
Tuplesortstate * sort_in
Definition: execnodes.h:1822
#define EXEC_FLAG_BACKWARD
Definition: executor.h:60
#define lfirst_node(type, lc)
Definition: pg_list.h:109
#define outerPlanState(node)
Definition: execnodes.h:893
bool tuplesort_gettupleslot(Tuplesortstate *state, bool forward, bool copy, TupleTableSlot *slot, Datum *abbrev)
Definition: tuplesort.c:1996
int bms_num_members(const Bitmapset *a)
Definition: bitmapset.c:605
static void finalize_aggregates(AggState *aggstate, AggStatePerAgg peragg, AggStatePerGroup pergroup)
Definition: nodeAgg.c:1744
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:4220
Aggref * aggref
Definition: execnodes.h:657
#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:789
static int initValue(long lng_val)
Definition: informix.c:702
MemoryContext tablecxt
Definition: execnodes.h:610
void ExecAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc)
Definition: execUtils.c:492
bool * tts_isnull
Definition: tuptable.h:126
static Datum ExecEvalExpr(ExprState *state, ExprContext *econtext, bool *isNull)
Definition: executor.h:286
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3399
static void process_ordered_aggregate_multi(AggState *aggstate, AggStatePerTrans pertrans, AggStatePerGroup pergroupstate)
Definition: nodeAgg.c:1426
List * aggorder
Definition: primnodes.h:302
static void build_hash_table(AggState *aggstate)
Definition: nodeAgg.c:1888
#define fmgr_info_set_expr(expr, finfo)
Definition: fmgr.h:104
AttrNumber resno
Definition: primnodes.h:1369
#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:3778
AggStatePerAgg curperagg
Definition: execnodes.h:1811
AttrNumber * sortColIdx
Definition: nodeAgg.c:321
static bool find_unaggregated_cols_walker(Node *node, Bitmapset **colnos)
Definition: nodeAgg.c:1848
AggStatePerHash perhash
Definition: execnodes.h:1831
bool argnull[FUNC_MAX_ARGS]
Definition: fmgr.h:86
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
TargetEntry * flatCopyTargetEntry(TargetEntry *src_tle)
Definition: makefuncs.c:268
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:896
#define EXEC_FLAG_REWIND
Definition: executor.h:59
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
Definition: lsyscache.c:2599
#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:1943
TargetEntry * makeTargetEntry(Expr *expr, AttrNumber resno, char *resname, bool resjunk)
Definition: makefuncs.c:235
Bitmapset * grouped_cols
Definition: execnodes.h:1817
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:4194
List * lappend_int(List *list, int datum)
Definition: list.c:146
Bitmapset * chgParam
Definition: execnodes.h:875
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:745
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:1830
Plan plan
Definition: plannodes.h:782
AttrNumber * hashGrpColIdxHash
Definition: nodeAgg.c:526
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
bool input_done
Definition: execnodes.h:1813
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:121
ProjectionInfo * combinedproj
Definition: execnodes.h:1834
ExprContext * curaggcontext
Definition: execnodes.h:1810
ExprContext * hashcontext
Definition: execnodes.h:1807
bool * ecxt_aggnulls
Definition: execnodes.h:214
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:3806
AggStatePerPhase phase
Definition: execnodes.h:1802
void * palloc0(Size size)
Definition: mcxt.c:877
ExecProcNodeMtd ExecProcNode
Definition: execnodes.h:853
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:246
FunctionCallInfoData serialfn_fcinfo
Definition: nodeAgg.c:393
AggStatePerGroup pergroup
Definition: execnodes.h:1826
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:791
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:847
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:632
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:806
ExprContext ** aggcontexts
Definition: execnodes.h:1808
#define makeNode(_type_)
Definition: nodes.h:558
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:199
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
FmgrInfo * hashfunctions
Definition: nodeAgg.c:520
#define Assert(condition)
Definition: c.h:681
#define lfirst(lc)
Definition: pg_list.h:106
void RegisterExprContextCallback(ExprContext *econtext, ExprContextCallbackFunction function, Datum arg)
Definition: execUtils.c:737
FmgrInfo serialfn
Definition: nodeAgg.c:305
#define EXEC_FLAG_MARK
Definition: executor.h:61
AggSplit aggsplit
Definition: plannodes.h:784
struct AggStatePerAggData * AggStatePerAgg
Definition: execnodes.h:1788
void ExecReScanAgg(AggState *node)
Definition: nodeAgg.c:3981
#define DatumIsReadWriteExpandedObject(d, isnull, typlen)
void build_aggregate_serialfn_expr(Oid serialfn_oid, Expr **serialfnexpr)
Definition: parse_agg.c:1972
FormData_pg_aggregate * Form_pg_aggregate
Definition: pg_aggregate.h:89
Expr * expr
Definition: primnodes.h:1368
AggSplit aggsplit
Definition: primnodes.h:310
bool MemoryContextContains(MemoryContext context, void *pointer)
Definition: mcxt.c:566
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:1882
ProjectionInfo * evalproj
Definition: nodeAgg.c:357
size_t Size
Definition: c.h:350
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:423
#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:2039
long numGroups
Definition: plannodes.h:788
Oid exprCollation(const Node *expr)
Definition: nodeFuncs.c:720
#define DO_AGGSPLIT_SKIPFINAL(as)
Definition: nodes.h:770
void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
Definition: lsyscache.c:2001
Expr * aggfilter
Definition: primnodes.h:304
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4116
#define MAXALIGN(LEN)
Definition: c.h:576
void ReScanExprContext(ExprContext *econtext)
Definition: execUtils.c:381
static Bitmapset * find_unaggregated_cols(AggState *aggstate)
Definition: nodeAgg.c:1834
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:698
#define DO_AGGSPLIT_DESERIALIZE(as)
Definition: nodes.h:772
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:1803
TupleDesc ExecGetResultType(PlanState *planstate)
Definition: execUtils.c:474
List * targetlist
Definition: plannodes.h:144
ExprState * qual
Definition: execnodes.h:865
#define DatumGetPointer(X)
Definition: postgres.h:555
AttrNumber * sortColIdx
Definition: plannodes.h:746
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:443
void AggRegisterCallback(FunctionCallInfo fcinfo, ExprContextCallbackFunction func, Datum arg)
Definition: nodeAgg.c:4259
AggStrategy
Definition: nodes.h:736
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:557
Oid * grpOperators
Definition: plannodes.h:787
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:792
AggStatePerAgg peragg
Definition: execnodes.h:1805
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:4446
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:3884
void * arg
AggStatePerTrans curpertrans
Definition: execnodes.h:1812
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:1333
#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 TRUE
Definition: c.h:215
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:98
Definition: plannodes.h:780
#define elog
Definition: elog.h:219
struct AggStatePerHashData AggStatePerHashData
List * aggs
Definition: execnodes.h:1797
struct AggStatePerAggData AggStatePerAggData
TupleTableSlot * sortslot
Definition: nodeAgg.c:364
void(* ExprContextCallbackFunction)(Datum arg)
Definition: execnodes.h:160
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:748
int get_aggregate_argtypes(Aggref *aggref, Oid *inputTypes)
Definition: parse_agg.c:1801
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:3497
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:3935
#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:329
#define ResetExprContext(econtext)
Definition: executor.h:471
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:4160
bool * sortNullsFirst
Definition: nodeAgg.c:324