@@ -114,6 +114,7 @@ static Size estimate_hashagg_tablesize(Path *path,
114
114
static RelOptInfo * create_grouping_paths (PlannerInfo * root ,
115
115
RelOptInfo * input_rel ,
116
116
PathTarget * target ,
117
+ const AggClauseCosts * agg_costs ,
117
118
List * rollup_lists ,
118
119
List * rollup_groupclauses );
119
120
static RelOptInfo * create_window_paths (PlannerInfo * root ,
@@ -1499,6 +1500,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
1499
1500
PathTarget * grouping_target ;
1500
1501
PathTarget * scanjoin_target ;
1501
1502
bool have_grouping ;
1503
+ AggClauseCosts agg_costs ;
1502
1504
WindowFuncLists * wflists = NULL ;
1503
1505
List * activeWindows = NIL ;
1504
1506
List * rollup_lists = NIL ;
@@ -1623,6 +1625,28 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
1623
1625
*/
1624
1626
root -> processed_tlist = tlist ;
1625
1627
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
+
1626
1650
/*
1627
1651
* Locate any window functions in the tlist. (We don't need to look
1628
1652
* anywhere else, since expressions used in ORDER BY will be in there
@@ -1822,6 +1846,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
1822
1846
current_rel = create_grouping_paths (root ,
1823
1847
current_rel ,
1824
1848
grouping_target ,
1849
+ & agg_costs ,
1825
1850
rollup_lists ,
1826
1851
rollup_groupclauses );
1827
1852
}
@@ -3244,6 +3269,7 @@ estimate_hashagg_tablesize(Path *path, const AggClauseCosts *agg_costs,
3244
3269
*
3245
3270
* input_rel: contains the source-data Paths
3246
3271
* target: the pathtarget for the result Paths to compute
3272
+ * agg_costs: cost info about all aggregates in query (in AGGSPLIT_SIMPLE mode)
3247
3273
* rollup_lists: list of grouping sets, or NIL if not doing grouping sets
3248
3274
* rollup_groupclauses: list of grouping clauses for grouping sets,
3249
3275
* or NIL if not doing grouping sets
@@ -3260,14 +3286,14 @@ static RelOptInfo *
3260
3286
create_grouping_paths (PlannerInfo * root ,
3261
3287
RelOptInfo * input_rel ,
3262
3288
PathTarget * target ,
3289
+ const AggClauseCosts * agg_costs ,
3263
3290
List * rollup_lists ,
3264
3291
List * rollup_groupclauses )
3265
3292
{
3266
3293
Query * parse = root -> parse ;
3267
3294
Path * cheapest_path = input_rel -> cheapest_total_path ;
3268
3295
RelOptInfo * grouped_rel ;
3269
3296
PathTarget * partial_grouping_target = NULL ;
3270
- AggClauseCosts agg_costs ;
3271
3297
AggClauseCosts agg_partial_costs ; /* parallel only */
3272
3298
AggClauseCosts agg_final_costs ; /* parallel only */
3273
3299
Size hashaggtablesize ;
@@ -3364,20 +3390,6 @@ create_grouping_paths(PlannerInfo *root,
3364
3390
return grouped_rel ;
3365
3391
}
3366
3392
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
-
3381
3393
/*
3382
3394
* Estimate number of groups.
3383
3395
*/
@@ -3414,7 +3426,7 @@ create_grouping_paths(PlannerInfo *root,
3414
3426
*/
3415
3427
can_hash = (parse -> groupClause != NIL &&
3416
3428
parse -> groupingSets == NIL &&
3417
- agg_costs . numOrderedAggs == 0 &&
3429
+ agg_costs -> numOrderedAggs == 0 &&
3418
3430
grouping_is_hashable (parse -> groupClause ));
3419
3431
3420
3432
/*
@@ -3446,7 +3458,7 @@ create_grouping_paths(PlannerInfo *root,
3446
3458
/* We don't know how to do grouping sets in parallel. */
3447
3459
try_parallel_aggregation = false;
3448
3460
}
3449
- else if (agg_costs . hasNonPartial || agg_costs . hasNonSerial )
3461
+ else if (agg_costs -> hasNonPartial || agg_costs -> hasNonSerial )
3450
3462
{
3451
3463
/* Insufficient support for partial mode. */
3452
3464
try_parallel_aggregation = false;
@@ -3627,7 +3639,7 @@ create_grouping_paths(PlannerInfo *root,
3627
3639
(List * ) parse -> havingQual ,
3628
3640
rollup_lists ,
3629
3641
rollup_groupclauses ,
3630
- & agg_costs ,
3642
+ agg_costs ,
3631
3643
dNumGroups ));
3632
3644
}
3633
3645
else if (parse -> hasAggs )
@@ -3645,7 +3657,7 @@ create_grouping_paths(PlannerInfo *root,
3645
3657
AGGSPLIT_SIMPLE ,
3646
3658
parse -> groupClause ,
3647
3659
(List * ) parse -> havingQual ,
3648
- & agg_costs ,
3660
+ agg_costs ,
3649
3661
dNumGroups ));
3650
3662
}
3651
3663
else if (parse -> groupClause )
@@ -3727,7 +3739,7 @@ create_grouping_paths(PlannerInfo *root,
3727
3739
if (can_hash )
3728
3740
{
3729
3741
hashaggtablesize = estimate_hashagg_tablesize (cheapest_path ,
3730
- & agg_costs ,
3742
+ agg_costs ,
3731
3743
dNumGroups );
3732
3744
3733
3745
/*
@@ -3751,7 +3763,7 @@ create_grouping_paths(PlannerInfo *root,
3751
3763
AGGSPLIT_SIMPLE ,
3752
3764
parse -> groupClause ,
3753
3765
(List * ) parse -> havingQual ,
3754
- & agg_costs ,
3766
+ agg_costs ,
3755
3767
dNumGroups ));
3756
3768
}
3757
3769
0 commit comments