diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c index a244300463c..39711384801 100644 --- a/src/backend/optimizer/path/joinpath.c +++ b/src/backend/optimizer/path/joinpath.c @@ -25,6 +25,7 @@ #include "optimizer/paths.h" #include "optimizer/placeholder.h" #include "optimizer/planmain.h" +#include "optimizer/restrictinfo.h" #include "utils/lsyscache.h" #include "utils/typcache.h" @@ -58,9 +59,6 @@ static void try_partial_mergejoin_path(PlannerInfo *root, static void sort_inner_and_outer(PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *outerrel, RelOptInfo *innerrel, JoinType jointype, JoinPathExtraData *extra); -static inline bool clause_sides_match_join(RestrictInfo *rinfo, - RelOptInfo *outerrel, - RelOptInfo *innerrel); static void match_unsorted_outer(PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *outerrel, RelOptInfo *innerrel, JoinType jointype, JoinPathExtraData *extra); @@ -470,7 +468,8 @@ paraminfo_get_equal_hashops(PlannerInfo *root, ParamPathInfo *param_info, * with 2 args. */ if (!IsA(opexpr, OpExpr) || list_length(opexpr->args) != 2 || - !clause_sides_match_join(rinfo, outerrel, innerrel)) + !clause_sides_match_join(rinfo, outerrel->relids, + innerrel->relids)) { list_free(*operators); list_free(*param_exprs); @@ -1320,37 +1319,6 @@ try_partial_hashjoin_path(PlannerInfo *root, hashclauses)); } -/* - * clause_sides_match_join - * Determine whether a join clause is of the right form to use in this join. - * - * We already know that the clause is a binary opclause referencing only the - * rels in the current join. The point here is to check whether it has the - * form "outerrel_expr op innerrel_expr" or "innerrel_expr op outerrel_expr", - * rather than mixing outer and inner vars on either side. If it matches, - * we set the transient flag outer_is_left to identify which side is which. - */ -static inline bool -clause_sides_match_join(RestrictInfo *rinfo, RelOptInfo *outerrel, - RelOptInfo *innerrel) -{ - if (bms_is_subset(rinfo->left_relids, outerrel->relids) && - bms_is_subset(rinfo->right_relids, innerrel->relids)) - { - /* lefthand side is outer */ - rinfo->outer_is_left = true; - return true; - } - else if (bms_is_subset(rinfo->left_relids, innerrel->relids) && - bms_is_subset(rinfo->right_relids, outerrel->relids)) - { - /* righthand side is outer */ - rinfo->outer_is_left = false; - return true; - } - return false; /* no good for these input relations */ -} - /* * sort_inner_and_outer * Create mergejoin join paths by explicitly sorting both the outer and @@ -2264,7 +2232,8 @@ hash_inner_and_outer(PlannerInfo *root, /* * Check if clause has the form "outer op inner" or "inner op outer". */ - if (!clause_sides_match_join(restrictinfo, outerrel, innerrel)) + if (!clause_sides_match_join(restrictinfo, outerrel->relids, + innerrel->relids)) continue; /* no good for these input relations */ /* @@ -2549,7 +2518,8 @@ select_mergejoin_clauses(PlannerInfo *root, /* * Check if clause has the form "outer op inner" or "inner op outer". */ - if (!clause_sides_match_join(restrictinfo, outerrel, innerrel)) + if (!clause_sides_match_join(restrictinfo, outerrel->relids, + innerrel->relids)) { have_nonmergeable_joinclause = true; continue; /* no good for these input relations */ diff --git a/src/backend/optimizer/plan/analyzejoins.c b/src/backend/optimizer/plan/analyzejoins.c index 928d926645e..5bc16c4bfc7 100644 --- a/src/backend/optimizer/plan/analyzejoins.c +++ b/src/backend/optimizer/plan/analyzejoins.c @@ -115,37 +115,6 @@ restart: return joinlist; } -/* - * clause_sides_match_join - * Determine whether a join clause is of the right form to use in this join. - * - * We already know that the clause is a binary opclause referencing only the - * rels in the current join. The point here is to check whether it has the - * form "outerrel_expr op innerrel_expr" or "innerrel_expr op outerrel_expr", - * rather than mixing outer and inner vars on either side. If it matches, - * we set the transient flag outer_is_left to identify which side is which. - */ -static inline bool -clause_sides_match_join(RestrictInfo *rinfo, Relids outerrelids, - Relids innerrelids) -{ - if (bms_is_subset(rinfo->left_relids, outerrelids) && - bms_is_subset(rinfo->right_relids, innerrelids)) - { - /* lefthand side is outer */ - rinfo->outer_is_left = true; - return true; - } - else if (bms_is_subset(rinfo->left_relids, innerrelids) && - bms_is_subset(rinfo->right_relids, outerrelids)) - { - /* righthand side is outer */ - rinfo->outer_is_left = false; - return true; - } - return false; /* no good for these input relations */ -} - /* * join_is_removable * Check whether we need not perform this special join at all, because diff --git a/src/include/optimizer/restrictinfo.h b/src/include/optimizer/restrictinfo.h index 1b42c832c59..fe03a8ecd34 100644 --- a/src/include/optimizer/restrictinfo.h +++ b/src/include/optimizer/restrictinfo.h @@ -48,4 +48,35 @@ extern bool join_clause_is_movable_into(RestrictInfo *rinfo, Relids currentrelids, Relids current_and_outer); +/* + * clause_sides_match_join + * Determine whether a join clause is of the right form to use in this join. + * + * We already know that the clause is a binary opclause referencing only the + * rels in the current join. The point here is to check whether it has the + * form "outerrel_expr op innerrel_expr" or "innerrel_expr op outerrel_expr", + * rather than mixing outer and inner vars on either side. If it matches, + * we set the transient flag outer_is_left to identify which side is which. + */ +static inline bool +clause_sides_match_join(RestrictInfo *rinfo, Relids outerrelids, + Relids innerrelids) +{ + if (bms_is_subset(rinfo->left_relids, outerrelids) && + bms_is_subset(rinfo->right_relids, innerrelids)) + { + /* lefthand side is outer */ + rinfo->outer_is_left = true; + return true; + } + else if (bms_is_subset(rinfo->left_relids, innerrelids) && + bms_is_subset(rinfo->right_relids, outerrelids)) + { + /* righthand side is outer */ + rinfo->outer_is_left = false; + return true; + } + return false; /* no good for these input relations */ +} + #endif /* RESTRICTINFO_H */