text: /*-------------------------------------------------------------------------
   *
   * nodeAgg.h
   *	  prototypes for nodeAgg.c
   *
   *
   * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
   * Portions Copyright (c) 1994, Regents of the University of California
   *
   * src/include/executor/nodeAgg.h
   *
   *-------------------------------------------------------------------------
   */
  #ifndef NODEAGG_H
  #define NODEAGG_H
  
  #include "fmgr.h"
  #include "executor/tuptable.h"
  #include "nodes/execnodes.h"
  #include "nodes/primnodes.h"
  #include "utils/tuplesort.h"
  
  extern AggState *ExecInitAgg(Agg *node, EState *estate, int eflags);
  extern struct TupleTableSlot *ExecAgg(AggState *node);
  extern void ExecEndAgg(AggState *node);
  extern void ExecReScanAgg(AggState *node);
  
  extern Size hash_agg_entry_size(int numAggs);
  
  extern Datum aggregate_dummy(PG_FUNCTION_ARGS);
  
  /* MPP needs to see these in execHHashAgg.c */
  
  /*
   * AggStatePerTransData - per aggregate state value information
   *
   * Working state for updating the aggregate's state value, by calling the
   * transition function with an input row. This struct does not store the
   * information needed to produce the final aggregate result from the transition
   * state, that's stored in AggStatePerAggData instead. This separation allows
   * multiple aggregate results to be produced from a single state value.
   */
  typedef struct AggStatePerTransData
  {
  	/*
  	 * These values are set up during ExecInitAgg() and do not change
  	 * thereafter:
  	 */
  
  	/*
  	 * Link to an Aggref expr this state value is for.
  	 *
  	 * There can be multiple Aggref's sharing the same state value, as long as
  	 * the inputs and transition function are identical. This points to the
  	 * first one of them.
  	 */
  	Aggref	   *aggref;
  
  	/*
  	 * Nominal number of arguments for aggregate function.  For plain aggs,
  	 * this excludes any ORDER BY expressions.  For ordered-set aggs, this
  	 * counts both the direct and aggregated (ORDER BY) arguments.
  	 */
  	int			numArguments;
  
  	/*
  	 * Number of aggregated input columns.  This includes ORDER BY expressions
  	 * in both the plain-agg and ordered-set cases.  Ordered-set direct args
  	 * are not counted, though.
  	 */
  	int			numInputs;
  
  	/*
  	 * Number of aggregated input columns to pass to the transfn.  This
  	 * includes the ORDER BY columns for ordered-set aggs, but not for plain
  	 * aggs.  (This doesn't count the transition state value!)
  	 */
  	int			numTransInputs;
  
  	/* Oids of transfer functions */
  	Oid			transfn_oid;
  
  	/* Oids of combine functions, for spilling */
  	Oid			combinefn_oid;
  
  	/* Oid of the serialization function or InvalidOid */
  	Oid			serialfn_oid;
  
  	/* Oid of the deserialization function or InvalidOid */
  	Oid			deserialfn_oid;
  
  	/* Oid of state value's datatype */
  	Oid			aggtranstype;
  
  	/* ExprStates of the FILTER and argument expressions. */
  	ExprState  *aggfilter;		/* state of FILTER expression, if any */
  	List	   *args;			/* states of aggregated-argument expressions */
  	List	   *aggdirectargs;	/* states of direct-argument expressions */
  
  	/*
  	 * fmgr lookup data for transition function or combine function.  Note in
  	 * particular that the fn_strict flag is kept here.
  	 */
  	FmgrInfo	transfn;
  
  	/* fmgr lookup data for combine function */
  	FmgrInfo	combinefn;
  
  	/* fmgr lookup data for serialization function */
  	FmgrInfo	serialfn;
  
  	/* fmgr lookup data for deserialization function */
  	FmgrInfo	deserialfn;
  
  	/* Input collation derived for aggregate */
  	Oid			aggCollation;
  
  	/* number of sorting columns */
  	int			numSortCols;
  
  	/* number of sorting columns to consider in DISTINCT comparisons */
  	/* (this is either zero or the same as numSortCols) */
  	int			numDistinctCols;
  
  	/* deconstructed sorting information (arrays of length numSortCols) */
  	AttrNumber *sortColIdx;
  	Oid		   *sortOperators;
  	Oid		   *sortCollations;
  	bool	   *sortNullsFirst;
  
  	/*
  	 * fmgr lookup data for input columns' equality operators --- only
  	 * set/used when aggregate has DISTINCT flag.  Note that these are in
  	 * order of sort column index, not parameter index.
  	 */
  	FmgrInfo   *equalfns;		/* array of length numDistinctCols */
  
  	/*
  	 * initial value from pg_aggregate entry
  	 */
  	Datum		initValue;
  	bool		initValueIsNull;
  
  	/*
  	 * We need the len and byval info for the agg's input and transition data
  	 * types in order to know how to copy/delete values.
  	 *
  	 * Note that the info for the input type is used only when handling
  	 * DISTINCT aggs with just one argument, so there is only one input type.
  	 */
  	int16		inputtypeLen,
  				transtypeLen;
  	bool		inputtypeByVal,
  				transtypeByVal;
  
  	/*
  	 * Stuff for evaluation of inputs.  We used to just use ExecEvalExpr, but
  	 * with the addition of ORDER BY we now need at least a slot for passing
  	 * data to the sort object, which requires a tupledesc, so we might as
  	 * well go whole hog and use ExecProject too.
  	 */
  	TupleDesc	evaldesc;		/* descriptor of input tuples */
  	ProjectionInfo *evalproj;	/* projection machinery */
  
  	/*
  	 * Slots for holding the evaluated input arguments.  These are set up
  	 * during ExecInitAgg() and then used for each input row.
  	 */
  	TupleTableSlot *evalslot;	/* current input tuple */
  	TupleTableSlot *uniqslot;	/* used for multi-column DISTINCT */
  
  	/*
  	 * These values are working state that is initialized at the start of an
  	 * input tuple group and updated for each input tuple.
  	 *
  	 * For a simple (non DISTINCT/ORDER BY) aggregate, we just feed the input
  	 * values straight to the transition function.  If it's DISTINCT or
  	 * requires ORDER BY, we pass the input values into a Tuplesort object;
  	 * then at completion of the input tuple group, we scan the sorted values,
  	 * eliminate duplicates if needed, and run the transition function on the
  	 * rest.
  	 *
  	 * We need a separate tuplesort for each grouping set.
  	 */
  
  	Tuplesortstate **sortstates;	/* sort objects, if DISTINCT or ORDER BY */
  
  	/*
  	 * This field is a pre-initialized FunctionCallInfo struct used for
  	 * calling this aggregate's transfn.  We save a few cycles per row by not
  	 * re-initializing the unchanging fields; which isn't much, but it seems
  	 * worth the extra space consumption.
  	 */
  	FunctionCallInfoData transfn_fcinfo;
  
  	/* Likewise for serialization and deserialization functions */
  	FunctionCallInfoData serialfn_fcinfo;
  
  	FunctionCallInfoData deserialfn_fcinfo;
  
  	/* in GPDB, we need to call both trans and combine functions if the hash
  	 * table spills, so we need this separately from transfn_fcinfo. Like
  	 * in upstream, if this is the final stage of an aggregate, transfn
  	 * actually points to the combine function, but this one points to the
  	 * combine function in all cases.
  	 */
  	FunctionCallInfoData combinefn_fcinfo;
  
  }	AggStatePerTransData;
  
  /*
   * AggStatePerAggData - per-aggregate information
   *
   * This contains the information needed to call the final function, to produce
   * a final aggregate result from the state value. If there are multiple
   * identical Aggrefs in the query, they can all share the same per-agg data.
   *
   * These values are set up during ExecInitAgg() and do not change thereafter.
   */
  typedef struct AggStatePerAggData
  {
  	/*
  	 * Link to an Aggref expr this state value is for.
  	 *
  	 * There can be multiple identical Aggref's sharing the same per-agg. This
  	 * points to the first one of them.
  	 */
  	Aggref	   *aggref;
  
  	/* index to the state value which this agg should use */
  	int			transno;
  
  	/* Optional Oid of final function (may be InvalidOid) */
  	Oid			finalfn_oid;
  
  	/*
  	 * fmgr lookup data for final function --- only valid when finalfn_oid oid
  	 * is not InvalidOid.
  	 */
  	FmgrInfo	finalfn;
  
  	/*
  	 * Number of arguments to pass to the finalfn.  This is always at least 1
  	 * (the transition state value) plus any ordered-set direct args. If the
  	 * finalfn wants extra args then we pass nulls corresponding to the
  	 * aggregated input columns.
  	 */
  	int			numFinalArgs;
  
  	/*
  	 * We need the len and byval info for the agg's result data type in order
  	 * to know how to copy/delete values.
  	 */
  	int16		resulttypeLen;
  	bool		resulttypeByVal;
  
  }	AggStatePerAggData;
  
  /*
   * AggStatePerGroupData - per-aggregate-per-group working state
   *
   * These values are working state that is initialized at the start of
   * an input tuple group and updated for each input tuple.
   *
   * In AGG_PLAIN and AGG_SORTED modes, we have a single array of these
   * structs (pointed to by aggstate->pergroup); we re-use the array for
   * each input group, if it's AGG_SORTED mode.  In AGG_HASHED mode, the
   * hash table contains an array of these structs for each tuple group.
   *
   * Logically, the sortstate field belongs in this struct, but we do not
   * keep it here for space reasons: we don't support DISTINCT aggregates
   * in AGG_HASHED mode, so there's no reason to use up a pointer field
   * in every entry of the hashtable.
   */
  typedef struct AggStatePerGroupData
  {
  	Datum		transValue;		/* current transition value */
  	bool		transValueIsNull;
  
  	bool		noTransValue;	/* true if transValue not set yet */
  
  	/*
  	 * Note: noTransValue initially has the same value as transValueIsNull,
  	 * and if true both are cleared to false at the same time.  They are not
  	 * the same though: if transfn later returns a NULL, we want to keep that
  	 * NULL and not auto-replace it with a later input value. Only the first
  	 * non-NULL input will be auto-substituted.
  	 */
  } AggStatePerGroupData;
  
  extern void initialize_aggregates(AggState *aggstate,
  					  AggStatePerGroup pergroup,
  					  int numReset);
  extern void advance_aggregates(AggState *aggstate, AggStatePerGroup pergroup);
  extern void combine_aggregates(AggState *aggstate, AggStatePerGroup pergroup);
  extern TupleTableSlot *fetch_input_tuple(AggState *aggstate);
  
  void fetch_input_tuples(AggState *aggstate,TupleTableSlots* resultSlots);
  
  extern Datum GetAggInitVal(Datum textInitVal, Oid transtype);
  
  extern void advance_combine_function(AggState *aggstate,
  						 AggStatePerTrans pertrans,
  						 AggStatePerGroup pergroupstate,
  						 FunctionCallInfo fcinfo);
  
  extern Datum datumCopyWithMemManager(Datum oldvalue, Datum value, bool typByVal, int typLen,
  									 MemoryManagerContainer *mem_manager);
  extern void ExecSquelchAgg(AggState *aggstate);
  
  #endif   /* NODEAGG_H */
  