aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeAgg.c
diff options
context:
space:
mode:
authorAndres Freund <andres@anarazel.de>2018-02-16 21:17:38 -0800
committerAndres Freund <andres@anarazel.de>2018-02-16 21:17:38 -0800
commitad7dbee368a7cd9e595d2a957be784326b08c943 (patch)
treea4846e24bf9f2d78b7c8dfb04323ef984aede517 /src/backend/executor/nodeAgg.c
parentbf6c614a2f2c58312b3be34a47e7fb7362e07bcb (diff)
downloadpostgresql-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.c62
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 */