@@ -114,6 +114,7 @@ static Size estimate_hashagg_tablesize(Path *path,
114114static RelOptInfo * create_grouping_paths (PlannerInfo * root ,
115115RelOptInfo * input_rel ,
116116PathTarget * target ,
117+ const AggClauseCosts * agg_costs ,
117118List * rollup_lists ,
118119List * rollup_groupclauses );
119120static RelOptInfo * create_window_paths (PlannerInfo * root ,
@@ -1499,6 +1500,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
14991500PathTarget * grouping_target ;
15001501PathTarget * scanjoin_target ;
15011502bool have_grouping ;
1503+ AggClauseCosts agg_costs ;
15021504WindowFuncLists * wflists = NULL ;
15031505List * activeWindows = NIL ;
15041506List * rollup_lists = NIL ;
@@ -1623,6 +1625,28 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
16231625 */
16241626root -> processed_tlist = tlist ;
16251627
1628+ /*
1629+ * Collect statistics about aggregates for estimating costs, and mark
1630+ * all the aggregates with resolved aggtranstypes. We must do this
1631+ * before slicing and dicing the tlist into various pathtargets, else
1632+ * some copies of the Aggref nodes might escape being marked with the
1633+ * correct transtypes.
1634+ *
1635+ * Note: currently, we do not detect duplicate aggregates here. This
1636+ * may result in somewhat-overestimated cost, which is fine for our
1637+ * purposes since all Paths will get charged the same. But at some
1638+ * point we might wish to do that detection in the planner, rather
1639+ * than during executor startup.
1640+ */
1641+ MemSet (& agg_costs ,0 ,sizeof (AggClauseCosts ));
1642+ if (parse -> hasAggs )
1643+ {
1644+ get_agg_clause_costs (root , (Node * )tlist ,AGGSPLIT_SIMPLE ,
1645+ & agg_costs );
1646+ get_agg_clause_costs (root ,parse -> havingQual ,AGGSPLIT_SIMPLE ,
1647+ & agg_costs );
1648+ }
1649+
16261650/*
16271651 * Locate any window functions in the tlist. (We don't need to look
16281652 * anywhere else, since expressions used in ORDER BY will be in there
@@ -1822,6 +1846,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
18221846current_rel = create_grouping_paths (root ,
18231847current_rel ,
18241848grouping_target ,
1849+ & agg_costs ,
18251850rollup_lists ,
18261851rollup_groupclauses );
18271852}
@@ -3244,6 +3269,7 @@ estimate_hashagg_tablesize(Path *path, const AggClauseCosts *agg_costs,
32443269 *
32453270 * input_rel: contains the source-data Paths
32463271 * target: the pathtarget for the result Paths to compute
3272+ * agg_costs: cost info about all aggregates in query (in AGGSPLIT_SIMPLE mode)
32473273 * rollup_lists: list of grouping sets, or NIL if not doing grouping sets
32483274 * rollup_groupclauses: list of grouping clauses for grouping sets,
32493275 *or NIL if not doing grouping sets
@@ -3260,14 +3286,14 @@ static RelOptInfo *
32603286create_grouping_paths (PlannerInfo * root ,
32613287RelOptInfo * input_rel ,
32623288PathTarget * target ,
3289+ const AggClauseCosts * agg_costs ,
32633290List * rollup_lists ,
32643291List * rollup_groupclauses )
32653292{
32663293Query * parse = root -> parse ;
32673294Path * cheapest_path = input_rel -> cheapest_total_path ;
32683295RelOptInfo * grouped_rel ;
32693296PathTarget * partial_grouping_target = NULL ;
3270- AggClauseCosts agg_costs ;
32713297AggClauseCosts agg_partial_costs ;/* parallel only */
32723298AggClauseCosts agg_final_costs ;/* parallel only */
32733299Size hashaggtablesize ;
@@ -3364,20 +3390,6 @@ create_grouping_paths(PlannerInfo *root,
33643390return grouped_rel ;
33653391}
33663392
3367- /*
3368- * Collect statistics about aggregates for estimating costs. Note: we do
3369- * not detect duplicate aggregates here; a somewhat-overestimated cost is
3370- * okay for our purposes.
3371- */
3372- MemSet (& agg_costs ,0 ,sizeof (AggClauseCosts ));
3373- if (parse -> hasAggs )
3374- {
3375- get_agg_clause_costs (root , (Node * )target -> exprs ,AGGSPLIT_SIMPLE ,
3376- & agg_costs );
3377- get_agg_clause_costs (root ,parse -> havingQual ,AGGSPLIT_SIMPLE ,
3378- & agg_costs );
3379- }
3380-
33813393/*
33823394 * Estimate number of groups.
33833395 */
@@ -3414,7 +3426,7 @@ create_grouping_paths(PlannerInfo *root,
34143426 */
34153427can_hash = (parse -> groupClause != NIL &&
34163428parse -> groupingSets == NIL &&
3417- agg_costs . numOrderedAggs == 0 &&
3429+ agg_costs -> numOrderedAggs == 0 &&
34183430grouping_is_hashable (parse -> groupClause ));
34193431
34203432/*
@@ -3446,7 +3458,7 @@ create_grouping_paths(PlannerInfo *root,
34463458/* We don't know how to do grouping sets in parallel. */
34473459try_parallel_aggregation = false;
34483460}
3449- else if (agg_costs . hasNonPartial || agg_costs . hasNonSerial )
3461+ else if (agg_costs -> hasNonPartial || agg_costs -> hasNonSerial )
34503462{
34513463/* Insufficient support for partial mode. */
34523464try_parallel_aggregation = false;
@@ -3627,7 +3639,7 @@ create_grouping_paths(PlannerInfo *root,
36273639 (List * )parse -> havingQual ,
36283640rollup_lists ,
36293641rollup_groupclauses ,
3630- & agg_costs ,
3642+ agg_costs ,
36313643dNumGroups ));
36323644}
36333645else if (parse -> hasAggs )
@@ -3645,7 +3657,7 @@ create_grouping_paths(PlannerInfo *root,
36453657AGGSPLIT_SIMPLE ,
36463658parse -> groupClause ,
36473659 (List * )parse -> havingQual ,
3648- & agg_costs ,
3660+ agg_costs ,
36493661dNumGroups ));
36503662}
36513663else if (parse -> groupClause )
@@ -3727,7 +3739,7 @@ create_grouping_paths(PlannerInfo *root,
37273739if (can_hash )
37283740{
37293741hashaggtablesize = estimate_hashagg_tablesize (cheapest_path ,
3730- & agg_costs ,
3742+ agg_costs ,
37313743dNumGroups );
37323744
37333745/*
@@ -3751,7 +3763,7 @@ create_grouping_paths(PlannerInfo *root,
37513763AGGSPLIT_SIMPLE ,
37523764parse -> groupClause ,
37533765 (List * )parse -> havingQual ,
3754- & agg_costs ,
3766+ agg_costs ,
37553767dNumGroups ));
37563768}
37573769