@@ -1291,6 +1291,12 @@ inheritance_planner(PlannerInfo *root)
1291
1291
/* Result path must go into outer query's FINAL upperrel */
1292
1292
final_rel = fetch_upper_rel (root , UPPERREL_FINAL , NULL );
1293
1293
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
+
1294
1300
/*
1295
1301
* If we managed to exclude every child rel, return a dummy plan; it
1296
1302
* doesn't even need a ModifyTable node.
@@ -1788,21 +1794,6 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
1788
1794
root -> upper_targets [UPPERREL_WINDOW ] = sort_input_target ;
1789
1795
root -> upper_targets [UPPERREL_GROUP_AGG ] = grouping_target ;
1790
1796
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
-
1806
1797
/*
1807
1798
* If we have grouping and/or aggregation, consider ways to implement
1808
1799
* that. We build a new upperrel representing the output of this
@@ -1891,9 +1882,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
1891
1882
}
1892
1883
1893
1884
/*
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.
1897
1886
*/
1898
1887
final_rel = fetch_upper_rel (root , UPPERREL_FINAL , NULL );
1899
1888
@@ -1910,7 +1899,15 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
1910
1899
final_rel -> consider_parallel = true;
1911
1900
1912
1901
/*
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.
1914
1911
*/
1915
1912
foreach (lc , current_rel -> pathlist )
1916
1913
{
@@ -1994,6 +1991,15 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
1994
1991
add_path (final_rel , path );
1995
1992
}
1996
1993
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
+
1997
2003
/* Let extensions possibly add some more paths */
1998
2004
if (create_upper_paths_hook )
1999
2005
(* create_upper_paths_hook ) (root , UPPERREL_FINAL ,
@@ -3268,6 +3274,13 @@ create_grouping_paths(PlannerInfo *root,
3268
3274
!has_parallel_hazard ((Node * ) parse -> havingQual , false))
3269
3275
grouped_rel -> consider_parallel = true;
3270
3276
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
+
3271
3284
/*
3272
3285
* Check for degenerate grouping.
3273
3286
*/
@@ -3770,6 +3783,15 @@ create_grouping_paths(PlannerInfo *root,
3770
3783
errmsg ("could not implement GROUP BY" ),
3771
3784
errdetail ("Some of the datatypes only support hashing, while others only support sorting." )));
3772
3785
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
+
3773
3795
/* Let extensions possibly add some more paths */
3774
3796
if (create_upper_paths_hook )
3775
3797
(* create_upper_paths_hook ) (root , UPPERREL_GROUP_AGG ,
@@ -3820,6 +3842,13 @@ create_window_paths(PlannerInfo *root,
3820
3842
!has_parallel_hazard ((Node * ) activeWindows , false))
3821
3843
window_rel -> consider_parallel = true;
3822
3844
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
+
3823
3852
/*
3824
3853
* Consider computing window functions starting from the existing
3825
3854
* cheapest-total path (which will likely require a sort) as well as any
@@ -3841,6 +3870,15 @@ create_window_paths(PlannerInfo *root,
3841
3870
activeWindows );
3842
3871
}
3843
3872
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
+
3844
3882
/* Let extensions possibly add some more paths */
3845
3883
if (create_upper_paths_hook )
3846
3884
(* create_upper_paths_hook ) (root , UPPERREL_WINDOW ,
@@ -3984,6 +4022,13 @@ create_distinct_paths(PlannerInfo *root,
3984
4022
*/
3985
4023
distinct_rel -> consider_parallel = input_rel -> consider_parallel ;
3986
4024
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
+
3987
4032
/* Estimate number of distinct rows there will be */
3988
4033
if (parse -> groupClause || parse -> groupingSets || parse -> hasAggs ||
3989
4034
root -> hasHavingQual )
@@ -4129,6 +4174,15 @@ create_distinct_paths(PlannerInfo *root,
4129
4174
errmsg ("could not implement DISTINCT" ),
4130
4175
errdetail ("Some of the datatypes only support hashing, while others only support sorting." )));
4131
4176
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
+
4132
4186
/* Let extensions possibly add some more paths */
4133
4187
if (create_upper_paths_hook )
4134
4188
(* create_upper_paths_hook ) (root , UPPERREL_DISTINCT ,
@@ -4176,6 +4230,13 @@ create_ordered_paths(PlannerInfo *root,
4176
4230
!has_parallel_hazard ((Node * ) target -> exprs , false))
4177
4231
ordered_rel -> consider_parallel = true;
4178
4232
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
+
4179
4240
foreach (lc , input_rel -> pathlist )
4180
4241
{
4181
4242
Path * path = (Path * ) lfirst (lc );
@@ -4204,6 +4265,15 @@ create_ordered_paths(PlannerInfo *root,
4204
4265
}
4205
4266
}
4206
4267
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
+
4207
4277
/* Let extensions possibly add some more paths */
4208
4278
if (create_upper_paths_hook )
4209
4279
(* create_upper_paths_hook ) (root , UPPERREL_ORDERED ,
0 commit comments