diff options
Diffstat (limited to 'src/backend/executor/nodeAgg.c')
-rw-r--r-- | src/backend/executor/nodeAgg.c | 143 |
1 files changed, 56 insertions, 87 deletions
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c index 467f8d896ec..a86d4b68eac 100644 --- a/src/backend/executor/nodeAgg.c +++ b/src/backend/executor/nodeAgg.c @@ -755,7 +755,7 @@ process_ordered_aggregate_single(AggState *aggstate, ((oldIsNull && *isNull) || (!oldIsNull && !*isNull && oldAbbrevVal == newAbbrevVal && - DatumGetBool(FunctionCall2(&pertrans->equalfnOne, + DatumGetBool(FunctionCall2(&pertrans->equalfns[0], oldVal, *newVal))))) { /* equal to prior, so forget this one */ @@ -802,7 +802,7 @@ process_ordered_aggregate_multi(AggState *aggstate, AggStatePerTrans pertrans, AggStatePerGroup pergroupstate) { - ExprContext *tmpcontext = aggstate->tmpcontext; + MemoryContext workcontext = aggstate->tmpcontext->ecxt_per_tuple_memory; FunctionCallInfo fcinfo = &pertrans->transfn_fcinfo; TupleTableSlot *slot1 = pertrans->sortslot; TupleTableSlot *slot2 = pertrans->uniqslot; @@ -811,7 +811,6 @@ process_ordered_aggregate_multi(AggState *aggstate, Datum newAbbrevVal = (Datum) 0; Datum oldAbbrevVal = (Datum) 0; bool haveOldValue = false; - TupleTableSlot *save = aggstate->tmpcontext->ecxt_outertuple; int i; tuplesort_performsort(pertrans->sortstates[aggstate->current_set]); @@ -825,20 +824,22 @@ process_ordered_aggregate_multi(AggState *aggstate, { CHECK_FOR_INTERRUPTS(); - tmpcontext->ecxt_outertuple = slot1; - tmpcontext->ecxt_innertuple = slot2; + /* + * Extract the first numTransInputs columns as datums to pass to the + * transfn. (This will help execTuplesMatch too, so we do it + * immediately.) + */ + slot_getsomeattrs(slot1, numTransInputs); if (numDistinctCols == 0 || !haveOldValue || newAbbrevVal != oldAbbrevVal || - !ExecQual(pertrans->equalfnMulti, tmpcontext)) + !execTuplesMatch(slot1, slot2, + numDistinctCols, + pertrans->sortColIdx, + pertrans->equalfns, + workcontext)) { - /* - * Extract the first numTransInputs columns as datums to pass to - * the transfn. - */ - slot_getsomeattrs(slot1, numTransInputs); - /* Load values into fcinfo */ /* Start from 1, since the 0th arg will be the transition value */ for (i = 0; i < numTransInputs; i++) @@ -856,14 +857,15 @@ process_ordered_aggregate_multi(AggState *aggstate, slot2 = slot1; slot1 = tmpslot; - /* avoid ExecQual() calls by reusing abbreviated keys */ + /* avoid execTuplesMatch() calls by reusing abbreviated keys */ oldAbbrevVal = newAbbrevVal; haveOldValue = true; } } - /* Reset context each time */ - ResetExprContext(tmpcontext); + /* Reset context each time, unless execTuplesMatch did it for us */ + if (numDistinctCols == 0) + MemoryContextReset(workcontext); ExecClearTuple(slot1); } @@ -873,9 +875,6 @@ process_ordered_aggregate_multi(AggState *aggstate, tuplesort_end(pertrans->sortstates[aggstate->current_set]); pertrans->sortstates[aggstate->current_set] = NULL; - - /* restore previous slot, potentially in use for grouping sets */ - tmpcontext->ecxt_outertuple = save; } /* @@ -1277,9 +1276,7 @@ build_hash_table(AggState *aggstate) Assert(perhash->aggnode->numGroups > 0); - perhash->hashtable = BuildTupleHashTable(&aggstate->ss.ps, - perhash->hashslot->tts_tupleDescriptor, - perhash->numCols, + perhash->hashtable = BuildTupleHashTable(perhash->numCols, perhash->hashGrpColIdxHash, perhash->eqfunctions, perhash->hashfunctions, @@ -1317,7 +1314,6 @@ find_hash_columns(AggState *aggstate) Bitmapset *base_colnos; List *outerTlist = outerPlanState(aggstate)->plan->targetlist; int numHashes = aggstate->num_hashes; - EState *estate = aggstate->ss.ps.state; int j; /* Find Vars that will be needed in tlist and qual */ @@ -1397,12 +1393,6 @@ find_hash_columns(AggState *aggstate) } hashDesc = ExecTypeFromTL(hashTlist, false); - - execTuplesHashPrepare(perhash->numCols, - perhash->aggnode->grpOperators, - &perhash->eqfunctions, - &perhash->hashfunctions); - perhash->hashslot = ExecAllocTableSlot(&estate->es_tupleTable); ExecSetSlotDescriptor(perhash->hashslot, hashDesc); list_free(hashTlist); @@ -1704,14 +1694,17 @@ agg_retrieve_direct(AggState *aggstate) * of the next grouping set *---------- */ - tmpcontext->ecxt_innertuple = econtext->ecxt_outertuple; if (aggstate->input_done || (node->aggstrategy != AGG_PLAIN && aggstate->projected_set != -1 && aggstate->projected_set < (numGroupingSets - 1) && nextSetSize > 0 && - !ExecQualAndReset(aggstate->phase->eqfunctions[nextSetSize - 1], - tmpcontext))) + !execTuplesMatch(econtext->ecxt_outertuple, + tmpcontext->ecxt_outertuple, + nextSetSize, + node->grpColIdx, + aggstate->phase->eqfunctions, + tmpcontext->ecxt_per_tuple_memory))) { aggstate->projected_set += 1; @@ -1854,9 +1847,12 @@ agg_retrieve_direct(AggState *aggstate) */ if (node->aggstrategy != AGG_PLAIN) { - tmpcontext->ecxt_innertuple = firstSlot; - if (!ExecQual(aggstate->phase->eqfunctions[node->numCols - 1], - tmpcontext)) + if (!execTuplesMatch(firstSlot, + outerslot, + node->numCols, + node->grpColIdx, + aggstate->phase->eqfunctions, + tmpcontext->ecxt_per_tuple_memory)) { aggstate->grp_firstTuple = ExecCopySlotTuple(outerslot); break; @@ -2082,7 +2078,6 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) AggStatePerGroup *pergroups; Plan *outerPlan; ExprContext *econtext; - TupleDesc scanDesc; int numaggs, transno, aggno; @@ -2238,9 +2233,9 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) * initialize source tuple type. */ ExecAssignScanTypeFromOuterPlan(&aggstate->ss); - scanDesc = aggstate->ss.ss_ScanTupleSlot->tts_tupleDescriptor; if (node->chain) - ExecSetSlotDescriptor(aggstate->sort_slot, scanDesc); + ExecSetSlotDescriptor(aggstate->sort_slot, + aggstate->ss.ss_ScanTupleSlot->tts_tupleDescriptor); /* * Initialize result tuple type and projection info. @@ -2360,43 +2355,11 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) */ if (aggnode->aggstrategy == AGG_SORTED) { - int i = 0; - Assert(aggnode->numCols > 0); - /* - * Build a separate function for each subset of columns that - * need to be compared. - */ phasedata->eqfunctions = - (ExprState **) palloc0(aggnode->numCols * sizeof(ExprState *)); - - /* for each grouping set */ - for (i = 0; i < phasedata->numsets; i++) - { - int length = phasedata->gset_lengths[i]; - - if (phasedata->eqfunctions[length - 1] != NULL) - continue; - - phasedata->eqfunctions[length - 1] = - execTuplesMatchPrepare(scanDesc, - length, - aggnode->grpColIdx, - aggnode->grpOperators, - (PlanState *) aggstate); - } - - /* and for all grouped columns, unless already computed */ - if (phasedata->eqfunctions[aggnode->numCols - 1] == NULL) - { - phasedata->eqfunctions[aggnode->numCols - 1] = - execTuplesMatchPrepare(scanDesc, - aggnode->numCols, - aggnode->grpColIdx, - aggnode->grpOperators, - (PlanState *) aggstate); - } + execTuplesMatchPrepare(aggnode->numCols, + aggnode->grpOperators); } phasedata->aggnode = aggnode; @@ -2449,6 +2412,16 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) */ if (use_hashing) { + for (i = 0; i < numHashes; ++i) + { + aggstate->perhash[i].hashslot = ExecInitExtraTupleSlot(estate); + + execTuplesHashPrepare(aggstate->perhash[i].numCols, + aggstate->perhash[i].aggnode->grpOperators, + &aggstate->perhash[i].eqfunctions, + &aggstate->perhash[i].hashfunctions); + } + /* this is an array of pointers, not structures */ aggstate->hash_pergroup = pergroups; @@ -3128,28 +3101,24 @@ build_pertrans_for_aggref(AggStatePerTrans pertrans, if (aggref->aggdistinct) { - Oid *ops; - Assert(numArguments > 0); - Assert(list_length(aggref->aggdistinct) == numDistinctCols); - ops = palloc(numDistinctCols * sizeof(Oid)); + /* + * We need the equal function for each DISTINCT comparison we will + * make. + */ + pertrans->equalfns = + (FmgrInfo *) palloc(numDistinctCols * sizeof(FmgrInfo)); i = 0; foreach(lc, aggref->aggdistinct) - ops[i++] = ((SortGroupClause *) lfirst(lc))->eqop; + { + SortGroupClause *sortcl = (SortGroupClause *) lfirst(lc); - /* lookup / build the necessary comparators */ - if (numDistinctCols == 1) - fmgr_info(get_opcode(ops[0]), &pertrans->equalfnOne); - else - pertrans->equalfnMulti = - execTuplesMatchPrepare(pertrans->sortdesc, - numDistinctCols, - pertrans->sortColIdx, - ops, - &aggstate->ss.ps); - pfree(ops); + fmgr_info(get_opcode(sortcl->eqop), &pertrans->equalfns[i]); + i++; + } + Assert(i == numDistinctCols); } pertrans->sortstates = (Tuplesortstate **) |