diff options
author | Robert Haas <rhaas@postgresql.org> | 2015-05-01 08:50:35 -0400 |
---|---|---|
committer | Robert Haas <rhaas@postgresql.org> | 2015-05-01 08:50:35 -0400 |
commit | e7cb7ee14555cc9c5773e2c102efd6371f6f2005 (patch) | |
tree | fc1d7ab49a9f9eee6027a6ace17c37963e514cc9 /src/backend/optimizer/path/joinpath.c | |
parent | 2b22795b32576fa7173b501b646581a17de35902 (diff) |
Allow FDWs and custom scan providers to replace joins with scans.
Foreign data wrappers can use this capability for so-called "join
pushdown"; that is, instead of executing two separate foreign scans
and then joining the results locally, they can generate a path which
performs the join on the remote server and then is scanned locally.
This commit does not extend postgres_fdw to take advantage of this
capability; it just provides the infrastructure.
Custom scan providers can use this in a similar way. Previously,
it was only possible for a custom scan provider to scan a single
relation. Now, it can scan an entire join tree, provided of course
that it knows how to produce the same results that the join would
have produced if executed normally.
KaiGai Kohei, reviewed by Shigeru Hanada, Ashutosh Bapat, and me.
Diffstat (limited to 'src/backend/optimizer/path/joinpath.c')
-rw-r--r-- | src/backend/optimizer/path/joinpath.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c index 1da953f6d33..dabef3c3c7f 100644 --- a/src/backend/optimizer/path/joinpath.c +++ b/src/backend/optimizer/path/joinpath.c @@ -17,10 +17,13 @@ #include <math.h> #include "executor/executor.h" +#include "foreign/fdwapi.h" #include "optimizer/cost.h" #include "optimizer/pathnode.h" #include "optimizer/paths.h" +/* Hook for plugins to get control in add_paths_to_joinrel() */ +set_join_pathlist_hook_type set_join_pathlist_hook = NULL; #define PATH_PARAM_BY_REL(path, rel) \ ((path)->param_info && bms_overlap(PATH_REQ_OUTER(path), (rel)->relids)) @@ -260,6 +263,27 @@ add_paths_to_joinrel(PlannerInfo *root, restrictlist, jointype, sjinfo, &semifactors, param_source_rels, extra_lateral_rels); + + /* + * 5. If both inner and outer relations are managed by the same FDW, + * give it a chance to push down joins. + */ + if (joinrel->fdwroutine && + joinrel->fdwroutine->GetForeignJoinPaths) + joinrel->fdwroutine->GetForeignJoinPaths(root, joinrel, + outerrel, innerrel, + restrictlist, jointype, sjinfo, + &semifactors, + param_source_rels, + extra_lateral_rels); + /* + * 6. Finally, give extensions a chance to manipulate the path list. + */ + if (set_join_pathlist_hook) + set_join_pathlist_hook(root, joinrel, outerrel, innerrel, + restrictlist, jointype, + sjinfo, &semifactors, + param_source_rels, extra_lateral_rels); } /* |