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