Skip to content

Commit 7ab80ac

Browse files
committed
Generalize the common code of adding sort before processing of grouping
Extract the repetitive code pattern into a new function make_ordered_path(). Discussion: https://postgr.es/m/CAPpHfdtzaVa7S4onKy3YvttF2rrH5hQNHx9HtcSTLbpjx%2BMJ%2Bw%40mail.gmail.com Author: Andrei Lepikhov
1 parent 58447e3 commit 7ab80ac

File tree

1 file changed

+80
-148
lines changed

1 file changed

+80
-148
lines changed

src/backend/optimizer/plan/planner.c

+80-148
Original file line numberDiff line numberDiff line change
@@ -6809,6 +6809,58 @@ plan_create_index_workers(Oid tableOid, Oid indexOid)
68096809
return parallel_workers;
68106810
}
68116811

6812+
/*
6813+
* make_ordered_path
6814+
* Return a path ordered by 'pathkeys' based on the given 'path'. May
6815+
* return NULL if it doesn't make sense to generate an ordered path in
6816+
* this case.
6817+
*/
6818+
static Path *
6819+
make_ordered_path(PlannerInfo *root, RelOptInfo *rel, Path *path,
6820+
Path *cheapest_path, List *pathkeys)
6821+
{
6822+
bool is_sorted;
6823+
int presorted_keys;
6824+
6825+
is_sorted = pathkeys_count_contained_in(pathkeys,
6826+
path->pathkeys,
6827+
&presorted_keys);
6828+
6829+
if (!is_sorted)
6830+
{
6831+
/*
6832+
* Try at least sorting the cheapest path and also try incrementally
6833+
* sorting any path which is partially sorted already (no need to deal
6834+
* with paths which have presorted keys when incremental sort is
6835+
* disabled unless it's the cheapest input path).
6836+
*/
6837+
if (path != cheapest_path &&
6838+
(presorted_keys == 0 || !enable_incremental_sort))
6839+
return NULL;
6840+
6841+
/*
6842+
* We've no need to consider both a sort and incremental sort. We'll
6843+
* just do a sort if there are no presorted keys and an incremental
6844+
* sort when there are presorted keys.
6845+
*/
6846+
if (presorted_keys == 0 || !enable_incremental_sort)
6847+
path = (Path *) create_sort_path(root,
6848+
rel,
6849+
path,
6850+
pathkeys,
6851+
-1.0);
6852+
else
6853+
path = (Path *) create_incremental_sort_path(root,
6854+
rel,
6855+
path,
6856+
pathkeys,
6857+
presorted_keys,
6858+
-1.0);
6859+
}
6860+
6861+
return path;
6862+
}
6863+
68126864
/*
68136865
* add_paths_to_grouping_rel
68146866
*
@@ -6840,45 +6892,15 @@ add_paths_to_grouping_rel(PlannerInfo *root, RelOptInfo *input_rel,
68406892
foreach(lc, input_rel->pathlist)
68416893
{
68426894
Path *path = (Path *) lfirst(lc);
6843-
bool is_sorted;
6844-
int presorted_keys;
68456895

6846-
is_sorted = pathkeys_count_contained_in(root->group_pathkeys,
6847-
path->pathkeys,
6848-
&presorted_keys);
6849-
6850-
if (!is_sorted)
6851-
{
6852-
/*
6853-
* Try at least sorting the cheapest path and also try
6854-
* incrementally sorting any path which is partially sorted
6855-
* already (no need to deal with paths which have presorted
6856-
* keys when incremental sort is disabled unless it's the
6857-
* cheapest input path).
6858-
*/
6859-
if (path != cheapest_path &&
6860-
(presorted_keys == 0 || !enable_incremental_sort))
6861-
continue;
6896+
path = make_ordered_path(root,
6897+
grouped_rel,
6898+
path,
6899+
cheapest_path,
6900+
root->group_pathkeys);
68626901

6863-
/*
6864-
* We've no need to consider both a sort and incremental sort.
6865-
* We'll just do a sort if there are no presorted keys and an
6866-
* incremental sort when there are presorted keys.
6867-
*/
6868-
if (presorted_keys == 0 || !enable_incremental_sort)
6869-
path = (Path *) create_sort_path(root,
6870-
grouped_rel,
6871-
path,
6872-
root->group_pathkeys,
6873-
-1.0);
6874-
else
6875-
path = (Path *) create_incremental_sort_path(root,
6876-
grouped_rel,
6877-
path,
6878-
root->group_pathkeys,
6879-
presorted_keys,
6880-
-1.0);
6881-
}
6902+
if (path == NULL)
6903+
continue;
68826904

68836905
/* Now decide what to stick atop it */
68846906
if (parse->groupingSets)
@@ -6935,46 +6957,15 @@ add_paths_to_grouping_rel(PlannerInfo *root, RelOptInfo *input_rel,
69356957
foreach(lc, partially_grouped_rel->pathlist)
69366958
{
69376959
Path *path = (Path *) lfirst(lc);
6938-
bool is_sorted;
6939-
int presorted_keys;
69406960

6941-
is_sorted = pathkeys_count_contained_in(root->group_pathkeys,
6942-
path->pathkeys,
6943-
&presorted_keys);
6944-
6945-
if (!is_sorted)
6946-
{
6947-
/*
6948-
* Try at least sorting the cheapest path and also try
6949-
* incrementally sorting any path which is partially
6950-
* sorted already (no need to deal with paths which have
6951-
* presorted keys when incremental sort is disabled unless
6952-
* it's the cheapest input path).
6953-
*/
6954-
if (path != partially_grouped_rel->cheapest_total_path &&
6955-
(presorted_keys == 0 || !enable_incremental_sort))
6956-
continue;
6961+
path = make_ordered_path(root,
6962+
grouped_rel,
6963+
path,
6964+
partially_grouped_rel->cheapest_total_path,
6965+
root->group_pathkeys);
69576966

6958-
/*
6959-
* We've no need to consider both a sort and incremental
6960-
* sort. We'll just do a sort if there are no pre-sorted
6961-
* keys and an incremental sort when there are presorted
6962-
* keys.
6963-
*/
6964-
if (presorted_keys == 0 || !enable_incremental_sort)
6965-
path = (Path *) create_sort_path(root,
6966-
grouped_rel,
6967-
path,
6968-
root->group_pathkeys,
6969-
-1.0);
6970-
else
6971-
path = (Path *) create_incremental_sort_path(root,
6972-
grouped_rel,
6973-
path,
6974-
root->group_pathkeys,
6975-
presorted_keys,
6976-
-1.0);
6977-
}
6967+
if (path == NULL)
6968+
continue;
69786969

69796970
if (parse->hasAggs)
69806971
add_path(grouped_rel, (Path *)
@@ -7200,44 +7191,15 @@ create_partial_grouping_paths(PlannerInfo *root,
72007191
foreach(lc, input_rel->pathlist)
72017192
{
72027193
Path *path = (Path *) lfirst(lc);
7203-
bool is_sorted;
7204-
int presorted_keys;
72057194

7206-
is_sorted = pathkeys_count_contained_in(root->group_pathkeys,
7207-
path->pathkeys,
7208-
&presorted_keys);
7209-
if (!is_sorted)
7210-
{
7211-
/*
7212-
* Try at least sorting the cheapest path and also try
7213-
* incrementally sorting any path which is partially sorted
7214-
* already (no need to deal with paths which have presorted
7215-
* keys when incremental sort is disabled unless it's the
7216-
* cheapest input path).
7217-
*/
7218-
if (path != cheapest_total_path &&
7219-
(presorted_keys == 0 || !enable_incremental_sort))
7220-
continue;
7195+
path = make_ordered_path(root,
7196+
partially_grouped_rel,
7197+
path,
7198+
cheapest_total_path,
7199+
root->group_pathkeys);
72217200

7222-
/*
7223-
* We've no need to consider both a sort and incremental sort.
7224-
* We'll just do a sort if there are no presorted keys and an
7225-
* incremental sort when there are presorted keys.
7226-
*/
7227-
if (presorted_keys == 0 || !enable_incremental_sort)
7228-
path = (Path *) create_sort_path(root,
7229-
partially_grouped_rel,
7230-
path,
7231-
root->group_pathkeys,
7232-
-1.0);
7233-
else
7234-
path = (Path *) create_incremental_sort_path(root,
7235-
partially_grouped_rel,
7236-
path,
7237-
root->group_pathkeys,
7238-
presorted_keys,
7239-
-1.0);
7240-
}
7201+
if (path == NULL)
7202+
continue;
72417203

72427204
if (parse->hasAggs)
72437205
add_path(partially_grouped_rel, (Path *)
@@ -7268,45 +7230,15 @@ create_partial_grouping_paths(PlannerInfo *root,
72687230
foreach(lc, input_rel->partial_pathlist)
72697231
{
72707232
Path *path = (Path *) lfirst(lc);
7271-
bool is_sorted;
7272-
int presorted_keys;
7273-
7274-
is_sorted = pathkeys_count_contained_in(root->group_pathkeys,
7275-
path->pathkeys,
7276-
&presorted_keys);
72777233

7278-
if (!is_sorted)
7279-
{
7280-
/*
7281-
* Try at least sorting the cheapest path and also try
7282-
* incrementally sorting any path which is partially sorted
7283-
* already (no need to deal with paths which have presorted
7284-
* keys when incremental sort is disabled unless it's the
7285-
* cheapest input path).
7286-
*/
7287-
if (path != cheapest_partial_path &&
7288-
(presorted_keys == 0 || !enable_incremental_sort))
7289-
continue;
7234+
path = make_ordered_path(root,
7235+
partially_grouped_rel,
7236+
path,
7237+
cheapest_partial_path,
7238+
root->group_pathkeys);
72907239

7291-
/*
7292-
* We've no need to consider both a sort and incremental sort.
7293-
* We'll just do a sort if there are no presorted keys and an
7294-
* incremental sort when there are presorted keys.
7295-
*/
7296-
if (presorted_keys == 0 || !enable_incremental_sort)
7297-
path = (Path *) create_sort_path(root,
7298-
partially_grouped_rel,
7299-
path,
7300-
root->group_pathkeys,
7301-
-1.0);
7302-
else
7303-
path = (Path *) create_incremental_sort_path(root,
7304-
partially_grouped_rel,
7305-
path,
7306-
root->group_pathkeys,
7307-
presorted_keys,
7308-
-1.0);
7309-
}
7240+
if (path == NULL)
7241+
continue;
73107242

73117243
if (parse->hasAggs)
73127244
add_partial_path(partially_grouped_rel, (Path *)

0 commit comments

Comments
 (0)