From f63c93a404554f7e48a01ed14661a119ae10b604 Mon Sep 17 00:00:00 2001 From: "Andrei V. Lepikhov" Date: Mon, 30 Sep 2024 13:32:43 +0700 Subject: [PATCH 2/2] Introduce compare_partial_path_hook. By analogy of compare_path_hook, let an extension to alter decisions on accepting new and removing old path. The add_partial_path() routine has different logic. Hence, the hook also differs from non-partial case. Also, move hooks and newly exported functions to paths.h. Do we need to revert it and allow to stay in the pathnode.h? --- src/backend/optimizer/util/pathnode.c | 5 +++++ src/include/optimizer/pathnode.h | 17 ----------------- src/include/optimizer/paths.h | 24 ++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c index ae57932862..5f91ead226 100644 --- a/src/backend/optimizer/util/pathnode.c +++ b/src/backend/optimizer/util/pathnode.c @@ -41,6 +41,7 @@ /* Hook for plugins to get control over the add_path decision */ compare_path_hook_type compare_path_hook = NULL; +compare_partial_path_hook_type compare_partial_path_hook = NULL; static List *translate_sub_tlist(List *tlist, int relid); static int append_total_cost_compare(const ListCell *a, const ListCell *b); @@ -870,6 +871,10 @@ add_partial_path(RelOptInfo *parent_rel, Path *new_path) } } + if (compare_partial_path_hook) + (*compare_partial_path_hook)(parent_rel, new_path, old_path, + &accept_new, &remove_old); + /* * Remove current element from partial_pathlist if dominated by new. */ diff --git a/src/include/optimizer/pathnode.h b/src/include/optimizer/pathnode.h index 4b95d85e1a..1035e6560c 100644 --- a/src/include/optimizer/pathnode.h +++ b/src/include/optimizer/pathnode.h @@ -18,28 +18,11 @@ #include "nodes/pathnodes.h" -typedef enum -{ - COSTS_EQUAL, /* path costs are fuzzily equal */ - COSTS_BETTER1, /* first path is cheaper than second */ - COSTS_BETTER2, /* second path is cheaper than first */ - COSTS_DIFFERENT, /* neither path dominates the other on cost */ -} PathCostComparison; - -/* Hook for plugins to get control when grouping_planner() plans upper rels */ -typedef PathCostComparison (*compare_path_hook_type) (RelOptInfo *parent_rel, - Path *new_path, - Path *old_path, - double fuzz_factor); -extern PGDLLIMPORT compare_path_hook_type compare_path_hook; - /* * prototypes for pathnode.c */ extern int compare_path_costs(Path *path1, Path *path2, CostSelector criterion); -extern PathCostComparison -compare_path_costs_fuzzily(Path *path1, Path *path2, double fuzz_factor); extern int compare_fractional_path_costs(Path *path1, Path *path2, double fraction); extern void set_cheapest(RelOptInfo *parent_rel); diff --git a/src/include/optimizer/paths.h b/src/include/optimizer/paths.h index 54869d4401..47ae26033c 100644 --- a/src/include/optimizer/paths.h +++ b/src/include/optimizer/paths.h @@ -271,4 +271,28 @@ extern PathKey *make_canonical_pathkey(PlannerInfo *root, extern void add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, List *live_childrels); + +typedef enum +{ + COSTS_EQUAL, /* path costs are fuzzily equal */ + COSTS_BETTER1, /* first path is cheaper than second */ + COSTS_BETTER2, /* second path is cheaper than first */ + COSTS_DIFFERENT, /* neither path dominates the other on cost */ +} PathCostComparison; + +extern PathCostComparison compare_path_costs_fuzzily(Path *path1, Path *path2, + double fuzz_factor); +/* Hook for plugins to get control when grouping_planner() plans upper rels */ +typedef PathCostComparison (*compare_path_hook_type) (RelOptInfo *rel, + Path *new_path, + Path *old_path, + double fuzz_factor); +typedef void (*compare_partial_path_hook_type) (RelOptInfo *rel, + Path *new_path, + Path *old_path, + bool *accept_new, + bool *remove_old); +extern PGDLLIMPORT compare_path_hook_type compare_path_hook; +extern PGDLLIMPORT compare_partial_path_hook_type compare_partial_path_hook; + #endif /* PATHS_H */ -- 2.46.2