summaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeAgg.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor/nodeAgg.c')
-rw-r--r--src/backend/executor/nodeAgg.c143
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 **)