blob: 5d4ac13d1d8a2dd1e20b36003cf40682a739a920 [file] [log] [blame]
/*-------------------------------------------------------------------------
*
* nodeAgg.h
* prototypes for nodeAgg.c
*
*
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/executor/nodeAgg.h,v 1.27 2006/07/13 16:49:19 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef NODEAGG_H
#define NODEAGG_H
#include "fmgr.h"
#include "executor/tuptable.h"
#include "nodes/execnodes.h"
#include "nodes/primnodes.h"
extern int ExecCountSlotsAgg(Agg *node);
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, ExprContext *exprCtxt);
extern Size hash_agg_entry_size(int numAggs);
extern Datum aggregate_dummy(PG_FUNCTION_ARGS);
/* MPP needs to see these in execHHashAgg.c */
/*
* AggStatePerAggData - per-aggregate working state for the Agg scan
*/
typedef struct AggStatePerAggData
{
/*
* These values are set up during ExecInitAgg() and do not change
* thereafter:
*/
/* Links to Aggref expr and state nodes this working state is for */
AggrefExprState *aggrefstate;
Aggref *aggref;
/* Links to PercentileExpr expr and state nodes this working state is for */
PercentileExprState *percstate;
PercentileExpr *perc;
/*
* number of input arguments for aggregate. It's usually length of
* the argument list supplied in SQL, but in case of PercentileExpr,
* it includes sort list, pcExpr and tcExpr.
*/
int numArguments;
/* number of inputs including ORDER BY expressions */
int numInputs;
/* Oids of transfer functions */
Oid transfn_oid;
Oid prelimfn_oid;
Oid finalfn_oid; /* may be InvalidOid */
/*
* fmgr lookup data for transfer functions --- only valid when
* corresponding oid is not InvalidOid. Note in particular that fn_strict
* flags are kept here.
*/
FmgrInfo transfn;
FmgrInfo prelimfn;
FmgrInfo finalfn;
/* --- Ordered Aggregate Additions ( --- */
/* number of sorting columns */
int numSortCols;
/* deconstructed sorting information (arrays of length numSortCols) */
AttrNumber *sortColIdx;
Oid *sortOperators;
/* --- Ordered Aggregate Additions ) --- */
/*
* fmgr lookup data for input type's equality operator --- only set/used
* when aggregate has DISTINCT flag. (In PG 9, equalfns is a vector.)
*/
FmgrInfo equalfn;
/*
* initial value from pg_aggregate entry
*/
Datum initValue;
bool initValueIsNull;
/*
* We need the len and byval info for the agg's input, result, and
* transition data types in order to know how to copy/delete values.
*/
int16 inputtypeLen,
resulttypeLen,
transtypeLen;
bool inputtypeByVal,
resulttypeByVal,
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 */
/*
* Slot for holding the evaluated input arguments. This is set up
* during ExecInitAgg() and then used for each input row.
*/
TupleTableSlot *evalslot; /* current input tuple */
/*
* 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) aggregate, we just feed the input values
* straight to the transition function. If it's DISTINCT, we pass the
* input values into a Tuplesort object; then at completion of the input
* tuple group, we scan the sorted values, eliminate duplicates, and run
* the transition function on the rest.
*/
void *sortstate; /* sort object, if DISTINCT or ORDER BY */
} 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,
AggStatePerAgg peragg,
AggStatePerGroup pergroup,
MemoryManagerContainer *mem_manager);
extern void
advance_aggregates(AggState *aggstate, AggStatePerGroup pergroup,
MemoryManagerContainer *mem_manager);
extern List *
get_agg_hash_collist(AggState *aggstate);
extern Oid resolve_polymorphic_transtype(Oid aggtranstype, Oid aggfnoid,
Oid *inputTypes);
extern Datum GetAggInitVal(Datum textInitVal, Oid transtype);
extern Datum invoke_agg_trans_func(FmgrInfo *transfn, int numargs,
Datum transValue, bool *noTransvalue,
bool *transValueIsNull, bool transtypeByVal,
int16 transtypeLen,
FunctionCallInfoData *fcinfo, void *funcctx,
MemoryContext tuplecontext,
MemoryManagerContainer *mem_manager);
extern Datum datumCopyWithMemManager(Datum oldvalue, Datum value, bool typByVal, int typLen,
MemoryManagerContainer *mem_manager);
extern void ExecEagerFreeAgg(AggState *aggstate);
enum {
GPMON_AGG_SPILLTUPLE = GPMON_QEXEC_M_NODE_START,
GPMON_AGG_SPILLBYTE,
GPMON_AGG_SPILLBATCH,
GPMON_AGG_SPILLPASS,
GPMON_AGG_CURRSPILLPASS_READTUPLE,
GPMON_AGG_CURRSPILLPASS_READBYTE,
GPMON_AGG_CURRSPILLPASS_TUPLE,
GPMON_AGG_CURRSPILLPASS_BYTE,
GPMON_AGG_CURRSPILLPASS_BATCH,
GPMON_AGG_TOTAL
};
static inline gpmon_packet_t * GpmonPktFromAggState(AggState *node)
{
return &node->ss.ps.gpmon_pkt;
}
extern List *combineAggrefArgs(Aggref *aggref, List **sort_clauses);
extern List *combinePercentileArgs(PercentileExpr *p);
extern void finalize_aggregates(AggState *aggstate, AggStatePerGroup pergroup);
extern TupleTableSlot *agg_retrieve_hash_table(AggState *aggstate);
extern void advance_transition_function(AggState *aggstate,
AggStatePerAgg peraggstate,
AggStatePerGroup pergroupstate,
FunctionCallInfoData *fcinfo,
MemoryManagerContainer *mem_manager);
#endif /* NODEAGG_H */