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;
/* Hook for plugins to get control in planner() */
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;
......@@ -1772,20 +1772,20 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
root->upper_targets[UPPERREL_GROUP_AGG] = grouping_target;
/*
* Let extensions, particularly FDWs and CustomScan providers,
* consider injecting extension Paths into the query's upperrels,
* where they will compete with the Paths we create below. We pass
* the final scan/join rel because that's not so easily findable from
* the PlannerInfo struct; anything else the hooks want to know should
* be obtainable via "root".
* If there is an FDW that's responsible for the final scan/join rel,
* let it consider injecting extension Paths into the query's
* upperrels, where they will compete with the Paths we create below.
* We pass the final scan/join rel because that's not so easily
* findable from the PlannerInfo struct; anything else the FDW wants
* 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 &&
current_rel->fdwroutine->GetForeignUpperPaths)
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
* that. We build a new upperrel representing the output of this
......@@ -1962,6 +1962,11 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
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() */
}
......@@ -3724,6 +3729,11 @@ create_grouping_paths(PlannerInfo *root,
errmsg("could not implement GROUP BY"),
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) */
set_cheapest(grouped_rel);
......@@ -3780,6 +3790,11 @@ create_window_paths(PlannerInfo *root,
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) */
set_cheapest(window_rel);
......@@ -4056,6 +4071,11 @@ create_distinct_paths(PlannerInfo *root,
errmsg("could not implement DISTINCT"),
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) */
set_cheapest(distinct_rel);
......@@ -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
* need us to do it.
......
......@@ -206,7 +206,12 @@ plan_set_operations(PlannerInfo *root)
/* Add only the final path to the SETOP upperrel. */
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);
return setop_rel;
......
......@@ -24,9 +24,11 @@ typedef PlannedStmt *(*planner_hook_type) (Query *parse,
ParamListInfo boundParams);
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,
RelOptInfo *scan_join_rel);
UpperRelationKind stage,
RelOptInfo *input_rel,
RelOptInfo *output_rel);
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