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