diff options
Diffstat (limited to 'src/backend/optimizer')
-rw-r--r-- | src/backend/optimizer/path/joinpath.c | 19 | ||||
-rw-r--r-- | src/backend/optimizer/plan/createplan.c | 21 | ||||
-rw-r--r-- | src/backend/optimizer/util/pathnode.c | 10 | ||||
-rw-r--r-- | src/backend/optimizer/util/restrictinfo.c | 30 |
4 files changed, 32 insertions, 48 deletions
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c index 059e605e04e..821d282497b 100644 --- a/src/backend/optimizer/path/joinpath.c +++ b/src/backend/optimizer/path/joinpath.c @@ -24,7 +24,6 @@ #include "optimizer/pathnode.h" #include "optimizer/paths.h" #include "optimizer/planmain.h" -#include "optimizer/restrictinfo.h" #include "utils/typcache.h" /* Hook for plugins to get control in add_paths_to_joinrel() */ @@ -131,7 +130,6 @@ add_paths_to_joinrel(PlannerInfo *root, { JoinPathExtraData extra; bool mergejoin_allowed = true; - bool consider_join_pushdown = false; ListCell *lc; Relids joinrelids; @@ -324,24 +322,12 @@ add_paths_to_joinrel(PlannerInfo *root, jointype, &extra); /* - * createplan.c does not currently support handling of pseudoconstant - * clauses assigned to joins pushed down by extensions; check if the - * restrictlist has such clauses, and if so, disallow pushing down joins. - */ - if ((joinrel->fdwroutine && - joinrel->fdwroutine->GetForeignJoinPaths) || - set_join_pathlist_hook) - consider_join_pushdown = !has_pseudoconstant_clauses(root, - restrictlist); - - /* * 5. If inner and outer relations are foreign tables (or joins) belonging * to the same server and assigned to the same user to check access * permissions as, give the FDW a chance to push down joins. */ if (joinrel->fdwroutine && - joinrel->fdwroutine->GetForeignJoinPaths && - consider_join_pushdown) + joinrel->fdwroutine->GetForeignJoinPaths) joinrel->fdwroutine->GetForeignJoinPaths(root, joinrel, outerrel, innerrel, jointype, &extra); @@ -349,8 +335,7 @@ add_paths_to_joinrel(PlannerInfo *root, /* * 6. Finally, give extensions a chance to manipulate the path list. */ - if (set_join_pathlist_hook && - consider_join_pushdown) + if (set_join_pathlist_hook) set_join_pathlist_hook(root, joinrel, outerrel, innerrel, jointype, &extra); } diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index af48109058d..34ca6d4ac21 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -599,8 +599,27 @@ create_scan_plan(PlannerInfo *root, Path *best_path, int flags) * Detect whether we have any pseudoconstant quals to deal with. Then, if * we'll need a gating Result node, it will be able to project, so there * are no requirements on the child's tlist. + * + * If this replaces a join, it must be a foreign scan or a custom scan, + * and the FDW or the custom scan provider would have stored in the best + * path the list of RestrictInfo nodes to apply to the join; check against + * that list in that case. */ - gating_clauses = get_gating_quals(root, scan_clauses); + if (IS_JOIN_REL(rel)) + { + List *join_clauses; + + Assert(best_path->pathtype == T_ForeignScan || + best_path->pathtype == T_CustomScan); + if (best_path->pathtype == T_ForeignScan) + join_clauses = ((ForeignPath *) best_path)->fdw_restrictinfo; + else + join_clauses = ((CustomPath *) best_path)->custom_restrictinfo; + + gating_clauses = get_gating_quals(root, join_clauses); + } + else + gating_clauses = get_gating_quals(root, scan_clauses); if (gating_clauses) flags = 0; diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c index 754f0b9f34c..211ba65389d 100644 --- a/src/backend/optimizer/util/pathnode.c +++ b/src/backend/optimizer/util/pathnode.c @@ -2229,6 +2229,7 @@ create_foreignscan_path(PlannerInfo *root, RelOptInfo *rel, List *pathkeys, Relids required_outer, Path *fdw_outerpath, + List *fdw_restrictinfo, List *fdw_private) { ForeignPath *pathnode = makeNode(ForeignPath); @@ -2250,6 +2251,7 @@ create_foreignscan_path(PlannerInfo *root, RelOptInfo *rel, pathnode->path.pathkeys = pathkeys; pathnode->fdw_outerpath = fdw_outerpath; + pathnode->fdw_restrictinfo = fdw_restrictinfo; pathnode->fdw_private = fdw_private; return pathnode; @@ -2273,6 +2275,7 @@ create_foreign_join_path(PlannerInfo *root, RelOptInfo *rel, List *pathkeys, Relids required_outer, Path *fdw_outerpath, + List *fdw_restrictinfo, List *fdw_private) { ForeignPath *pathnode = makeNode(ForeignPath); @@ -2300,6 +2303,7 @@ create_foreign_join_path(PlannerInfo *root, RelOptInfo *rel, pathnode->path.pathkeys = pathkeys; pathnode->fdw_outerpath = fdw_outerpath; + pathnode->fdw_restrictinfo = fdw_restrictinfo; pathnode->fdw_private = fdw_private; return pathnode; @@ -2322,6 +2326,7 @@ create_foreign_upper_path(PlannerInfo *root, RelOptInfo *rel, double rows, Cost startup_cost, Cost total_cost, List *pathkeys, Path *fdw_outerpath, + List *fdw_restrictinfo, List *fdw_private) { ForeignPath *pathnode = makeNode(ForeignPath); @@ -2345,6 +2350,7 @@ create_foreign_upper_path(PlannerInfo *root, RelOptInfo *rel, pathnode->path.pathkeys = pathkeys; pathnode->fdw_outerpath = fdw_outerpath; + pathnode->fdw_restrictinfo = fdw_restrictinfo; pathnode->fdw_private = fdw_private; return pathnode; @@ -4149,6 +4155,8 @@ do { \ FLAT_COPY_PATH(fpath, path, ForeignPath); if (fpath->fdw_outerpath) REPARAMETERIZE_CHILD_PATH(fpath->fdw_outerpath); + if (fpath->fdw_restrictinfo) + ADJUST_CHILD_ATTRS(fpath->fdw_restrictinfo); /* Hand over to FDW if needed. */ rfpc_func = @@ -4166,6 +4174,8 @@ do { \ FLAT_COPY_PATH(cpath, path, CustomPath); REPARAMETERIZE_CHILD_PATH_LIST(cpath->custom_paths); + if (cpath->custom_restrictinfo) + ADJUST_CHILD_ATTRS(cpath->custom_restrictinfo); if (cpath->methods && cpath->methods->ReparameterizeCustomPathByChild) cpath->custom_private = diff --git a/src/backend/optimizer/util/restrictinfo.c b/src/backend/optimizer/util/restrictinfo.c index c1fbbb6bfee..d6d26a2b515 100644 --- a/src/backend/optimizer/util/restrictinfo.c +++ b/src/backend/optimizer/util/restrictinfo.c @@ -550,36 +550,6 @@ extract_actual_join_clauses(List *restrictinfo_list, } /* - * has_pseudoconstant_clauses - * - * Returns true if 'restrictinfo_list' includes pseudoconstant clauses. - * - * This is used when we determine whether to allow extensions to consider - * pushing down joins in add_paths_to_joinrel(). - */ -bool -has_pseudoconstant_clauses(PlannerInfo *root, - List *restrictinfo_list) -{ - ListCell *l; - - /* No need to look if we know there are no pseudoconstants */ - if (!root->hasPseudoConstantQuals) - return false; - - /* See if there are pseudoconstants in the RestrictInfo list */ - foreach(l, restrictinfo_list) - { - RestrictInfo *rinfo = lfirst_node(RestrictInfo, l); - - if (rinfo->pseudoconstant && - !rinfo_is_constant_true(rinfo)) - return true; - } - return false; -} - -/* * join_clause_is_movable_to * Test whether a join clause is a safe candidate for parameterization * of a scan on the specified base relation. |