diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/optimizer/path/joinpath.c | 19 | ||||
-rw-r--r-- | src/backend/optimizer/util/restrictinfo.c | 30 | ||||
-rw-r--r-- | src/include/optimizer/restrictinfo.h | 2 |
3 files changed, 49 insertions, 2 deletions
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c index f047ad9ba46..4b58936fa4c 100644 --- a/src/backend/optimizer/path/joinpath.c +++ b/src/backend/optimizer/path/joinpath.c @@ -24,6 +24,7 @@ #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() */ @@ -130,6 +131,7 @@ add_paths_to_joinrel(PlannerInfo *root, { JoinPathExtraData extra; bool mergejoin_allowed = true; + bool consider_join_pushdown = false; ListCell *lc; Relids joinrelids; @@ -322,12 +324,24 @@ 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) + joinrel->fdwroutine->GetForeignJoinPaths && + consider_join_pushdown) joinrel->fdwroutine->GetForeignJoinPaths(root, joinrel, outerrel, innerrel, jointype, &extra); @@ -335,7 +349,8 @@ add_paths_to_joinrel(PlannerInfo *root, /* * 6. Finally, give extensions a chance to manipulate the path list. */ - if (set_join_pathlist_hook) + if (set_join_pathlist_hook && + consider_join_pushdown) set_join_pathlist_hook(root, joinrel, outerrel, innerrel, jointype, &extra); } diff --git a/src/backend/optimizer/util/restrictinfo.c b/src/backend/optimizer/util/restrictinfo.c index d6d26a2b515..c1fbbb6bfee 100644 --- a/src/backend/optimizer/util/restrictinfo.c +++ b/src/backend/optimizer/util/restrictinfo.c @@ -550,6 +550,36 @@ 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. diff --git a/src/include/optimizer/restrictinfo.h b/src/include/optimizer/restrictinfo.h index e140e619ace..14cdce750cb 100644 --- a/src/include/optimizer/restrictinfo.h +++ b/src/include/optimizer/restrictinfo.h @@ -43,6 +43,8 @@ extern void extract_actual_join_clauses(List *restrictinfo_list, Relids joinrelids, List **joinquals, List **otherquals); +extern bool has_pseudoconstant_clauses(PlannerInfo *root, + List *restrictinfo_list); extern bool join_clause_is_movable_to(RestrictInfo *rinfo, RelOptInfo *baserel); extern bool join_clause_is_movable_into(RestrictInfo *rinfo, Relids currentrelids, |