LCOV - code coverage report
Current view: top level - src/backend/executor - nodeAgg.c (source / functions) Hit Total Coverage
Test: PostgreSQL 12beta2 Lines: 1087 1129 96.3 %
Date: 2019-06-19 16:07:09 Functions: 36 38 94.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13