Skip to content

Commit a71f101

Browse files
committed
Preparatory refactoring for parallel merge join support.
Extract the logic used by hash_inner_and_outer into a separate function, get_cheapest_parallel_safe_total_inner, so that it can also be used to plan parallel merge joins. Also, add a require_parallel_safe argument to the existing function get_cheapest_path_for_pathkeys, because parallel merge join needs to find the cheapest path for a given set of pathkeys that is parallel-safe, not just the cheapest one overall. Patch by me, reviewed by Dilip Kumar. Discussion: http://postgr.es/m/CA+TgmoYOv+dFK0MWW6366dFj_xTnohQfoBDrHyB7d1oZhrgPjA@mail.gmail.com
1 parent 655393a commit a71f101

File tree

4 files changed

+43
-22
lines changed

4 files changed

+43
-22
lines changed

src/backend/optimizer/path/allpaths.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1447,12 +1447,14 @@ generate_mergeappend_paths(PlannerInfo *root, RelOptInfo *rel,
14471447
get_cheapest_path_for_pathkeys(childrel->pathlist,
14481448
pathkeys,
14491449
NULL,
1450-
STARTUP_COST);
1450+
STARTUP_COST,
1451+
false);
14511452
cheapest_total =
14521453
get_cheapest_path_for_pathkeys(childrel->pathlist,
14531454
pathkeys,
14541455
NULL,
1455-
TOTAL_COST);
1456+
TOTAL_COST,
1457+
false);
14561458

14571459
/*
14581460
* If we can't find any paths with the right order just use the
@@ -1517,7 +1519,8 @@ get_cheapest_parameterized_child_path(PlannerInfo *root, RelOptInfo *rel,
15171519
cheapest = get_cheapest_path_for_pathkeys(rel->pathlist,
15181520
NIL,
15191521
required_outer,
1520-
TOTAL_COST);
1522+
TOTAL_COST,
1523+
false);
15211524
Assert(cheapest != NULL);
15221525
if (bms_equal(PATH_REQ_OUTER(cheapest), required_outer))
15231526
return cheapest;

src/backend/optimizer/path/joinpath.c

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -936,7 +936,8 @@ generate_mergejoin_paths(PlannerInfo *root,
936936
innerpath = get_cheapest_path_for_pathkeys(innerrel->pathlist,
937937
trialsortkeys,
938938
NULL,
939-
TOTAL_COST);
939+
TOTAL_COST,
940+
false);
940941
if (innerpath != NULL &&
941942
(cheapest_total_inner == NULL ||
942943
compare_path_costs(innerpath, cheapest_total_inner,
@@ -971,7 +972,8 @@ generate_mergejoin_paths(PlannerInfo *root,
971972
innerpath = get_cheapest_path_for_pathkeys(innerrel->pathlist,
972973
trialsortkeys,
973974
NULL,
974-
STARTUP_COST);
975+
STARTUP_COST,
976+
false);
975977
if (innerpath != NULL &&
976978
(cheapest_startup_inner == NULL ||
977979
compare_path_costs(innerpath, cheapest_startup_inner,
@@ -1517,21 +1519,8 @@ hash_inner_and_outer(PlannerInfo *root,
15171519
if (cheapest_total_inner->parallel_safe)
15181520
cheapest_safe_inner = cheapest_total_inner;
15191521
else if (save_jointype != JOIN_UNIQUE_INNER)
1520-
{
1521-
ListCell *lc;
1522-
1523-
foreach(lc, innerrel->pathlist)
1524-
{
1525-
Path *innerpath = (Path *) lfirst(lc);
1526-
1527-
if (innerpath->parallel_safe &&
1528-
bms_is_empty(PATH_REQ_OUTER(innerpath)))
1529-
{
1530-
cheapest_safe_inner = innerpath;
1531-
break;
1532-
}
1533-
}
1534-
}
1522+
cheapest_safe_inner =
1523+
get_cheapest_parallel_safe_total_inner(innerrel->pathlist);
15351524

15361525
if (cheapest_safe_inner != NULL)
15371526
try_partial_hashjoin_path(root, joinrel,

src/backend/optimizer/path/pathkeys.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,11 +337,13 @@ pathkeys_contained_in(List *keys1, List *keys2)
337337
* 'pathkeys' represents a required ordering (in canonical form!)
338338
* 'required_outer' denotes allowable outer relations for parameterized paths
339339
* 'cost_criterion' is STARTUP_COST or TOTAL_COST
340+
* 'require_parallel_safe' causes us to consider only parallel-safe paths
340341
*/
341342
Path *
342343
get_cheapest_path_for_pathkeys(List *paths, List *pathkeys,
343344
Relids required_outer,
344-
CostSelector cost_criterion)
345+
CostSelector cost_criterion,
346+
bool require_parallel_safe)
345347
{
346348
Path *matched_path = NULL;
347349
ListCell *l;
@@ -358,6 +360,9 @@ get_cheapest_path_for_pathkeys(List *paths, List *pathkeys,
358360
compare_path_costs(matched_path, path, cost_criterion) <= 0)
359361
continue;
360362

363+
if (require_parallel_safe && !path->parallel_safe)
364+
continue;
365+
361366
if (pathkeys_contained_in(pathkeys, path->pathkeys) &&
362367
bms_is_subset(PATH_REQ_OUTER(path), required_outer))
363368
matched_path = path;
@@ -407,6 +412,28 @@ get_cheapest_fractional_path_for_pathkeys(List *paths,
407412
return matched_path;
408413
}
409414

415+
416+
/*
417+
* get_cheapest_parallel_safe_total_inner
418+
* Find the unparameterized parallel-safe path with the least total cost.
419+
*/
420+
Path *
421+
get_cheapest_parallel_safe_total_inner(List *paths)
422+
{
423+
ListCell *l;
424+
425+
foreach(l, paths)
426+
{
427+
Path *innerpath = (Path *) lfirst(l);
428+
429+
if (innerpath->parallel_safe &&
430+
bms_is_empty(PATH_REQ_OUTER(innerpath)))
431+
return innerpath;
432+
}
433+
434+
return NULL;
435+
}
436+
410437
/****************************************************************************
411438
* NEW PATHKEY FORMATION
412439
****************************************************************************/

src/include/optimizer/paths.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,11 +182,13 @@ extern PathKeysComparison compare_pathkeys(List *keys1, List *keys2);
182182
extern bool pathkeys_contained_in(List *keys1, List *keys2);
183183
extern Path *get_cheapest_path_for_pathkeys(List *paths, List *pathkeys,
184184
Relids required_outer,
185-
CostSelector cost_criterion);
185+
CostSelector cost_criterion,
186+
bool require_parallel_safe);
186187
extern Path *get_cheapest_fractional_path_for_pathkeys(List *paths,
187188
List *pathkeys,
188189
Relids required_outer,
189190
double fraction);
191+
extern Path *get_cheapest_parallel_safe_total_inner(List *paths);
190192
extern List *build_index_pathkeys(PlannerInfo *root, IndexOptInfo *index,
191193
ScanDirection scandir);
192194
extern List *build_expression_pathkey(PlannerInfo *root, Expr *expr,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy