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 | 29 | ||||
-rw-r--r-- | src/include/optimizer/restrictinfo.h | 2 |
3 files changed, 48 insertions, 2 deletions
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c index c49c58289df..04429770df8 100644 --- a/src/backend/optimizer/path/joinpath.c +++ b/src/backend/optimizer/path/joinpath.c @@ -22,6 +22,7 @@ #include "optimizer/pathnode.h" #include "optimizer/paths.h" #include "optimizer/planmain.h" +#include "optimizer/restrictinfo.h" /* Hook for plugins to get control in add_paths_to_joinrel() */ set_join_pathlist_hook_type set_join_pathlist_hook = NULL; @@ -124,6 +125,7 @@ add_paths_to_joinrel(PlannerInfo *root, { JoinPathExtraData extra; bool mergejoin_allowed = true; + bool consider_join_pushdown = false; ListCell *lc; Relids joinrelids; @@ -308,12 +310,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); @@ -321,7 +335,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 2c3a6f2cf7c..e54580947c8 100644 --- a/src/backend/optimizer/util/restrictinfo.c +++ b/src/backend/optimizer/util/restrictinfo.c @@ -509,6 +509,35 @@ 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) + return true; + } + return false; +} + /* * join_clause_is_movable_to diff --git a/src/include/optimizer/restrictinfo.h b/src/include/optimizer/restrictinfo.h index 0f0ab801c04..78d6f8a8da3 100644 --- a/src/include/optimizer/restrictinfo.h +++ b/src/include/optimizer/restrictinfo.h @@ -49,6 +49,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, |