From 7448db6787c51f19c34a1c0f3efdcf288315d3f1 Mon Sep 17 00:00:00 2001 From: Nikita Malakhov Date: Sun, 13 Oct 2024 10:08:17 +0300 Subject: [PATCH] add_paths_to_append_rel() has to consider fractional paths while calculating the cheapest one. When add_paths_to_append_rel evaluates path costs if tuple_fraction has valid value (it has fractional paths) fractional paths costs should be taken into account while searching for the cheapest one. Author: Andrei Lepikhov --- src/backend/optimizer/path/allpaths.c | 15 +++++++++++++-- src/backend/optimizer/plan/planner.c | 24 ++++++++++++++++++++++-- src/include/optimizer/planner.h | 4 ++++ 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 172edb643a..9976907d3a 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -1364,9 +1364,20 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, */ if (rel->consider_startup && childrel->cheapest_startup_path != NULL) { + Path *cheapest_path; + + if (root->tuple_fraction > 0.0) + { + cheapest_path = + get_cheapest_fractional_path_ext(childrel, + root->tuple_fraction, true); + } + else + cheapest_path = childrel->cheapest_startup_path; + /* cheapest_startup_path must not be a parameterized path. */ - Assert(childrel->cheapest_startup_path->param_info == NULL); - accumulate_append_subpath(childrel->cheapest_startup_path, + Assert(cheapest_path->param_info == NULL); + accumulate_append_subpath(cheapest_path, &startup_subpaths, NULL); } diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index 0f423e9684..3c81614141 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -6517,16 +6517,17 @@ make_sort_input_target(PlannerInfo *root, } /* - * get_cheapest_fractional_path + * get_cheapest_fractional_path_ext * Find the cheapest path for retrieving a specified fraction of all * the tuples expected to be returned by the given relation. + * If nonparameterized is set, return only non-parameterized paths * * We interpret tuple_fraction the same way as grouping_planner. * * We assume set_cheapest() has been run on the given rel. */ Path * -get_cheapest_fractional_path(RelOptInfo *rel, double tuple_fraction) +get_cheapest_fractional_path_ext(RelOptInfo *rel, double tuple_fraction, bool nonparameterized) { Path *best_path = rel->cheapest_total_path; ListCell *l; @@ -6543,6 +6544,10 @@ get_cheapest_fractional_path(RelOptInfo *rel, double tuple_fraction) { Path *path = (Path *) lfirst(l); + /* Skip parameterized paths if requested */ + if (nonparameterized && path->param_info) + continue; + if (path == rel->cheapest_total_path || compare_fractional_path_costs(best_path, path, tuple_fraction) <= 0) continue; @@ -6553,6 +6558,21 @@ get_cheapest_fractional_path(RelOptInfo *rel, double tuple_fraction) return best_path; } +/* + * get_cheapest_fractional_path + * Find the cheapest path for retrieving a specified fraction of all + * the tuples expected to be returned by the given relation. + * + * We interpret tuple_fraction the same way as grouping_planner. + * + * We assume set_cheapest() has been run on the given rel. + */ +Path * +get_cheapest_fractional_path(RelOptInfo *rel, double tuple_fraction) +{ + return get_cheapest_fractional_path_ext(rel, tuple_fraction, false); +} + /* * adjust_paths_for_srfs * Fix up the Paths of the given upperrel to handle tSRFs properly. diff --git a/src/include/optimizer/planner.h b/src/include/optimizer/planner.h index 5aeff21b96..6d033d367f 100644 --- a/src/include/optimizer/planner.h +++ b/src/include/optimizer/planner.h @@ -57,6 +57,10 @@ extern void mark_partial_aggref(Aggref *agg, AggSplit aggsplit); extern Path *get_cheapest_fractional_path(RelOptInfo *rel, double tuple_fraction); +extern Path *get_cheapest_fractional_path_ext(RelOptInfo *rel, + double tuple_fraction, + bool nonparameterized); + extern Expr *preprocess_phv_expression(PlannerInfo *root, Expr *expr); #endif /* PLANNER_H */ -- 2.25.1