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