Commit f1f01de1 authored by Tom Lane's avatar Tom Lane

Redefine create_upper_paths_hook as being invoked once per upper relation.

Per discussion, this gives potential users of the hook more flexibility,
because they can build custom Paths that implement only one stage of
upper processing atop core-provided Paths for earlier stages.
parent 7a5f8b5c
...@@ -62,7 +62,7 @@ int force_parallel_mode = FORCE_PARALLEL_OFF; ...@@ -62,7 +62,7 @@ int force_parallel_mode = FORCE_PARALLEL_OFF;
/* Hook for plugins to get control in planner() */ /* Hook for plugins to get control in planner() */
planner_hook_type planner_hook = NULL; planner_hook_type planner_hook = NULL;
/* Hook for plugins to get control before grouping_planner plans upper rels */ /* Hook for plugins to get control when grouping_planner() plans upper rels */
create_upper_paths_hook_type create_upper_paths_hook = NULL; create_upper_paths_hook_type create_upper_paths_hook = NULL;
...@@ -1772,20 +1772,20 @@ grouping_planner(PlannerInfo *root, bool inheritance_update, ...@@ -1772,20 +1772,20 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
root->upper_targets[UPPERREL_GROUP_AGG] = grouping_target; root->upper_targets[UPPERREL_GROUP_AGG] = grouping_target;
/* /*
* Let extensions, particularly FDWs and CustomScan providers, * If there is an FDW that's responsible for the final scan/join rel,
* consider injecting extension Paths into the query's upperrels, * let it consider injecting extension Paths into the query's
* where they will compete with the Paths we create below. We pass * upperrels, where they will compete with the Paths we create below.
* the final scan/join rel because that's not so easily findable from * We pass the final scan/join rel because that's not so easily
* the PlannerInfo struct; anything else the hooks want to know should * findable from the PlannerInfo struct; anything else the FDW wants
* be obtainable via "root". * to know should be obtainable via "root".
*
* Note: CustomScan providers, as well as FDWs that don't want to
* use this hook, can use the create_upper_paths_hook; see below.
*/ */
if (current_rel->fdwroutine && if (current_rel->fdwroutine &&
current_rel->fdwroutine->GetForeignUpperPaths) current_rel->fdwroutine->GetForeignUpperPaths)
current_rel->fdwroutine->GetForeignUpperPaths(root, current_rel); current_rel->fdwroutine->GetForeignUpperPaths(root, current_rel);
if (create_upper_paths_hook)
(*create_upper_paths_hook) (root, current_rel);
/* /*
* If we have grouping and/or aggregation, consider ways to implement * If we have grouping and/or aggregation, consider ways to implement
* that. We build a new upperrel representing the output of this * that. We build a new upperrel representing the output of this
...@@ -1962,6 +1962,11 @@ grouping_planner(PlannerInfo *root, bool inheritance_update, ...@@ -1962,6 +1962,11 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
add_path(final_rel, path); add_path(final_rel, path);
} }
/* Let extensions possibly add some more paths */
if (create_upper_paths_hook)
(*create_upper_paths_hook) (root, UPPERREL_FINAL,
current_rel, final_rel);
/* Note: currently, we leave it to callers to do set_cheapest() */ /* Note: currently, we leave it to callers to do set_cheapest() */
} }
...@@ -3724,6 +3729,11 @@ create_grouping_paths(PlannerInfo *root, ...@@ -3724,6 +3729,11 @@ create_grouping_paths(PlannerInfo *root,
errmsg("could not implement GROUP BY"), errmsg("could not implement GROUP BY"),
errdetail("Some of the datatypes only support hashing, while others only support sorting."))); errdetail("Some of the datatypes only support hashing, while others only support sorting.")));
/* Let extensions possibly add some more paths */
if (create_upper_paths_hook)
(*create_upper_paths_hook) (root, UPPERREL_GROUP_AGG,
input_rel, grouped_rel);
/* Now choose the best path(s) */ /* Now choose the best path(s) */
set_cheapest(grouped_rel); set_cheapest(grouped_rel);
...@@ -3780,6 +3790,11 @@ create_window_paths(PlannerInfo *root, ...@@ -3780,6 +3790,11 @@ create_window_paths(PlannerInfo *root,
activeWindows); activeWindows);
} }
/* Let extensions possibly add some more paths */
if (create_upper_paths_hook)
(*create_upper_paths_hook) (root, UPPERREL_WINDOW,
input_rel, window_rel);
/* Now choose the best path(s) */ /* Now choose the best path(s) */
set_cheapest(window_rel); set_cheapest(window_rel);
...@@ -4056,6 +4071,11 @@ create_distinct_paths(PlannerInfo *root, ...@@ -4056,6 +4071,11 @@ create_distinct_paths(PlannerInfo *root,
errmsg("could not implement DISTINCT"), errmsg("could not implement DISTINCT"),
errdetail("Some of the datatypes only support hashing, while others only support sorting."))); errdetail("Some of the datatypes only support hashing, while others only support sorting.")));
/* Let extensions possibly add some more paths */
if (create_upper_paths_hook)
(*create_upper_paths_hook) (root, UPPERREL_DISTINCT,
input_rel, distinct_rel);
/* Now choose the best path(s) */ /* Now choose the best path(s) */
set_cheapest(distinct_rel); set_cheapest(distinct_rel);
...@@ -4117,6 +4137,11 @@ create_ordered_paths(PlannerInfo *root, ...@@ -4117,6 +4137,11 @@ create_ordered_paths(PlannerInfo *root,
} }
} }
/* Let extensions possibly add some more paths */
if (create_upper_paths_hook)
(*create_upper_paths_hook) (root, UPPERREL_ORDERED,
input_rel, ordered_rel);
/* /*
* No need to bother with set_cheapest here; grouping_planner does not * No need to bother with set_cheapest here; grouping_planner does not
* need us to do it. * need us to do it.
......
...@@ -206,7 +206,12 @@ plan_set_operations(PlannerInfo *root) ...@@ -206,7 +206,12 @@ plan_set_operations(PlannerInfo *root)
/* Add only the final path to the SETOP upperrel. */ /* Add only the final path to the SETOP upperrel. */
add_path(setop_rel, path); add_path(setop_rel, path);
/* Select cheapest path (pretty easy at the moment) */ /* Let extensions possibly add some more paths */
if (create_upper_paths_hook)
(*create_upper_paths_hook) (root, UPPERREL_SETOP,
NULL, setop_rel);
/* Select cheapest path */
set_cheapest(setop_rel); set_cheapest(setop_rel);
return setop_rel; return setop_rel;
......
...@@ -24,9 +24,11 @@ typedef PlannedStmt *(*planner_hook_type) (Query *parse, ...@@ -24,9 +24,11 @@ typedef PlannedStmt *(*planner_hook_type) (Query *parse,
ParamListInfo boundParams); ParamListInfo boundParams);
extern PGDLLIMPORT planner_hook_type planner_hook; extern PGDLLIMPORT planner_hook_type planner_hook;
/* Hook for plugins to get control before grouping_planner plans upper rels */ /* Hook for plugins to get control when grouping_planner() plans upper rels */
typedef void (*create_upper_paths_hook_type) (PlannerInfo *root, typedef void (*create_upper_paths_hook_type) (PlannerInfo *root,
RelOptInfo *scan_join_rel); UpperRelationKind stage,
RelOptInfo *input_rel,
RelOptInfo *output_rel);
extern PGDLLIMPORT create_upper_paths_hook_type create_upper_paths_hook; extern PGDLLIMPORT create_upper_paths_hook_type create_upper_paths_hook;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment