diff options
author | Andres Freund <andres@anarazel.de> | 2018-02-16 21:17:38 -0800 |
---|---|---|
committer | Andres Freund <andres@anarazel.de> | 2018-02-16 21:17:38 -0800 |
commit | ad7dbee368a7cd9e595d2a957be784326b08c943 (patch) | |
tree | a4846e24bf9f2d78b7c8dfb04323ef984aede517 /src/backend/executor/nodeAgg.c | |
parent | bf6c614a2f2c58312b3be34a47e7fb7362e07bcb (diff) | |
download | postgresql-ad7dbee368a7cd9e595d2a957be784326b08c943.tar.gz postgresql-ad7dbee368a7cd9e595d2a957be784326b08c943.zip |
Allow tupleslots to have a fixed tupledesc, use in executor nodes.
The reason for doing so is that it will allow expression evaluation to
optimize based on the underlying tupledesc. In particular it will
allow to JIT tuple deforming together with the expression itself.
For that expression initialization needs to be moved after the
relevant slots are initialized - mostly unproblematic, except in the
case of nodeWorktablescan.c.
After doing so there's no need for ExecAssignResultType() and
ExecAssignResultTypeFromTL() anymore, as all former callers have been
converted to create a slot with a fixed descriptor.
When creating a slot with a fixed descriptor, tts_values/isnull can be
allocated together with the main slot, reducing allocation overhead
and increasing cache density a bit.
Author: Andres Freund
Discussion: https://postgr.es/m/20171206093717.vqdxe5icqttpxs3p@alap3.anarazel.de
Diffstat (limited to 'src/backend/executor/nodeAgg.c')
-rw-r--r-- | src/backend/executor/nodeAgg.c | 62 |
1 files changed, 26 insertions, 36 deletions
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c index e74b3a93911..1b1334006fa 100644 --- a/src/backend/executor/nodeAgg.c +++ b/src/backend/executor/nodeAgg.c @@ -1402,8 +1402,8 @@ find_hash_columns(AggState *aggstate) perhash->aggnode->grpOperators, &perhash->eqfuncoids, &perhash->hashfunctions); - perhash->hashslot = ExecAllocTableSlot(&estate->es_tupleTable); - ExecSetSlotDescriptor(perhash->hashslot, hashDesc); + perhash->hashslot = + ExecAllocTableSlot(&estate->es_tupleTable, hashDesc); list_free(hashTlist); bms_free(colnos); @@ -2199,31 +2199,6 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) ExecAssignExprContext(estate, &aggstate->ss.ps); /* - * tuple table initialization. - * - * For hashtables, we create some additional slots below. - */ - ExecInitScanTupleSlot(estate, &aggstate->ss); - ExecInitResultTupleSlot(estate, &aggstate->ss.ps); - aggstate->sort_slot = ExecInitExtraTupleSlot(estate); - - /* - * initialize child expressions - * - * We expect the parser to have checked that no aggs contain other agg - * calls in their arguments (and just to be sure, we verify it again while - * initializing the plan node). This would make no sense under SQL - * semantics, and it's forbidden by the spec. Because it is true, we - * don't need to worry about evaluating the aggs in any particular order. - * - * Note: execExpr.c finds Aggrefs for us, and adds their AggrefExprState - * nodes to aggstate->aggs. Aggrefs in the qual are found here; Aggrefs - * in the targetlist are found during ExecAssignProjectionInfo, below. - */ - aggstate->ss.ps.qual = - ExecInitQual(node->plan.qual, (PlanState *) aggstate); - - /* * Initialize child nodes. * * If we are doing a hashed aggregation then the child plan does not need @@ -2237,18 +2212,34 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) /* * initialize source tuple type. */ - ExecAssignScanTypeFromOuterPlan(&aggstate->ss); + ExecCreateScanSlotFromOuterPlan(estate, &aggstate->ss); scanDesc = aggstate->ss.ss_ScanTupleSlot->tts_tupleDescriptor; if (node->chain) - ExecSetSlotDescriptor(aggstate->sort_slot, scanDesc); + aggstate->sort_slot = ExecInitExtraTupleSlot(estate, scanDesc); /* - * Initialize result tuple type and projection info. + * Initialize result type, slot and projection. */ - ExecAssignResultTypeFromTL(&aggstate->ss.ps); + ExecInitResultTupleSlotTL(estate, &aggstate->ss.ps); ExecAssignProjectionInfo(&aggstate->ss.ps, NULL); /* + * initialize child expressions + * + * We expect the parser to have checked that no aggs contain other agg + * calls in their arguments (and just to be sure, we verify it again while + * initializing the plan node). This would make no sense under SQL + * semantics, and it's forbidden by the spec. Because it is true, we + * don't need to worry about evaluating the aggs in any particular order. + * + * Note: execExpr.c finds Aggrefs for us, and adds their AggrefExprState + * nodes to aggstate->aggs. Aggrefs in the qual are found here; Aggrefs + * in the targetlist are found during ExecAssignProjectionInfo, below. + */ + aggstate->ss.ps.qual = + ExecInitQual(node->plan.qual, (PlanState *) aggstate); + + /* * We should now have found all Aggrefs in the targetlist and quals. */ numaggs = aggstate->numaggs; @@ -3071,8 +3062,8 @@ build_pertrans_for_aggref(AggStatePerTrans pertrans, if (numSortCols > 0 || aggref->aggfilter) { pertrans->sortdesc = ExecTypeFromTL(aggref->args, false); - pertrans->sortslot = ExecInitExtraTupleSlot(estate); - ExecSetSlotDescriptor(pertrans->sortslot, pertrans->sortdesc); + pertrans->sortslot = + ExecInitExtraTupleSlot(estate, pertrans->sortdesc); } if (numSortCols > 0) @@ -3093,9 +3084,8 @@ build_pertrans_for_aggref(AggStatePerTrans pertrans, else if (numDistinctCols > 0) { /* we will need an extra slot to store prior values */ - pertrans->uniqslot = ExecInitExtraTupleSlot(estate); - ExecSetSlotDescriptor(pertrans->uniqslot, - pertrans->sortdesc); + pertrans->uniqslot = + ExecInitExtraTupleSlot(estate, pertrans->sortdesc); } /* Extract the sort information for use later */ |