Provide a planner hook at a suitable place for creating upper-rel Paths.
In the initial revision of the upper-planner pathification work, the only available way for an FDW or custom-scan provider to inject Paths representing post-scan-join processing was to insert them during scan-level GetForeignPaths or similar processing. While that's not impossible, it'd require quite a lot of duplicative processing to look forward and see if the extension would be capable of implementing the whole query. To improve matters for custom-scan providers, provide a hook function at the point where the core code is about to start filling in upperrel Paths. At this point Paths are available for the whole scan/join tree, which should reduce the amount of redundant effort considerably. (An alternative design that was suggested was to provide a separate hook for each post-scan-join processing step, but that seems messy and not clearly more useful.) Following our time-honored tradition, there's no documentation for this hook outside the source code. As-is, this hook is only meant for custom scan providers, which we can't assume very much about. A followon patch will implement an FDW callback to let FDWs do the same thing in a somewhat more structured fashion.
This commit is contained in:
parent
28048cbaa2
commit
5864d6a4b6
@ -62,6 +62,9 @@ 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 */
|
||||
create_upper_paths_hook_type create_upper_paths_hook = NULL;
|
||||
|
||||
|
||||
/* Expression kind codes for preprocess_expression */
|
||||
#define EXPRKIND_QUAL 0
|
||||
@ -459,6 +462,7 @@ subquery_planner(PlannerGlobal *glob, Query *parse,
|
||||
root->append_rel_list = NIL;
|
||||
root->rowMarks = NIL;
|
||||
memset(root->upper_rels, 0, sizeof(root->upper_rels));
|
||||
memset(root->upper_targets, 0, sizeof(root->upper_targets));
|
||||
root->processed_tlist = NIL;
|
||||
root->grouping_map = NULL;
|
||||
root->minmax_aggs = NIL;
|
||||
@ -1736,6 +1740,28 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Save the various upper-rel PathTargets we just computed into
|
||||
* root->upper_targets[]. The core code doesn't use this, but it
|
||||
* provides a convenient place for extensions to get at the info. For
|
||||
* consistency, we save all the intermediate targets, even though some
|
||||
* of the corresponding upperrels might not be needed for this query.
|
||||
*/
|
||||
root->upper_targets[UPPERREL_FINAL] = final_target;
|
||||
root->upper_targets[UPPERREL_WINDOW] = sort_input_target;
|
||||
root->upper_targets[UPPERREL_GROUP_AGG] = grouping_target;
|
||||
|
||||
/*
|
||||
* Let extensions, particularly 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 hook wants to know should be
|
||||
* obtainable via "root".
|
||||
*/
|
||||
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
|
||||
|
@ -909,6 +909,7 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte,
|
||||
subroot->append_rel_list = NIL;
|
||||
subroot->rowMarks = NIL;
|
||||
memset(subroot->upper_rels, 0, sizeof(subroot->upper_rels));
|
||||
memset(subroot->upper_targets, 0, sizeof(subroot->upper_targets));
|
||||
subroot->processed_tlist = NIL;
|
||||
subroot->grouping_map = NULL;
|
||||
subroot->minmax_aggs = NIL;
|
||||
|
@ -263,6 +263,9 @@ typedef struct PlannerInfo
|
||||
/* Use fetch_upper_rel() to get any particular upper rel */
|
||||
List *upper_rels[UPPERREL_FINAL + 1]; /* upper-rel RelOptInfos */
|
||||
|
||||
/* Result tlists chosen by grouping_planner for upper-stage processing */
|
||||
struct PathTarget *upper_targets[UPPERREL_FINAL + 1];
|
||||
|
||||
/*
|
||||
* grouping_planner passes back its final processed targetlist here, for
|
||||
* use in relabeling the topmost tlist of the finished Plan.
|
||||
|
@ -24,6 +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 */
|
||||
typedef void (*create_upper_paths_hook_type) (PlannerInfo *root,
|
||||
RelOptInfo *scan_join_rel);
|
||||
extern PGDLLIMPORT create_upper_paths_hook_type create_upper_paths_hook;
|
||||
|
||||
|
||||
extern PlannedStmt *planner(Query *parse, int cursorOptions,
|
||||
ParamListInfo boundParams);
|
||||
|
Loading…
x
Reference in New Issue
Block a user