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