summaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeAgg.c
diff options
context:
space:
mode:
authorAndres Freund <andres@anarazel.de>2018-02-15 22:39:18 -0800
committerAndres Freund <andres@anarazel.de>2018-02-15 22:39:18 -0800
commit2a41507dab0f293ff241fe8ae326065998668af8 (patch)
tree30fe1118750ea9c2805bd38a7485390f4d381715 /src/backend/executor/nodeAgg.c
parent773aec7aa98abd38d6d9435913bb8e14e392c274 (diff)
Revert "Do execGrouping.c via expression eval machinery."
This reverts commit 773aec7aa98abd38d6d9435913bb8e14e392c274. There's an unresolved issue in the reverted commit: It only creates one comparator function, but in for the nodeSubplan.c case we need more (c.f. FindTupleHashEntry vs LookupTupleHashEntry calls in nodeSubplan.c). This isn't too difficult to fix, but it's not entirely trivial either. The fact that the issue only causes breakage on 32bit systems shows that the current test coverage isn't that great. To avoid turning half the buildfarm red till those two issues are addressed, revert.
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 **)