From 9e703987a8a1961af8edd751169a8ae1055890eb Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 1 Jul 2016 13:12:34 -0400 Subject: Rethink the GetForeignUpperPaths API (again). In the previous design, the GetForeignUpperPaths FDW callback hook was called before we got around to labeling upper relations with the proper consider_parallel flag; this meant that any upper paths created by an FDW would be marked not-parallel-safe. While that's probably just as well right now, we aren't going to want it to be true forever. Hence, abandon the idea that FDWs should be allowed to inject upper paths before the core code has gotten around to creating the relevant upper relation. (Well, actually they still can, but it's on their own heads how well it works.) Instead, adopt the same API already designed for create_upper_paths_hook: we call GetForeignUpperPaths after each upperrel has been created and populated with the paths the core planner knows how to make. --- doc/src/sgml/fdwhandler.sgml | 55 ++++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 20 deletions(-) (limited to 'doc/src') diff --git a/doc/src/sgml/fdwhandler.sgml b/doc/src/sgml/fdwhandler.sgml index 5c40168ce85..455eef64af4 100644 --- a/doc/src/sgml/fdwhandler.sgml +++ b/doc/src/sgml/fdwhandler.sgml @@ -357,7 +357,9 @@ GetForeignJoinPaths (PlannerInfo *root, void GetForeignUpperPaths (PlannerInfo *root, - RelOptInfo *scan_join_rel); + UpperRelationKind stage, + RelOptInfo *input_rel, + RelOptInfo *output_rel); Create possible access paths for upper relation processing, which is the planner's term for all post-scan/join query processing, such @@ -365,11 +367,24 @@ GetForeignUpperPaths (PlannerInfo *root, optional function is called during query planning. Currently, it is called only if all base relation(s) involved in the query belong to the same FDW. This function should generate ForeignPath - path(s) for the steps that the FDW knows how to perform remotely, and - call add_path to add these paths to the appropriate upper - relation. As with GetForeignJoinPaths, it is not necessary - that this function succeed in creating any paths, since paths involving - local processing are always possible. + path(s) for any post-scan/join processing that the FDW knows how to + perform remotely, and call add_path to add these paths to + the indicated upper relation. As with GetForeignJoinPaths, + it is not necessary that this function succeed in creating any paths, + since paths involving local processing are always possible. + + + + The stage parameter identifies which post-scan/join step is + currently being considered. output_rel is the upper relation + that should receive paths representing computation of this step, + and input_rel is the relation representing the input to this + step. (Note that ForeignPath paths added + to output_rel would typically not have any direct dependency + on paths of the input_rel, since their processing is expected + to be done externally. However, examining paths previously generated for + the previous processing step can be useful to avoid redundant planning + work.) @@ -1530,20 +1545,20 @@ GetForeignServerByName(const char *name, bool missing_ok); An FDW might additionally support direct execution of some plan actions that are above the level of scans and joins, such as grouping or - aggregation. To offer such options, the FDW should generate paths - and insert them into the - appropriate upper relation. For example, a path - representing remote aggregation should be inserted into the relation - obtained from fetch_upper_rel(root, UPPERREL_GROUP_AGG, - NULL), using add_path. This path will be compared on a - cost basis with local aggregation performed by reading a simple scan path - for the foreign relation (note that such a path must also be supplied, - else there will be an error at plan time). If the remote-aggregation - path wins, which it usually would, it will be converted into a plan in - the usual way, by calling GetForeignPlan. - Usually the most convenient place to generate such paths is in - the GetForeignUpperPaths callback function, although - it can be done earlier if that seems appropriate. + aggregation. To offer such options, the FDW should generate paths and + insert them into the appropriate upper relation. For + example, a path representing remote aggregation should be inserted into + the UPPERREL_GROUP_AGG relation, using add_path. + This path will be compared on a cost basis with local aggregation + performed by reading a simple scan path for the foreign relation (note + that such a path must also be supplied, else there will be an error at + plan time). If the remote-aggregation path wins, which it usually would, + it will be converted into a plan in the usual way, by + calling GetForeignPlan. The recommended place to generate + such paths is in the GetForeignUpperPaths + callback function, which is called for each upper relation (i.e., each + post-scan/join processing step), if all the base relations of the query + come from the same FDW. -- cgit v1.2.3