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