@@ -1291,6 +1291,12 @@ inheritance_planner(PlannerInfo *root)
12911291 /* Result path must go into outer query's FINAL upperrel */
12921292 final_rel = fetch_upper_rel (root , UPPERREL_FINAL , NULL );
12931293
1294+ /*
1295+ * We don't currently worry about setting final_rel's consider_parallel
1296+ * flag in this case, nor about allowing FDWs or create_upper_paths_hook
1297+ * to get control here.
1298+ */
1299+
12941300 /*
12951301 * If we managed to exclude every child rel, return a dummy plan; it
12961302 * doesn't even need a ModifyTable node.
@@ -1788,21 +1794,6 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
17881794 root -> upper_targets [UPPERREL_WINDOW ] = sort_input_target ;
17891795 root -> upper_targets [UPPERREL_GROUP_AGG ] = grouping_target ;
17901796
1791- /*
1792- * If there is an FDW that's responsible for the final scan/join rel,
1793- * let it consider injecting extension Paths into the query's
1794- * upperrels, where they will compete with the Paths we create below.
1795- * We pass the final scan/join rel because that's not so easily
1796- * findable from the PlannerInfo struct; anything else the FDW wants
1797- * to know should be obtainable via "root".
1798- *
1799- * Note: CustomScan providers, as well as FDWs that don't want to use
1800- * this hook, can use the create_upper_paths_hook; see below.
1801- */
1802- if (current_rel -> fdwroutine &&
1803- current_rel -> fdwroutine -> GetForeignUpperPaths )
1804- current_rel -> fdwroutine -> GetForeignUpperPaths (root , current_rel );
1805-
18061797 /*
18071798 * If we have grouping and/or aggregation, consider ways to implement
18081799 * that. We build a new upperrel representing the output of this
@@ -1891,9 +1882,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
18911882 }
18921883
18931884 /*
1894- * Now we are prepared to build the final-output upperrel. Insert all
1895- * surviving paths, with LockRows, Limit, and/or ModifyTable steps added
1896- * if needed.
1885+ * Now we are prepared to build the final-output upperrel.
18971886 */
18981887 final_rel = fetch_upper_rel (root , UPPERREL_FINAL , NULL );
18991888
@@ -1910,7 +1899,15 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
19101899 final_rel -> consider_parallel = true;
19111900
19121901 /*
1913- * Generate paths for the final rel.
1902+ * If the current_rel belongs to a single FDW, so does the final_rel.
1903+ */
1904+ final_rel -> serverid = current_rel -> serverid ;
1905+ final_rel -> umid = current_rel -> umid ;
1906+ final_rel -> fdwroutine = current_rel -> fdwroutine ;
1907+
1908+ /*
1909+ * Generate paths for the final_rel. Insert all surviving paths, with
1910+ * LockRows, Limit, and/or ModifyTable steps added if needed.
19141911 */
19151912 foreach (lc , current_rel -> pathlist )
19161913 {
@@ -1994,6 +1991,15 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
19941991 add_path (final_rel , path );
19951992 }
19961993
1994+ /*
1995+ * If there is an FDW that's responsible for all baserels of the query,
1996+ * let it consider adding ForeignPaths.
1997+ */
1998+ if (final_rel -> fdwroutine &&
1999+ final_rel -> fdwroutine -> GetForeignUpperPaths )
2000+ final_rel -> fdwroutine -> GetForeignUpperPaths (root , UPPERREL_FINAL ,
2001+ current_rel , final_rel );
2002+
19972003 /* Let extensions possibly add some more paths */
19982004 if (create_upper_paths_hook )
19992005 (* create_upper_paths_hook ) (root , UPPERREL_FINAL ,
@@ -3268,6 +3274,13 @@ create_grouping_paths(PlannerInfo *root,
32683274 !has_parallel_hazard ((Node * ) parse -> havingQual , false))
32693275 grouped_rel -> consider_parallel = true;
32703276
3277+ /*
3278+ * If the input rel belongs to a single FDW, so does the grouped rel.
3279+ */
3280+ grouped_rel -> serverid = input_rel -> serverid ;
3281+ grouped_rel -> umid = input_rel -> umid ;
3282+ grouped_rel -> fdwroutine = input_rel -> fdwroutine ;
3283+
32713284 /*
32723285 * Check for degenerate grouping.
32733286 */
@@ -3770,6 +3783,15 @@ create_grouping_paths(PlannerInfo *root,
37703783 errmsg ("could not implement GROUP BY" ),
37713784 errdetail ("Some of the datatypes only support hashing, while others only support sorting." )));
37723785
3786+ /*
3787+ * If there is an FDW that's responsible for all baserels of the query,
3788+ * let it consider adding ForeignPaths.
3789+ */
3790+ if (grouped_rel -> fdwroutine &&
3791+ grouped_rel -> fdwroutine -> GetForeignUpperPaths )
3792+ grouped_rel -> fdwroutine -> GetForeignUpperPaths (root , UPPERREL_GROUP_AGG ,
3793+ input_rel , grouped_rel );
3794+
37733795 /* Let extensions possibly add some more paths */
37743796 if (create_upper_paths_hook )
37753797 (* create_upper_paths_hook ) (root , UPPERREL_GROUP_AGG ,
@@ -3820,6 +3842,13 @@ create_window_paths(PlannerInfo *root,
38203842 !has_parallel_hazard ((Node * ) activeWindows , false))
38213843 window_rel -> consider_parallel = true;
38223844
3845+ /*
3846+ * If the input rel belongs to a single FDW, so does the window rel.
3847+ */
3848+ window_rel -> serverid = input_rel -> serverid ;
3849+ window_rel -> umid = input_rel -> umid ;
3850+ window_rel -> fdwroutine = input_rel -> fdwroutine ;
3851+
38233852 /*
38243853 * Consider computing window functions starting from the existing
38253854 * cheapest-total path (which will likely require a sort) as well as any
@@ -3841,6 +3870,15 @@ create_window_paths(PlannerInfo *root,
38413870 activeWindows );
38423871 }
38433872
3873+ /*
3874+ * If there is an FDW that's responsible for all baserels of the query,
3875+ * let it consider adding ForeignPaths.
3876+ */
3877+ if (window_rel -> fdwroutine &&
3878+ window_rel -> fdwroutine -> GetForeignUpperPaths )
3879+ window_rel -> fdwroutine -> GetForeignUpperPaths (root , UPPERREL_WINDOW ,
3880+ input_rel , window_rel );
3881+
38443882 /* Let extensions possibly add some more paths */
38453883 if (create_upper_paths_hook )
38463884 (* create_upper_paths_hook ) (root , UPPERREL_WINDOW ,
@@ -3984,6 +4022,13 @@ create_distinct_paths(PlannerInfo *root,
39844022 */
39854023 distinct_rel -> consider_parallel = input_rel -> consider_parallel ;
39864024
4025+ /*
4026+ * If the input rel belongs to a single FDW, so does the distinct_rel.
4027+ */
4028+ distinct_rel -> serverid = input_rel -> serverid ;
4029+ distinct_rel -> umid = input_rel -> umid ;
4030+ distinct_rel -> fdwroutine = input_rel -> fdwroutine ;
4031+
39874032 /* Estimate number of distinct rows there will be */
39884033 if (parse -> groupClause || parse -> groupingSets || parse -> hasAggs ||
39894034 root -> hasHavingQual )
@@ -4129,6 +4174,15 @@ create_distinct_paths(PlannerInfo *root,
41294174 errmsg ("could not implement DISTINCT" ),
41304175 errdetail ("Some of the datatypes only support hashing, while others only support sorting." )));
41314176
4177+ /*
4178+ * If there is an FDW that's responsible for all baserels of the query,
4179+ * let it consider adding ForeignPaths.
4180+ */
4181+ if (distinct_rel -> fdwroutine &&
4182+ distinct_rel -> fdwroutine -> GetForeignUpperPaths )
4183+ distinct_rel -> fdwroutine -> GetForeignUpperPaths (root , UPPERREL_DISTINCT ,
4184+ input_rel , distinct_rel );
4185+
41324186 /* Let extensions possibly add some more paths */
41334187 if (create_upper_paths_hook )
41344188 (* create_upper_paths_hook ) (root , UPPERREL_DISTINCT ,
@@ -4176,6 +4230,13 @@ create_ordered_paths(PlannerInfo *root,
41764230 !has_parallel_hazard ((Node * ) target -> exprs , false))
41774231 ordered_rel -> consider_parallel = true;
41784232
4233+ /*
4234+ * If the input rel belongs to a single FDW, so does the ordered_rel.
4235+ */
4236+ ordered_rel -> serverid = input_rel -> serverid ;
4237+ ordered_rel -> umid = input_rel -> umid ;
4238+ ordered_rel -> fdwroutine = input_rel -> fdwroutine ;
4239+
41794240 foreach (lc , input_rel -> pathlist )
41804241 {
41814242 Path * path = (Path * ) lfirst (lc );
@@ -4204,6 +4265,15 @@ create_ordered_paths(PlannerInfo *root,
42044265 }
42054266 }
42064267
4268+ /*
4269+ * If there is an FDW that's responsible for all baserels of the query,
4270+ * let it consider adding ForeignPaths.
4271+ */
4272+ if (ordered_rel -> fdwroutine &&
4273+ ordered_rel -> fdwroutine -> GetForeignUpperPaths )
4274+ ordered_rel -> fdwroutine -> GetForeignUpperPaths (root , UPPERREL_ORDERED ,
4275+ input_rel , ordered_rel );
4276+
42074277 /* Let extensions possibly add some more paths */
42084278 if (create_upper_paths_hook )
42094279 (* create_upper_paths_hook ) (root , UPPERREL_ORDERED ,
0 commit comments