diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c index fcc3859..984216d 100644 --- a/src/backend/executor/nodeAgg.c +++ b/src/backend/executor/nodeAgg.c @@ -152,15 +152,15 @@ /* - * AggStatePerAggStateData - per aggregate state data for the Agg scan + * AggStateTransStateData - per aggregate state data for the Agg scan * - * Working state for calculating the aggregate state, using the state - * transition function. This struct does not store the information needed - * to produce the final aggregate result from the state value; that's stored + * Working state for calculating the aggregate's transition state, using the + * state transition function. 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 AggStatePerAggStateData +typedef struct AggStateTransStateData { /* * These values are set up during ExecInitAgg() and do not change @@ -209,7 +209,7 @@ typedef struct AggStatePerAggStateData List *aggdirectargs; /* states of direct-argument expressions */ /* - * fmgr lookup data for transfer function. Note in particular that the + * fmgr lookup data for transition function. Note in particular that the * fn_strict flag is kept here. */ FmgrInfo transfn; @@ -294,7 +294,7 @@ typedef struct AggStatePerAggStateData * worth the extra space consumption. */ FunctionCallInfoData transfn_fcinfo; -} AggStatePerAggStateData; +} AggStateTransStateData; /* * AggStatePerAggData - per-aggregate working state @@ -421,18 +421,17 @@ typedef enum AggRefCompatibility static void initialize_phase(AggState *aggstate, int newphase); static TupleTableSlot *fetch_input_tuple(AggState *aggstate); static void initialize_aggregates(AggState *aggstate, - AggStatePerAggState peraggstates, AggStatePerGroup pergroup, int numReset); static void advance_transition_function(AggState *aggstate, - AggStatePerAggState peraggstate, + AggStateTransState transstate, AggStatePerGroup pergroupstate); static void advance_aggregates(AggState *aggstate, AggStatePerGroup pergroup); static void process_ordered_aggregate_single(AggState *aggstate, - AggStatePerAggState peraggstate, + AggStateTransState transstate, AggStatePerGroup pergroupstate); static void process_ordered_aggregate_multi(AggState *aggstate, - AggStatePerAggState peraggstate, + AggStateTransState transstate, AggStatePerGroup pergroupstate); static void finalize_aggregate(AggState *aggstate, AggStatePerAgg peragg, @@ -455,14 +454,14 @@ static TupleTableSlot *agg_retrieve_direct(AggState *aggstate); static void agg_fill_hash_table(AggState *aggstate); static TupleTableSlot *agg_retrieve_hash_table(AggState *aggstate); static Datum GetAggInitVal(Datum textInitVal, Oid transtype); -static void build_peraggstate_for_aggref(AggStatePerAggState peraggstate, +static void build_transstate_for_aggref(AggStateTransState transstate, AggState *aggsate, EState *estate, Aggref *aggref, HeapTuple aggtuple, Oid *inputTypes, int numArguments); static AggRefCompatibility find_compatible_aggref(Aggref *newagg, AggState *aggstate, int lastaggno, int *foundaggno); static AggRefCompatibility aggref_has_compatible_states(Aggref *newagg, - AggStatePerAgg peragg, AggStatePerAggState peraggstate); + AggStatePerAgg peragg, AggStateTransState transstate); /* @@ -565,20 +564,20 @@ fetch_input_tuple(AggState *aggstate) * When called, CurrentMemoryContext should be the per-query context. */ static void -initialize_aggregate(AggState *aggstate, AggStatePerAggState peraggstate, +initialize_aggregate(AggState *aggstate, AggStateTransState transstate, AggStatePerGroup pergroupstate) { /* * Start a fresh sort operation for each DISTINCT/ORDER BY aggregate. */ - if (peraggstate->numSortCols > 0) + if (transstate->numSortCols > 0) { /* * In case of rescan, maybe there could be an uncompleted sort * operation? Clean it up if so. */ - if (peraggstate->sortstates[aggstate->current_set]) - tuplesort_end(peraggstate->sortstates[aggstate->current_set]); + if (transstate->sortstates[aggstate->current_set]) + tuplesort_end(transstate->sortstates[aggstate->current_set]); /* @@ -586,21 +585,21 @@ initialize_aggregate(AggState *aggstate, AggStatePerAggState peraggstate, * otherwise sort the full tuple. (See comments for * process_ordered_aggregate_single.) */ - if (peraggstate->numInputs == 1) - peraggstate->sortstates[aggstate->current_set] = - tuplesort_begin_datum(peraggstate->evaldesc->attrs[0]->atttypid, - peraggstate->sortOperators[0], - peraggstate->sortCollations[0], - peraggstate->sortNullsFirst[0], + if (transstate->numInputs == 1) + transstate->sortstates[aggstate->current_set] = + tuplesort_begin_datum(transstate->evaldesc->attrs[0]->atttypid, + transstate->sortOperators[0], + transstate->sortCollations[0], + transstate->sortNullsFirst[0], work_mem, false); else - peraggstate->sortstates[aggstate->current_set] = - tuplesort_begin_heap(peraggstate->evaldesc, - peraggstate->numSortCols, - peraggstate->sortColIdx, - peraggstate->sortOperators, - peraggstate->sortCollations, - peraggstate->sortNullsFirst, + transstate->sortstates[aggstate->current_set] = + tuplesort_begin_heap(transstate->evaldesc, + transstate->numSortCols, + transstate->sortColIdx, + transstate->sortOperators, + transstate->sortCollations, + transstate->sortNullsFirst, work_mem, false); } @@ -610,20 +609,20 @@ initialize_aggregate(AggState *aggstate, AggStatePerAggState peraggstate, * Note that when the initial value is pass-by-ref, we must copy it (into * the aggcontext) since we will pfree the transValue later. */ - if (peraggstate->initValueIsNull) - pergroupstate->transValue = peraggstate->initValue; + if (transstate->initValueIsNull) + pergroupstate->transValue = transstate->initValue; else { MemoryContext oldContext; oldContext = MemoryContextSwitchTo( aggstate->aggcontexts[aggstate->current_set]->ecxt_per_tuple_memory); - pergroupstate->transValue = datumCopy(peraggstate->initValue, - peraggstate->transtypeByVal, - peraggstate->transtypeLen); + pergroupstate->transValue = datumCopy(transstate->initValue, + transstate->transtypeByVal, + transstate->transtypeLen); MemoryContextSwitchTo(oldContext); } - pergroupstate->transValueIsNull = peraggstate->initValueIsNull; + pergroupstate->transValueIsNull = transstate->initValueIsNull; /* * If the initial value for the transition state doesn't exist in the @@ -632,11 +631,11 @@ initialize_aggregate(AggState *aggstate, AggStatePerAggState peraggstate, * aggregates like max() and min().) The noTransValue flag signals that we * still need to do this. */ - pergroupstate->noTransValue = peraggstate->initValueIsNull; + pergroupstate->noTransValue = transstate->initValueIsNull; } /* - * Initialize all aggregate states for a new group of input values. + * Initialize all aggregate transition states for a new group of input values. * * If there are multiple grouping sets, we initialize only the first numReset * of them (the grouping sets are ordered so that the most specific one, which @@ -647,20 +646,20 @@ initialize_aggregate(AggState *aggstate, AggStatePerAggState peraggstate, */ static void initialize_aggregates(AggState *aggstate, - AggStatePerAggState peraggstates, AggStatePerGroup pergroup, int numReset) { - int stateno; - int numGroupingSets = Max(aggstate->phase->numsets, 1); - int setno = 0; + int stateno; + int numGroupingSets = Max(aggstate->phase->numsets, 1); + int setno = 0; + AggStateTransState transstates = aggstate->transstates; if (numReset < 1) numReset = numGroupingSets; for (stateno = 0; stateno < aggstate->numstates; stateno++) { - AggStatePerAggState peraggstate = &peraggstates[stateno]; + AggStateTransState transstate = &transstates[stateno]; for (setno = 0; setno < numReset; setno++) { @@ -670,7 +669,7 @@ initialize_aggregates(AggState *aggstate, aggstate->current_set = setno; - initialize_aggregate(aggstate, peraggstate, pergroupstate); + initialize_aggregate(aggstate, transstate, pergroupstate); } } } @@ -680,7 +679,7 @@ initialize_aggregates(AggState *aggstate, * state within one grouping set only (already set in aggstate->current_set) * * The new values (and null flags) have been preloaded into argument positions - * 1 and up in peraggstate->transfn_fcinfo, so that we needn't copy them again + * 1 and up in transstate->transfn_fcinfo, so that we needn't copy them again * to pass to the transition function. We also expect that the static fields * of the fcinfo are already initialized; that was done by ExecInitAgg(). * @@ -688,20 +687,20 @@ initialize_aggregates(AggState *aggstate, */ static void advance_transition_function(AggState *aggstate, - AggStatePerAggState peraggstate, + AggStateTransState transstate, AggStatePerGroup pergroupstate) { - FunctionCallInfo fcinfo = &peraggstate->transfn_fcinfo; + FunctionCallInfo fcinfo = &transstate->transfn_fcinfo; MemoryContext oldContext; Datum newVal; - if (peraggstate->transfn.fn_strict) + if (transstate->transfn.fn_strict) { /* * For a strict transfn, nothing happens when there's a NULL input; we * just keep the prior transValue. */ - int numTransInputs = peraggstate->numTransInputs; + int numTransInputs = transstate->numTransInputs; int i; for (i = 1; i <= numTransInputs; i++) @@ -723,8 +722,8 @@ advance_transition_function(AggState *aggstate, oldContext = MemoryContextSwitchTo( aggstate->aggcontexts[aggstate->current_set]->ecxt_per_tuple_memory); pergroupstate->transValue = datumCopy(fcinfo->arg[1], - peraggstate->transtypeByVal, - peraggstate->transtypeLen); + transstate->transtypeByVal, + transstate->transtypeLen); pergroupstate->transValueIsNull = false; pergroupstate->noTransValue = false; MemoryContextSwitchTo(oldContext); @@ -745,8 +744,8 @@ advance_transition_function(AggState *aggstate, /* We run the transition functions in per-input-tuple memory context */ oldContext = MemoryContextSwitchTo(aggstate->tmpcontext->ecxt_per_tuple_memory); - /* set up aggstate->curperaggstate for AggGetAggref() */ - aggstate->curperaggstate = peraggstate; + /* set up aggstate->curtransstate for AggGetAggref() */ + aggstate->curtransstate = transstate; /* * OK to call the transition function @@ -757,22 +756,22 @@ advance_transition_function(AggState *aggstate, newVal = FunctionCallInvoke(fcinfo); - aggstate->curperaggstate = NULL; + aggstate->curtransstate = NULL; /* * If pass-by-ref datatype, must copy the new value into aggcontext and * pfree the prior transValue. But if transfn returned a pointer to its * first input, we don't need to do anything. */ - if (!peraggstate->transtypeByVal && + if (!transstate->transtypeByVal && DatumGetPointer(newVal) != DatumGetPointer(pergroupstate->transValue)) { if (!fcinfo->isnull) { MemoryContextSwitchTo(aggstate->aggcontexts[aggstate->current_set]->ecxt_per_tuple_memory); newVal = datumCopy(newVal, - peraggstate->transtypeByVal, - peraggstate->transtypeLen); + transstate->transtypeByVal, + transstate->transtypeLen); } if (!pergroupstate->transValueIsNull) pfree(DatumGetPointer(pergroupstate->transValue)); @@ -785,10 +784,10 @@ advance_transition_function(AggState *aggstate, } /* - * Advance each aggregate state for one input tuple. The input tuple - * has been stored in tmpcontext->ecxt_outertuple, so that it is accessible - * to ExecEvalExpr. pergroup is the array of per-group structs to use - * (this might be in a hashtable entry). + * Advance each aggregate transition state for one input tuple. The input + * tuple has been stored in tmpcontext->ecxt_outertuple, so that it is + * accessible to ExecEvalExpr. pergroup is the array of per-group structs to + * use (this might be in a hashtable entry). * * When called, CurrentMemoryContext should be the per-query context. */ @@ -802,9 +801,9 @@ advance_aggregates(AggState *aggstate, AggStatePerGroup pergroup) for (stateno = 0; stateno < numStates; stateno++) { - AggStatePerAggState peraggstate = &aggstate->peraggstate[stateno]; - ExprState *filter = peraggstate->aggfilter; - int numTransInputs = peraggstate->numTransInputs; + AggStateTransState transstate = &aggstate->transstates[stateno]; + ExprState *filter = transstate->aggfilter; + int numTransInputs = transstate->numTransInputs; int i; TupleTableSlot *slot; @@ -821,12 +820,12 @@ advance_aggregates(AggState *aggstate, AggStatePerGroup pergroup) } /* Evaluate the current input expressions for this aggregate */ - slot = ExecProject(peraggstate->evalproj, NULL); + slot = ExecProject(transstate->evalproj, NULL); - if (peraggstate->numSortCols > 0) + if (transstate->numSortCols > 0) { /* DISTINCT and/or ORDER BY case */ - Assert(slot->tts_nvalid == peraggstate->numInputs); + Assert(slot->tts_nvalid == transstate->numInputs); /* * If the transfn is strict, we want to check for nullity before @@ -835,7 +834,7 @@ advance_aggregates(AggState *aggstate, AggStatePerGroup pergroup) * not numInputs, since nullity in columns used only for sorting * is not relevant here. */ - if (peraggstate->transfn.fn_strict) + if (transstate->transfn.fn_strict) { for (i = 0; i < numTransInputs; i++) { @@ -849,18 +848,18 @@ advance_aggregates(AggState *aggstate, AggStatePerGroup pergroup) for (setno = 0; setno < numGroupingSets; setno++) { /* OK, put the tuple into the tuplesort object */ - if (peraggstate->numInputs == 1) - tuplesort_putdatum(peraggstate->sortstates[setno], + if (transstate->numInputs == 1) + tuplesort_putdatum(transstate->sortstates[setno], slot->tts_values[0], slot->tts_isnull[0]); else - tuplesort_puttupleslot(peraggstate->sortstates[setno], slot); + tuplesort_puttupleslot(transstate->sortstates[setno], slot); } } else { /* We can apply the transition function immediately */ - FunctionCallInfo fcinfo = &peraggstate->transfn_fcinfo; + FunctionCallInfo fcinfo = &transstate->transfn_fcinfo; /* Load values into fcinfo */ /* Start from 1, since the 0th arg will be the transition value */ @@ -877,7 +876,8 @@ advance_aggregates(AggState *aggstate, AggStatePerGroup pergroup) aggstate->current_set = setno; - advance_transition_function(aggstate, peraggstate, pergroupstate); + advance_transition_function(aggstate, transstate, + pergroupstate); } } } @@ -908,7 +908,7 @@ advance_aggregates(AggState *aggstate, AggStatePerGroup pergroup) */ static void process_ordered_aggregate_single(AggState *aggstate, - AggStatePerAggState peraggstate, + AggStateTransState transstate, AggStatePerGroup pergroupstate) { Datum oldVal = (Datum) 0; @@ -916,14 +916,14 @@ process_ordered_aggregate_single(AggState *aggstate, bool haveOldVal = false; MemoryContext workcontext = aggstate->tmpcontext->ecxt_per_tuple_memory; MemoryContext oldContext; - bool isDistinct = (peraggstate->numDistinctCols > 0); - FunctionCallInfo fcinfo = &peraggstate->transfn_fcinfo; + bool isDistinct = (transstate->numDistinctCols > 0); + FunctionCallInfo fcinfo = &transstate->transfn_fcinfo; Datum *newVal; bool *isNull; - Assert(peraggstate->numDistinctCols < 2); + Assert(transstate->numDistinctCols < 2); - tuplesort_performsort(peraggstate->sortstates[aggstate->current_set]); + tuplesort_performsort(transstate->sortstates[aggstate->current_set]); /* Load the column into argument 1 (arg 0 will be transition value) */ newVal = fcinfo->arg + 1; @@ -935,7 +935,7 @@ process_ordered_aggregate_single(AggState *aggstate, * pfree them when they are no longer needed. */ - while (tuplesort_getdatum(peraggstate->sortstates[aggstate->current_set], + while (tuplesort_getdatum(transstate->sortstates[aggstate->current_set], true, newVal, isNull)) { /* @@ -954,18 +954,18 @@ process_ordered_aggregate_single(AggState *aggstate, haveOldVal && ((oldIsNull && *isNull) || (!oldIsNull && !*isNull && - DatumGetBool(FunctionCall2(&peraggstate->equalfns[0], + DatumGetBool(FunctionCall2(&transstate->equalfns[0], oldVal, *newVal))))) { /* equal to prior, so forget this one */ - if (!peraggstate->inputtypeByVal && !*isNull) + if (!transstate->inputtypeByVal && !*isNull) pfree(DatumGetPointer(*newVal)); } else { - advance_transition_function(aggstate, peraggstate, pergroupstate); + advance_transition_function(aggstate, transstate, pergroupstate); /* forget the old value, if any */ - if (!oldIsNull && !peraggstate->inputtypeByVal) + if (!oldIsNull && !transstate->inputtypeByVal) pfree(DatumGetPointer(oldVal)); /* and remember the new one for subsequent equality checks */ oldVal = *newVal; @@ -976,11 +976,11 @@ process_ordered_aggregate_single(AggState *aggstate, MemoryContextSwitchTo(oldContext); } - if (!oldIsNull && !peraggstate->inputtypeByVal) + if (!oldIsNull && !transstate->inputtypeByVal) pfree(DatumGetPointer(oldVal)); - tuplesort_end(peraggstate->sortstates[aggstate->current_set]); - peraggstate->sortstates[aggstate->current_set] = NULL; + tuplesort_end(transstate->sortstates[aggstate->current_set]); + transstate->sortstates[aggstate->current_set] = NULL; } /* @@ -997,25 +997,25 @@ process_ordered_aggregate_single(AggState *aggstate, */ static void process_ordered_aggregate_multi(AggState *aggstate, - AggStatePerAggState peraggstate, + AggStateTransState transstate, AggStatePerGroup pergroupstate) { MemoryContext workcontext = aggstate->tmpcontext->ecxt_per_tuple_memory; - FunctionCallInfo fcinfo = &peraggstate->transfn_fcinfo; - TupleTableSlot *slot1 = peraggstate->evalslot; - TupleTableSlot *slot2 = peraggstate->uniqslot; - int numTransInputs = peraggstate->numTransInputs; - int numDistinctCols = peraggstate->numDistinctCols; + FunctionCallInfo fcinfo = &transstate->transfn_fcinfo; + TupleTableSlot *slot1 = transstate->evalslot; + TupleTableSlot *slot2 = transstate->uniqslot; + int numTransInputs = transstate->numTransInputs; + int numDistinctCols = transstate->numDistinctCols; bool haveOldValue = false; int i; - tuplesort_performsort(peraggstate->sortstates[aggstate->current_set]); + tuplesort_performsort(transstate->sortstates[aggstate->current_set]); ExecClearTuple(slot1); if (slot2) ExecClearTuple(slot2); - while (tuplesort_gettupleslot(peraggstate->sortstates[aggstate->current_set], + while (tuplesort_gettupleslot(transstate->sortstates[aggstate->current_set], true, slot1)) { /* @@ -1029,8 +1029,8 @@ process_ordered_aggregate_multi(AggState *aggstate, !haveOldValue || !execTuplesMatch(slot1, slot2, numDistinctCols, - peraggstate->sortColIdx, - peraggstate->equalfns, + transstate->sortColIdx, + transstate->equalfns, workcontext)) { /* Load values into fcinfo */ @@ -1041,7 +1041,7 @@ process_ordered_aggregate_multi(AggState *aggstate, fcinfo->argnull[i + 1] = slot1->tts_isnull[i]; } - advance_transition_function(aggstate, peraggstate, pergroupstate); + advance_transition_function(aggstate, transstate, pergroupstate); if (numDistinctCols > 0) { @@ -1064,8 +1064,8 @@ process_ordered_aggregate_multi(AggState *aggstate, if (slot2) ExecClearTuple(slot2); - tuplesort_end(peraggstate->sortstates[aggstate->current_set]); - peraggstate->sortstates[aggstate->current_set] = NULL; + tuplesort_end(transstate->sortstates[aggstate->current_set]); + transstate->sortstates[aggstate->current_set] = NULL; } /* @@ -1092,7 +1092,7 @@ finalize_aggregate(AggState *aggstate, MemoryContext oldContext; int i; ListCell *lc; - AggStatePerAggState peraggstate = &aggstate->peraggstate[peragg->stateno]; + AggStateTransState transstate = &aggstate->transstates[peragg->stateno]; oldContext = MemoryContextSwitchTo(aggstate->ss.ps.ps_ExprContext->ecxt_per_tuple_memory); @@ -1103,7 +1103,7 @@ finalize_aggregate(AggState *aggstate, * for the transition state value. */ i = 1; - foreach(lc, peraggstate->aggdirectargs) + foreach(lc, transstate->aggdirectargs) { ExprState *expr = (ExprState *) lfirst(lc); @@ -1122,12 +1122,12 @@ finalize_aggregate(AggState *aggstate, { int numFinalArgs = peragg->numFinalArgs; - /* set up aggstate->curperaggstate for AggGetAggref() */ - aggstate->curperaggstate = peraggstate; + /* set up aggstate->curtransstate for AggGetAggref() */ + aggstate->curtransstate = transstate; InitFunctionCallInfoData(fcinfo, &peragg->finalfn, numFinalArgs, - peraggstate->aggCollation, + transstate->aggCollation, (void *) aggstate, NULL); /* Fill in the transition state value */ @@ -1154,7 +1154,7 @@ finalize_aggregate(AggState *aggstate, *resultVal = FunctionCallInvoke(&fcinfo); *resultIsNull = fcinfo.isnull; } - aggstate->curperaggstate = NULL; + aggstate->curtransstate = NULL; } else { @@ -1263,22 +1263,22 @@ finalize_aggregates(AggState *aggstate, { AggStatePerAgg peragg = &peraggs[aggno]; int stateno = peragg->stateno; - AggStatePerAggState peraggstate = &aggstate->peraggstate[stateno]; + AggStateTransState transstate = &aggstate->transstates[stateno]; AggStatePerGroup pergroupstate; pergroupstate = &pergroup[stateno + (currentSet * (aggstate->numstates))]; - if (peraggstate->numSortCols > 0) + if (transstate->numSortCols > 0) { Assert(((Agg *) aggstate->ss.ps.plan)->aggstrategy != AGG_HASHED); - if (peraggstate->numInputs == 1) + if (transstate->numInputs == 1) process_ordered_aggregate_single(aggstate, - peraggstate, + transstate, pergroupstate); else process_ordered_aggregate_multi(aggstate, - peraggstate, + transstate, pergroupstate); } @@ -1502,7 +1502,7 @@ lookup_hash_entry(AggState *aggstate, TupleTableSlot *inputslot) if (isnew) { /* initialize aggregates for new tuple group */ - initialize_aggregates(aggstate, aggstate->peraggstate, entry->pergroup, 0); + initialize_aggregates(aggstate, entry->pergroup, 0); } return entry; @@ -1579,7 +1579,6 @@ agg_retrieve_direct(AggState *aggstate) ExprContext *econtext; ExprContext *tmpcontext; AggStatePerAgg peragg; - AggStatePerAggState peraggstate; AggStatePerGroup pergroup; TupleTableSlot *outerslot; TupleTableSlot *firstSlot; @@ -1602,7 +1601,6 @@ agg_retrieve_direct(AggState *aggstate) tmpcontext = aggstate->tmpcontext; peragg = aggstate->peragg; - peraggstate = aggstate->peraggstate; pergroup = aggstate->pergroup; firstSlot = aggstate->ss.ss_ScanTupleSlot; @@ -1792,7 +1790,7 @@ agg_retrieve_direct(AggState *aggstate) /* * Initialize working state for a new input tuple group. */ - initialize_aggregates(aggstate, peraggstate, pergroup, numReset); + initialize_aggregates(aggstate, pergroup, numReset); if (aggstate->grp_firstTuple != NULL) { @@ -2022,7 +2020,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) { AggState *aggstate; AggStatePerAgg peraggs; - AggStatePerAggState peraggstates; + AggStateTransState transstates; Plan *outerPlan; ExprContext *econtext; int numaggs, @@ -2054,8 +2052,8 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) aggstate->projected_set = -1; aggstate->current_set = 0; aggstate->peragg = NULL; - aggstate->peraggstate = NULL; - aggstate->curperaggstate = NULL; + aggstate->transstates = NULL; + aggstate->curtransstate = NULL; aggstate->agg_done = false; aggstate->input_done = false; aggstate->pergroup = NULL; @@ -2289,10 +2287,10 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) econtext->ecxt_aggnulls = (bool *) palloc0(sizeof(bool) * numaggs); peraggs = (AggStatePerAgg) palloc0(sizeof(AggStatePerAggData) * numaggs); - peraggstates = (AggStatePerAggState) palloc0(sizeof(AggStatePerAggStateData) * numaggs); + transstates = (AggStateTransState) palloc0(sizeof(AggStateTransStateData)* numaggs); aggstate->peragg = peraggs; - aggstate->peraggstate = peraggstates; + aggstate->transstates = transstates; if (node->aggstrategy == AGG_HASHED) { @@ -2323,7 +2321,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) AggrefExprState *aggrefstate = (AggrefExprState *) lfirst(l); Aggref *aggref = (Aggref *) aggrefstate->xprstate.expr; AggStatePerAgg peragg; - AggStatePerAggState peraggstate; + AggStateTransState transstate; AggRefCompatibility agg_match; Oid inputTypes[FUNC_MAX_ARGS]; int numArguments; @@ -2347,10 +2345,10 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) * giving them duplicate aggno values. We also do our best to reuse * duplicate aggregate states. The query may use 2 or more aggregate * functions which share the same transition function and initial - * value therefore would end up calculating the same state. In this - * case we can just calculate the state once, however if the finalfns - * do not match then we must create a new peragg to store the varying - * finalfn. + * value therefore would end up building an identical transition state. + * In this case we can just calculate the state once, however if the + * finalfns do not match then we must create a new peragg to store the + * varying finalfn. */ /* check if we have previous agg or state matches that can be reused */ @@ -2408,8 +2406,8 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) ReleaseSysCache(procTuple); /* - * If we're reusing an existing state, no need to check the - * transfn permission again. + * We only need to check permissions on the transfn if we're not + * reusing the transition state. */ if (agg_match == AGGREF_NO_MATCH) { @@ -2448,21 +2446,21 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) */ if (agg_match == AGGREF_NO_MATCH) { - peraggstate = &peraggstates[++stateno]; - build_peraggstate_for_aggref(peraggstate, aggstate, estate, + transstate = &transstates[++stateno]; + build_transstate_for_aggref(transstate, aggstate, estate, aggref, aggTuple, inputTypes, numArguments); peragg->stateno = stateno; } - else + else /* AGGREF_STATE_MATCH */ { int existing_stateno = peraggs[existing_aggno].stateno; - peraggstate = &peraggstates[existing_stateno]; + transstate = &transstates[existing_stateno]; peragg->stateno = existing_stateno; - /* when reusing the state the transfns should match! */ - Assert(peraggstate->transfn_oid == aggform->aggtransfn); + /* when reusing the state, the transfns should match! */ + Assert(transstate->transfn_oid == aggform->aggtransfn); } /* Detect how many arguments to pass to the finalfn */ @@ -2479,7 +2477,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) { build_aggregate_finalfn_expr(inputTypes, peragg->numFinalArgs, - peraggstate->aggtranstype, + transstate->aggtranstype, aggref->aggtype, aggref->inputcollid, finalfn_oid, @@ -2509,12 +2507,12 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) /* * Build the state needed to calculate a state value for an aggregate. * - * This initializes all the fields in 'peraggstate'. 'aggTuple', + * This initializes all the fields in 'transstate'. 'aggTuple', * 'inputTypes' and 'numArguments' could be derived from 'aggref', but the * caller has calculated them already, so might as well pass them. */ static void -build_peraggstate_for_aggref(AggStatePerAggState peraggstate, +build_transstate_for_aggref(AggStateTransState transstate, AggState *aggstate, EState *estate, Aggref *aggref, HeapTuple aggTuple, Oid *inputTypes, int numArguments) @@ -2528,25 +2526,24 @@ build_peraggstate_for_aggref(AggStatePerAggState peraggstate, List *sortlist; int numSortCols; int numDistinctCols; - int currentsortno; int naggs; int i; Datum textInitVal; Oid transfn_oid; - /* Begin filling in the peraggstate data */ - peraggstate->aggref = aggref; - peraggstate->aggCollation = aggref->inputcollid; - peraggstate->transfn_oid = transfn_oid = aggform->aggtransfn; + /* Begin filling in the transstate data */ + transstate->aggref = aggref; + transstate->aggCollation = aggref->inputcollid; + transstate->transfn_oid = transfn_oid = aggform->aggtransfn; /* Count the "direct" arguments, if any */ numDirectArgs = list_length(aggref->aggdirectargs); /* Count the number of aggregated input columns */ - peraggstate->numInputs = numInputs = list_length(aggref->args); + transstate->numInputs = numInputs = list_length(aggref->args); /* resolve actual type of transition state, if polymorphic */ - peraggstate->aggtranstype = + transstate->aggtranstype = resolve_aggregate_transtype(aggref->aggfnoid, aggform->aggtranstype, inputTypes, @@ -2554,9 +2551,9 @@ build_peraggstate_for_aggref(AggStatePerAggState peraggstate, /* Detect how many arguments to pass to the transfn */ if (AGGKIND_IS_ORDERED_SET(aggref->aggkind)) - peraggstate->numTransInputs = numInputs; + transstate->numTransInputs = numInputs; else - peraggstate->numTransInputs = numArguments; + transstate->numTransInputs = numArguments; /* * Set up infrastructure for calling the transfn @@ -2565,19 +2562,19 @@ build_peraggstate_for_aggref(AggStatePerAggState peraggstate, numArguments, numDirectArgs, aggref->aggvariadic, - peraggstate->aggtranstype, + transstate->aggtranstype, aggref->inputcollid, transfn_oid, InvalidOid, /* invtrans is not needed here */ &transfnexpr, NULL); - fmgr_info(peraggstate->transfn_oid, &peraggstate->transfn); - fmgr_info_set_expr((Node *) transfnexpr, &peraggstate->transfn); + fmgr_info(transfn_oid, &transstate->transfn); + fmgr_info_set_expr((Node *) transfnexpr, &transstate->transfn); - InitFunctionCallInfoData(peraggstate->transfn_fcinfo, - &peraggstate->transfn, - peraggstate->numTransInputs + 1, - peraggstate->aggCollation, + InitFunctionCallInfoData(transstate->transfn_fcinfo, + &transstate->transfn, + transstate->numTransInputs + 1, + transstate->aggCollation, (void *) aggstate, NULL); @@ -2589,13 +2586,13 @@ build_peraggstate_for_aggref(AggStatePerAggState peraggstate, */ textInitVal = SysCacheGetAttr(AGGFNOID, aggTuple, Anum_pg_aggregate_agginitval, - &peraggstate->initValueIsNull); + &transstate->initValueIsNull); - if (peraggstate->initValueIsNull) - peraggstate->initValue = (Datum) 0; + if (transstate->initValueIsNull) + transstate->initValue = (Datum) 0; else - peraggstate->initValue = GetAggInitVal(textInitVal, - peraggstate->aggtranstype); + transstate->initValue = GetAggInitVal(textInitVal, + transstate->aggtranstype); /* * If the transfn is strict and the initval is NULL, make sure input type @@ -2605,39 +2602,40 @@ build_peraggstate_for_aggref(AggStatePerAggState peraggstate, * we must check again in case the transfn's strictness property has been * changed. */ - if (peraggstate->transfn.fn_strict && peraggstate->initValueIsNull) + if (transstate->transfn.fn_strict && transstate->initValueIsNull) { if (numArguments <= numDirectArgs || !IsBinaryCoercible(inputTypes[numDirectArgs], - peraggstate->aggtranstype)) + transstate->aggtranstype)) ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("aggregate needs to have compatible input type and transition type"))); + errmsg("aggregate %u needs to have compatible input type and transition type", + aggref->aggfnoid))); } /* get info about the state value's datatype */ - get_typlenbyval(peraggstate->aggtranstype, - &peraggstate->transtypeLen, - &peraggstate->transtypeByVal); + get_typlenbyval(transstate->aggtranstype, + &transstate->transtypeLen, + &transstate->transtypeByVal); /* * Get a tupledesc corresponding to the aggregated inputs (including sort * expressions) of the agg. */ - peraggstate->evaldesc = ExecTypeFromTL(aggref->args, false); + transstate->evaldesc = ExecTypeFromTL(aggref->args, false); /* Create slot we're going to do argument evaluation in */ - peraggstate->evalslot = ExecInitExtraTupleSlot(estate); - ExecSetSlotDescriptor(peraggstate->evalslot, peraggstate->evaldesc); + transstate->evalslot = ExecInitExtraTupleSlot(estate); + ExecSetSlotDescriptor(transstate->evalslot, transstate->evaldesc); /* Initialize the input and FILTER expressions */ naggs = aggstate->numaggs; - peraggstate->aggfilter = ExecInitExpr(aggref->aggfilter, - (PlanState *) aggstate); - peraggstate->aggdirectargs = (List *) ExecInitExpr((Expr *) aggref->aggdirectargs, - (PlanState *) aggstate); - peraggstate->args = (List *) ExecInitExpr((Expr *) aggref->args, - (PlanState *) aggstate); + transstate->aggfilter = ExecInitExpr(aggref->aggfilter, + (PlanState *) aggstate); + transstate->aggdirectargs = (List *) ExecInitExpr((Expr *)aggref->aggdirectargs, + (PlanState *) aggstate); + transstate->args = (List *)ExecInitExpr((Expr *)aggref->args, + (PlanState *) aggstate); /* * Complain if the aggregate's arguments contain any aggregates; nested @@ -2650,10 +2648,10 @@ build_peraggstate_for_aggref(AggStatePerAggState peraggstate, errmsg("aggregate function calls cannot be nested"))); /* Set up projection info for evaluation */ - peraggstate->evalproj = ExecBuildProjectionInfo(peraggstate->args, - aggstate->tmpcontext, - peraggstate->evalslot, - NULL); + transstate->evalproj = ExecBuildProjectionInfo(transstate->args, + aggstate->tmpcontext, + transstate->evalslot, + NULL); /* * If we're doing either DISTINCT or ORDER BY for a plain agg, then we @@ -2682,8 +2680,8 @@ build_peraggstate_for_aggref(AggStatePerAggState peraggstate, numDistinctCols = 0; } - peraggstate->numSortCols = numSortCols; - peraggstate->numDistinctCols = numDistinctCols; + transstate->numSortCols = numSortCols; + transstate->numDistinctCols = numDistinctCols; if (numSortCols > 0) { @@ -2697,25 +2695,25 @@ build_peraggstate_for_aggref(AggStatePerAggState peraggstate, if (numInputs == 1) { get_typlenbyval(inputTypes[numDirectArgs], - &peraggstate->inputtypeLen, - &peraggstate->inputtypeByVal); + &transstate->inputtypeLen, + &transstate->inputtypeByVal); } else if (numDistinctCols > 0) { /* we will need an extra slot to store prior values */ - peraggstate->uniqslot = ExecInitExtraTupleSlot(estate); - ExecSetSlotDescriptor(peraggstate->uniqslot, - peraggstate->evaldesc); + transstate->uniqslot = ExecInitExtraTupleSlot(estate); + ExecSetSlotDescriptor(transstate->uniqslot, + transstate->evaldesc); } /* Extract the sort information for use later */ - peraggstate->sortColIdx = + transstate->sortColIdx = (AttrNumber *) palloc(numSortCols * sizeof(AttrNumber)); - peraggstate->sortOperators = + transstate->sortOperators = (Oid *) palloc(numSortCols * sizeof(Oid)); - peraggstate->sortCollations = + transstate->sortCollations = (Oid *) palloc(numSortCols * sizeof(Oid)); - peraggstate->sortNullsFirst = + transstate->sortNullsFirst = (bool *) palloc(numSortCols * sizeof(bool)); i = 0; @@ -2727,10 +2725,10 @@ build_peraggstate_for_aggref(AggStatePerAggState peraggstate, /* the parser should have made sure of this */ Assert(OidIsValid(sortcl->sortop)); - peraggstate->sortColIdx[i] = tle->resno; - peraggstate->sortOperators[i] = sortcl->sortop; - peraggstate->sortCollations[i] = exprCollation((Node *) tle->expr); - peraggstate->sortNullsFirst[i] = sortcl->nulls_first; + transstate->sortColIdx[i] = tle->resno; + transstate->sortOperators[i] = sortcl->sortop; + transstate->sortCollations[i] = exprCollation((Node *)tle->expr); + transstate->sortNullsFirst[i] = sortcl->nulls_first; i++; } Assert(i == numSortCols); @@ -2744,7 +2742,7 @@ build_peraggstate_for_aggref(AggStatePerAggState peraggstate, * We need the equal function for each DISTINCT comparison we will * make. */ - peraggstate->equalfns = + transstate->equalfns = (FmgrInfo *) palloc(numDistinctCols * sizeof(FmgrInfo)); i = 0; @@ -2752,16 +2750,14 @@ build_peraggstate_for_aggref(AggStatePerAggState peraggstate, { SortGroupClause *sortcl = (SortGroupClause *) lfirst(lc); - fmgr_info(get_opcode(sortcl->eqop), &peraggstate->equalfns[i]); + fmgr_info(get_opcode(sortcl->eqop), &transstate->equalfns[i]); i++; } Assert(i == numDistinctCols); } - peraggstate->sortstates = (Tuplesortstate **) + transstate->sortstates = (Tuplesortstate **) palloc0(sizeof(Tuplesortstate *) * numGroupingSets); - for (currentsortno = 0; currentsortno < numGroupingSets; currentsortno++) - peraggstate->sortstates[currentsortno] = NULL; } @@ -2838,7 +2834,7 @@ find_compatible_aggref(Aggref *newagg, AggState *aggstate, { int aggno; int statematchaggno; - AggStatePerAggState peraggstates; + AggStateTransState transstates; AggStatePerAgg peraggs; /* we mustn't reuse the aggref if it contains volatile function calls */ @@ -2846,7 +2842,7 @@ find_compatible_aggref(Aggref *newagg, AggState *aggstate, return AGGREF_NO_MATCH; statematchaggno = -1; - peraggstates = aggstate->peraggstate; + transstates = aggstate->transstates; peraggs = aggstate->peragg; /* @@ -2859,13 +2855,13 @@ find_compatible_aggref(Aggref *newagg, AggState *aggstate, { AggRefCompatibility matchtype; AggStatePerAgg peragg; - AggStatePerAggState peraggstate; + AggStateTransState transstate; peragg = &peraggs[aggno]; - peraggstate = &peraggstates[peragg->stateno]; + transstate = &transstates[peragg->stateno]; /* lookup the match type of this agg */ - matchtype = aggref_has_compatible_states(newagg, peragg, peraggstate); + matchtype = aggref_has_compatible_states(newagg, peragg, transstate); /* if it's an exact match then we're done. */ if (matchtype == AGGREF_EXACT_MATCH) @@ -2897,9 +2893,9 @@ find_compatible_aggref(Aggref *newagg, AggState *aggstate, static AggRefCompatibility aggref_has_compatible_states(Aggref *newagg, AggStatePerAgg peragg, - AggStatePerAggState peraggstate) + AggStateTransState transstate) { - Aggref *existingRef = peraggstate->aggref; + Aggref *existingRef = transstate->aggref; /* all of the following must be the same or it's no match */ if (newagg->inputcollid != existingRef->inputcollid || @@ -2938,7 +2934,7 @@ aggref_has_compatible_states(Aggref *newagg, aggform = (Form_pg_aggregate) GETSTRUCT(aggTuple); /* if the transfns are not the same then the state can't be shared */ - if (aggform->aggtransfn != peraggstate->transfn_oid) + if (aggform->aggtransfn != transstate->transfn_oid) { ReleaseSysCache(aggTuple); return AGGREF_NO_MATCH; @@ -2953,7 +2949,7 @@ aggref_has_compatible_states(Aggref *newagg, * If both INITCONDs are null then the outcome depends on if the * finalfns match. */ - if (initValueIsNull && peraggstate->initValueIsNull) + if (initValueIsNull && transstate->initValueIsNull) { if (aggform->aggfinalfn != peragg->finalfn_oid) return AGGREF_STATE_MATCH; @@ -2986,12 +2982,12 @@ ExecEndAgg(AggState *node) for (stateno = 0; stateno < node->numstates; stateno++) { - AggStatePerAggState peraggstate = &node->peraggstate[stateno]; + AggStateTransState transstate = &node->transstates[stateno]; for (setno = 0; setno < numGroupingSets; setno++) { - if (peraggstate->sortstates[setno]) - tuplesort_end(peraggstate->sortstates[setno]); + if (transstate->sortstates[setno]) + tuplesort_end(transstate->sortstates[setno]); } } @@ -3055,12 +3051,12 @@ ExecReScanAgg(AggState *node) { for (setno = 0; setno < numGroupingSets; setno++) { - AggStatePerAggState peraggstate = &node->peraggstate[stateno]; + AggStateTransState transstate = &node->transstates[stateno]; - if (peraggstate->sortstates[setno]) + if (transstate->sortstates[setno]) { - tuplesort_end(peraggstate->sortstates[setno]); - peraggstate->sortstates[setno] = NULL; + tuplesort_end(transstate->sortstates[setno]); + transstate->sortstates[setno] = NULL; } } } @@ -3184,12 +3180,12 @@ AggGetAggref(FunctionCallInfo fcinfo) { if (fcinfo->context && IsA(fcinfo->context, AggState)) { - AggStatePerAggState curperaggstate; + AggStateTransState curtransstate; - curperaggstate = ((AggState *) fcinfo->context)->curperaggstate; + curtransstate = ((AggState *)fcinfo->context)->curtransstate; - if (curperaggstate) - return curperaggstate->aggref; + if (curtransstate) + return curtransstate->aggref; } return NULL; } diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index 65c0f74..3579f3b 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -1822,7 +1822,7 @@ typedef struct GroupState */ /* these structs are private in nodeAgg.c: */ typedef struct AggStatePerAggData *AggStatePerAgg; -typedef struct AggStatePerAggStateData *AggStatePerAggState; +typedef struct AggStateTransStateData *AggStateTransState; typedef struct AggStatePerGroupData *AggStatePerGroup; typedef struct AggStatePerPhaseData *AggStatePerPhase; @@ -1837,10 +1837,10 @@ typedef struct AggState int current_phase; /* current phase number */ FmgrInfo *hashfunctions; /* per-grouping-field hash fns */ AggStatePerAgg peragg; /* per-Aggref information */ - AggStatePerAggState peraggstate; /* per-Agg State information */ + AggStateTransState transstates; /* per-Agg State information */ ExprContext **aggcontexts; /* econtexts for long-lived data (per GS) */ ExprContext *tmpcontext; /* econtext for input expressions */ - AggStatePerAggState curperaggstate; /* identifies currently active aggregate */ + AggStateTransState curtransstate; /* identifies currently active aggregate */ bool input_done; /* indicates end of input */ bool agg_done; /* indicates completion of Agg scan */ int projected_set; /* The last projected grouping set */