Skip to content

Commit 5864d6a

Browse files
committed
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.
1 parent 28048cb commit 5864d6a

File tree

4 files changed

+35
-0
lines changed

4 files changed

+35
-0
lines changed

src/backend/optimizer/plan/planner.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ int force_parallel_mode = FORCE_PARALLEL_OFF;
6262
/* Hook for plugins to get control in planner() */
6363
planner_hook_type planner_hook = NULL;
6464

65+
/* Hook for plugins to get control before grouping_planner plans upper rels */
66+
create_upper_paths_hook_type create_upper_paths_hook = NULL;
67+
6568

6669
/* Expression kind codes for preprocess_expression */
6770
#define EXPRKIND_QUAL 0
@@ -459,6 +462,7 @@ subquery_planner(PlannerGlobal *glob, Query *parse,
459462
root->append_rel_list = NIL;
460463
root->rowMarks = NIL;
461464
memset(root->upper_rels, 0, sizeof(root->upper_rels));
465+
memset(root->upper_targets, 0, sizeof(root->upper_targets));
462466
root->processed_tlist = NIL;
463467
root->grouping_map = NULL;
464468
root->minmax_aggs = NIL;
@@ -1736,6 +1740,28 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
17361740
}
17371741
}
17381742

1743+
/*
1744+
* Save the various upper-rel PathTargets we just computed into
1745+
* root->upper_targets[]. The core code doesn't use this, but it
1746+
* provides a convenient place for extensions to get at the info. For
1747+
* consistency, we save all the intermediate targets, even though some
1748+
* of the corresponding upperrels might not be needed for this query.
1749+
*/
1750+
root->upper_targets[UPPERREL_FINAL] = final_target;
1751+
root->upper_targets[UPPERREL_WINDOW] = sort_input_target;
1752+
root->upper_targets[UPPERREL_GROUP_AGG] = grouping_target;
1753+
1754+
/*
1755+
* Let extensions, particularly CustomScan providers, consider
1756+
* injecting extension Paths into the query's upperrels, where they
1757+
* will compete with the Paths we create below. We pass the final
1758+
* scan/join rel because that's not so easily findable from the
1759+
* PlannerInfo struct; anything else the hook wants to know should be
1760+
* obtainable via "root".
1761+
*/
1762+
if (create_upper_paths_hook)
1763+
(*create_upper_paths_hook) (root, current_rel);
1764+
17391765
/*
17401766
* If we have grouping and/or aggregation, consider ways to implement
17411767
* that. We build a new upperrel representing the output of this

src/backend/optimizer/prep/prepjointree.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,7 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte,
909909
subroot->append_rel_list = NIL;
910910
subroot->rowMarks = NIL;
911911
memset(subroot->upper_rels, 0, sizeof(subroot->upper_rels));
912+
memset(subroot->upper_targets, 0, sizeof(subroot->upper_targets));
912913
subroot->processed_tlist = NIL;
913914
subroot->grouping_map = NULL;
914915
subroot->minmax_aggs = NIL;

src/include/nodes/relation.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,9 @@ typedef struct PlannerInfo
263263
/* Use fetch_upper_rel() to get any particular upper rel */
264264
List *upper_rels[UPPERREL_FINAL + 1]; /* upper-rel RelOptInfos */
265265

266+
/* Result tlists chosen by grouping_planner for upper-stage processing */
267+
struct PathTarget *upper_targets[UPPERREL_FINAL + 1];
268+
266269
/*
267270
* grouping_planner passes back its final processed targetlist here, for
268271
* use in relabeling the topmost tlist of the finished Plan.

src/include/optimizer/planner.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ typedef PlannedStmt *(*planner_hook_type) (Query *parse,
2424
ParamListInfo boundParams);
2525
extern PGDLLIMPORT planner_hook_type planner_hook;
2626

27+
/* Hook for plugins to get control before grouping_planner plans upper rels */
28+
typedef void (*create_upper_paths_hook_type) (PlannerInfo *root,
29+
RelOptInfo *scan_join_rel);
30+
extern PGDLLIMPORT create_upper_paths_hook_type create_upper_paths_hook;
31+
2732

2833
extern PlannedStmt *planner(Query *parse, int cursorOptions,
2934
ParamListInfo boundParams);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy