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