Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1466bcf

Browse files
committed
Split create_grouping_paths into degenerate and non-degenerate cases.
There's no functional change here, or at least I hope there isn't,just code rearrangement. The rearrangement is motivated bypartition-wise aggregate, which doesn't need to consider thedegenerate case but wants to reuse the logic for the ordinary case.Based loosely on a patch from Ashutosh Bapat and Jeevan Chalke, but Iwhacked it around pretty heavily. The larger patch series of whichthis patch is a part was also reviewed and tested by Antonin Houska,Rajkumar Raghuwanshi, David Rowley, Dilip Kumar, Konstantin Knizhnik,Pascal Legrand, Rafia Sabih, and me.Discussion:http://postgr.es/m/CAFjFpRewpqCmVkwvq6qrRjmbMDpN0CZvRRzjd8UvncczA3Oz1Q@mail.gmail.com
1 parenta446a1c commit1466bcf

File tree

1 file changed

+114
-72
lines changed

1 file changed

+114
-72
lines changed

‎src/backend/optimizer/plan/planner.c

Lines changed: 114 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,16 @@ static RelOptInfo *create_grouping_paths(PlannerInfo *root,
141141
booltarget_parallel_safe,
142142
constAggClauseCosts*agg_costs,
143143
grouping_sets_data*gd);
144+
staticboolis_degenerate_grouping(PlannerInfo*root);
145+
staticvoidcreate_degenerate_grouping_paths(PlannerInfo*root,
146+
RelOptInfo*input_rel,
147+
PathTarget*target,RelOptInfo*grouped_rel);
148+
staticvoidcreate_ordinary_grouping_paths(PlannerInfo*root,
149+
RelOptInfo*input_rel,
150+
PathTarget*target,RelOptInfo*grouped_rel,
151+
RelOptInfo*partially_grouped_rel,
152+
constAggClauseCosts*agg_costs,
153+
grouping_sets_data*gd);
144154
staticvoidconsider_groupingsets_paths(PlannerInfo*root,
145155
RelOptInfo*grouped_rel,
146156
Path*path,
@@ -3667,11 +3677,6 @@ estimate_hashagg_tablesize(Path *path, const AggClauseCosts *agg_costs,
36673677
*
36683678
* Note: all Paths in input_rel are expected to return the target computed
36693679
* by make_group_input_target.
3670-
*
3671-
* We need to consider sorted and hashed aggregation in the same function,
3672-
* because otherwise (1) it would be harder to throw an appropriate error
3673-
* message if neither way works, and (2) we should not allow hashtable size
3674-
* considerations to dissuade us from using hashing if sorting is not possible.
36753680
*/
36763681
staticRelOptInfo*
36773682
create_grouping_paths(PlannerInfo*root,
@@ -3682,15 +3687,8 @@ create_grouping_paths(PlannerInfo *root,
36823687
grouping_sets_data*gd)
36833688
{
36843689
Query*parse=root->parse;
3685-
Path*cheapest_path=input_rel->cheapest_total_path;
36863690
RelOptInfo*grouped_rel;
36873691
RelOptInfo*partially_grouped_rel;
3688-
AggClauseCostsagg_partial_costs;/* parallel only */
3689-
AggClauseCostsagg_final_costs;/* parallel only */
3690-
doubledNumGroups;
3691-
boolcan_hash;
3692-
boolcan_sort;
3693-
booltry_parallel_aggregation;
36943692

36953693
/*
36963694
* For now, all aggregated paths are added to the (GROUP_AGG, NULL)
@@ -3728,73 +3726,123 @@ create_grouping_paths(PlannerInfo *root,
37283726
partially_grouped_rel->fdwroutine=input_rel->fdwroutine;
37293727

37303728
/*
3731-
* Check for degenerate grouping.
3729+
* Create either paths for a degenerate grouping or paths for ordinary
3730+
* grouping, as appropriate.
37323731
*/
3733-
if ((root->hasHavingQual||parse->groupingSets)&&
3734-
!parse->hasAggs&&parse->groupClause==NIL)
3732+
if (is_degenerate_grouping(root))
3733+
create_degenerate_grouping_paths(root,input_rel,target,grouped_rel);
3734+
else
3735+
create_ordinary_grouping_paths(root,input_rel,target,grouped_rel,
3736+
partially_grouped_rel,agg_costs,gd);
3737+
3738+
set_cheapest(grouped_rel);
3739+
returngrouped_rel;
3740+
}
3741+
3742+
/*
3743+
* is_degenerate_grouping
3744+
*
3745+
* A degenerate grouping is one in which the query has a HAVING qual and/or
3746+
* grouping sets, but no aggregates and no GROUP BY (which implies that the
3747+
* grouping sets are all empty).
3748+
*/
3749+
staticbool
3750+
is_degenerate_grouping(PlannerInfo*root)
3751+
{
3752+
Query*parse=root->parse;
3753+
3754+
return (root->hasHavingQual||parse->groupingSets)&&
3755+
!parse->hasAggs&&parse->groupClause==NIL;
3756+
}
3757+
3758+
/*
3759+
* create_degenerate_grouping_paths
3760+
*
3761+
* When the grouping is degenerate (see is_degenerate_grouping), we are
3762+
* supposed to emit either zero or one row for each grouping set depending on
3763+
* whether HAVING succeeds. Furthermore, there cannot be any variables in
3764+
* either HAVING or the targetlist, so we actually do not need the FROM table
3765+
* at all! We can just throw away the plan-so-far and generate a Result node.
3766+
* This is a sufficiently unusual corner case that it's not worth contorting
3767+
* the structure of this module to avoid having to generate the earlier paths
3768+
* in the first place.
3769+
*/
3770+
staticvoid
3771+
create_degenerate_grouping_paths(PlannerInfo*root,RelOptInfo*input_rel,
3772+
PathTarget*target,RelOptInfo*grouped_rel)
3773+
{
3774+
Query*parse=root->parse;
3775+
intnrows;
3776+
Path*path;
3777+
3778+
nrows=list_length(parse->groupingSets);
3779+
if (nrows>1)
37353780
{
37363781
/*
3737-
* We have a HAVING qual and/or grouping sets, but no aggregates and
3738-
* no GROUP BY (which implies that the grouping sets are all empty).
3739-
*
3740-
* This is a degenerate case in which we are supposed to emit either
3741-
* zero or one row for each grouping set depending on whether HAVING
3742-
* succeeds. Furthermore, there cannot be any variables in either
3743-
* HAVING or the targetlist, so we actually do not need the FROM table
3744-
* at all!We can just throw away the plan-so-far and generate a
3745-
* Result node. This is a sufficiently unusual corner case that it's
3746-
* not worth contorting the structure of this module to avoid having
3747-
* to generate the earlier paths in the first place.
3782+
* Doesn't seem worthwhile writing code to cons up a generate_series
3783+
* or a values scan to emit multiple rows. Instead just make N clones
3784+
* and append them. (With a volatile HAVING clause, this means you
3785+
* might get between 0 and N output rows. Offhand I think that's
3786+
* desired.)
37483787
*/
3749-
intnrows=list_length(parse->groupingSets);
3750-
Path*path;
3788+
List*paths=NIL;
37513789

3752-
if (nrows>1)
3790+
while (--nrows >=0)
37533791
{
3754-
/*
3755-
* Doesn't seem worthwhile writing code to cons up a
3756-
* generate_series or a values scan to emit multiple rows. Instead
3757-
* just make N clones and append them. (With a volatile HAVING
3758-
* clause, this means you might get between 0 and N output rows.
3759-
* Offhand I think that's desired.)
3760-
*/
3761-
List*paths=NIL;
3762-
3763-
while (--nrows >=0)
3764-
{
3765-
path= (Path*)
3766-
create_result_path(root,grouped_rel,
3767-
target,
3768-
(List*)parse->havingQual);
3769-
paths=lappend(paths,path);
3770-
}
3771-
path= (Path*)
3772-
create_append_path(grouped_rel,
3773-
paths,
3774-
NIL,
3775-
NULL,
3776-
0,
3777-
false,
3778-
NIL,
3779-
-1);
3780-
path->pathtarget=target;
3781-
}
3782-
else
3783-
{
3784-
/* No grouping sets, or just one, so one output row */
37853792
path= (Path*)
37863793
create_result_path(root,grouped_rel,
37873794
target,
37883795
(List*)parse->havingQual);
3796+
paths=lappend(paths,path);
37893797
}
3798+
path= (Path*)
3799+
create_append_path(grouped_rel,
3800+
paths,
3801+
NIL,
3802+
NULL,
3803+
0,
3804+
false,
3805+
NIL,
3806+
-1);
3807+
path->pathtarget=target;
3808+
}
3809+
else
3810+
{
3811+
/* No grouping sets, or just one, so one output row */
3812+
path= (Path*)
3813+
create_result_path(root,grouped_rel,
3814+
target,
3815+
(List*)parse->havingQual);
3816+
}
37903817

3791-
add_path(grouped_rel,path);
3792-
3793-
/* No need to consider any other alternatives. */
3794-
set_cheapest(grouped_rel);
3818+
add_path(grouped_rel,path);
3819+
}
37953820

3796-
returngrouped_rel;
3797-
}
3821+
/*
3822+
* create_ordinary_grouping_paths
3823+
*
3824+
* Create grouping paths for the ordinary (that is, non-degenerate) case.
3825+
*
3826+
* We need to consider sorted and hashed aggregation in the same function,
3827+
* because otherwise (1) it would be harder to throw an appropriate error
3828+
* message if neither way works, and (2) we should not allow hashtable size
3829+
* considerations to dissuade us from using hashing if sorting is not possible.
3830+
*/
3831+
staticvoid
3832+
create_ordinary_grouping_paths(PlannerInfo*root,RelOptInfo*input_rel,
3833+
PathTarget*target,RelOptInfo*grouped_rel,
3834+
RelOptInfo*partially_grouped_rel,
3835+
constAggClauseCosts*agg_costs,
3836+
grouping_sets_data*gd)
3837+
{
3838+
Query*parse=root->parse;
3839+
Path*cheapest_path=input_rel->cheapest_total_path;
3840+
AggClauseCostsagg_partial_costs;/* parallel only */
3841+
AggClauseCostsagg_final_costs;/* parallel only */
3842+
doubledNumGroups;
3843+
boolcan_hash;
3844+
boolcan_sort;
3845+
booltry_parallel_aggregation;
37983846

37993847
/*
38003848
* Estimate number of groups.
@@ -3922,14 +3970,8 @@ create_grouping_paths(PlannerInfo *root,
39223970
if (create_upper_paths_hook)
39233971
(*create_upper_paths_hook) (root,UPPERREL_GROUP_AGG,
39243972
input_rel,grouped_rel);
3925-
3926-
/* Now choose the best path(s) */
3927-
set_cheapest(grouped_rel);
3928-
3929-
returngrouped_rel;
39303973
}
39313974

3932-
39333975
/*
39343976
* For a given input path, consider the possible ways of doing grouping sets on
39353977
* it, by combinations of hashing and sorting. This can be called multiple

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp