@@ -114,6 +114,7 @@ static Size estimate_hashagg_tablesize(Path *path,
114114static RelOptInfo * create_grouping_paths (PlannerInfo * root ,
115115 RelOptInfo * input_rel ,
116116 PathTarget * target ,
117+ const AggClauseCosts * agg_costs ,
117118 List * rollup_lists ,
118119 List * rollup_groupclauses );
119120static RelOptInfo * create_window_paths (PlannerInfo * root ,
@@ -1499,6 +1500,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
14991500 PathTarget * grouping_target ;
15001501 PathTarget * scanjoin_target ;
15011502 bool have_grouping ;
1503+ AggClauseCosts agg_costs ;
15021504 WindowFuncLists * wflists = NULL ;
15031505 List * activeWindows = NIL ;
15041506 List * rollup_lists = NIL ;
@@ -1623,6 +1625,28 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
16231625 */
16241626 root -> 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,
18221846 current_rel = create_grouping_paths (root ,
18231847 current_rel ,
18241848 grouping_target ,
1849+ & agg_costs ,
18251850 rollup_lists ,
18261851 rollup_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 ,
32613287 RelOptInfo * input_rel ,
32623288 PathTarget * target ,
3289+ const AggClauseCosts * agg_costs ,
32633290 List * rollup_lists ,
32643291 List * rollup_groupclauses )
32653292{
32663293 Query * parse = root -> parse ;
32673294 Path * cheapest_path = input_rel -> cheapest_total_path ;
32683295 RelOptInfo * grouped_rel ;
32693296 PathTarget * partial_grouping_target = NULL ;
3270- AggClauseCosts agg_costs ;
32713297 AggClauseCosts agg_partial_costs ; /* parallel only */
32723298 AggClauseCosts agg_final_costs ; /* parallel only */
32733299 Size hashaggtablesize ;
@@ -3364,20 +3390,6 @@ create_grouping_paths(PlannerInfo *root,
33643390 return 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 */
34153427 can_hash = (parse -> groupClause != NIL &&
34163428 parse -> groupingSets == NIL &&
3417- agg_costs . numOrderedAggs == 0 &&
3429+ agg_costs -> numOrderedAggs == 0 &&
34183430 grouping_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. */
34473459 try_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. */
34523464 try_parallel_aggregation = false;
@@ -3627,7 +3639,7 @@ create_grouping_paths(PlannerInfo *root,
36273639 (List * ) parse -> havingQual ,
36283640 rollup_lists ,
36293641 rollup_groupclauses ,
3630- & agg_costs ,
3642+ agg_costs ,
36313643 dNumGroups ));
36323644 }
36333645 else if (parse -> hasAggs )
@@ -3645,7 +3657,7 @@ create_grouping_paths(PlannerInfo *root,
36453657 AGGSPLIT_SIMPLE ,
36463658 parse -> groupClause ,
36473659 (List * ) parse -> havingQual ,
3648- & agg_costs ,
3660+ agg_costs ,
36493661 dNumGroups ));
36503662 }
36513663 else if (parse -> groupClause )
@@ -3727,7 +3739,7 @@ create_grouping_paths(PlannerInfo *root,
37273739 if (can_hash )
37283740 {
37293741 hashaggtablesize = estimate_hashagg_tablesize (cheapest_path ,
3730- & agg_costs ,
3742+ agg_costs ,
37313743 dNumGroups );
37323744
37333745 /*
@@ -3751,7 +3763,7 @@ create_grouping_paths(PlannerInfo *root,
37513763 AGGSPLIT_SIMPLE ,
37523764 parse -> groupClause ,
37533765 (List * ) parse -> havingQual ,
3754- & agg_costs ,
3766+ agg_costs ,
37553767 dNumGroups ));
37563768 }
37573769
0 commit comments