aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/path
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/path')
-rw-r--r--src/backend/optimizer/path/allpaths.c16
-rw-r--r--src/backend/optimizer/path/costsize.c7
-rw-r--r--src/backend/optimizer/path/indxpath.c52
-rw-r--r--src/backend/optimizer/path/joinpath.c103
-rw-r--r--src/backend/optimizer/path/joinrels.c10
-rw-r--r--src/backend/optimizer/path/orindxpath.c2
-rw-r--r--src/backend/optimizer/path/tidpath.c3
7 files changed, 121 insertions, 72 deletions
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index 4b8a73d60f4..bfd3809a007 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -386,8 +386,7 @@ set_plain_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
/*
* We don't support pushing join clauses into the quals of a seqscan, but
* it could still have required parameterization due to LATERAL refs in
- * its tlist. (That can only happen if the seqscan is on a relation
- * pulled up out of a UNION ALL appendrel.)
+ * its tlist.
*/
required_outer = rel->lateral_relids;
@@ -550,8 +549,8 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
* Note: the resulting childrel->reltargetlist may contain arbitrary
* expressions, which otherwise would not occur in a reltargetlist.
* Code that might be looking at an appendrel child must cope with
- * such. Note in particular that "arbitrary expression" can include
- * "Var belonging to another relation", due to LATERAL references.
+ * such. (Normally, a reltargetlist would only include Vars and
+ * PlaceHolderVars.)
*/
childrel->joininfo = (List *)
adjust_appendrel_attrs(root,
@@ -1355,8 +1354,7 @@ set_cte_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
/*
* We don't support pushing join clauses into the quals of a CTE scan, but
* it could still have required parameterization due to LATERAL refs in
- * its tlist. (That can only happen if the CTE scan is on a relation
- * pulled up out of a UNION ALL appendrel.)
+ * its tlist.
*/
required_outer = rel->lateral_relids;
@@ -1408,10 +1406,8 @@ set_worktable_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
/*
* We don't support pushing join clauses into the quals of a worktable
* scan, but it could still have required parameterization due to LATERAL
- * refs in its tlist. (That can only happen if the worktable scan is on a
- * relation pulled up out of a UNION ALL appendrel. I'm not sure this is
- * actually possible given the restrictions on recursive references, but
- * it's easy enough to support.)
+ * refs in its tlist. (I'm not sure this is actually possible given the
+ * restrictions on recursive references, but it's easy enough to support.)
*/
required_outer = rel->lateral_relids;
diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
index 3507f18007e..a2cc6979594 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -3935,10 +3935,9 @@ set_rel_width(PlannerInfo *root, RelOptInfo *rel)
/*
* Ordinarily, a Var in a rel's reltargetlist must belong to that rel;
- * but there are corner cases involving LATERAL references in
- * appendrel members where that isn't so (see set_append_rel_size()).
- * If the Var has the wrong varno, fall through to the generic case
- * (it doesn't seem worth the trouble to be any smarter).
+ * but there are corner cases involving LATERAL references where that
+ * isn't so. If the Var has the wrong varno, fall through to the
+ * generic case (it doesn't seem worth the trouble to be any smarter).
*/
if (IsA(node, Var) &&
((Var *) node)->varno == rel->relid)
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index 65eb344cde4..606734a1221 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -141,12 +141,10 @@ static void match_restriction_clauses_to_index(RelOptInfo *rel,
IndexClauseSet *clauseset);
static void match_join_clauses_to_index(PlannerInfo *root,
RelOptInfo *rel, IndexOptInfo *index,
- Relids lateral_referencers,
IndexClauseSet *clauseset,
List **joinorclauses);
static void match_eclass_clauses_to_index(PlannerInfo *root,
IndexOptInfo *index,
- Relids lateral_referencers,
IndexClauseSet *clauseset);
static void match_clauses_to_index(IndexOptInfo *index,
List *clauses,
@@ -220,14 +218,14 @@ static Const *string_to_const(const char *str, Oid datatype);
*
* Note: check_partial_indexes() must have been run previously for this rel.
*
- * Note: in corner cases involving LATERAL appendrel children, it's possible
- * that rel->lateral_relids is nonempty. Currently, we include lateral_relids
- * into the parameterization reported for each path, but don't take it into
- * account otherwise. The fact that any such rels *must* be available as
- * parameter sources perhaps should influence our choices of index quals ...
- * but for now, it doesn't seem worth troubling over. In particular, comments
- * below about "unparameterized" paths should be read as meaning
- * "unparameterized so far as the indexquals are concerned".
+ * Note: in cases involving LATERAL references in the relation's tlist, it's
+ * possible that rel->lateral_relids is nonempty. Currently, we include
+ * lateral_relids into the parameterization reported for each path, but don't
+ * take it into account otherwise. The fact that any such rels *must* be
+ * available as parameter sources perhaps should influence our choices of
+ * index quals ... but for now, it doesn't seem worth troubling over.
+ * In particular, comments below about "unparameterized" paths should be read
+ * as meaning "unparameterized so far as the indexquals are concerned".
*/
void
create_index_paths(PlannerInfo *root, RelOptInfo *rel)
@@ -236,7 +234,6 @@ create_index_paths(PlannerInfo *root, RelOptInfo *rel)
List *bitindexpaths;
List *bitjoinpaths;
List *joinorclauses;
- Relids lateral_referencers;
IndexClauseSet rclauseset;
IndexClauseSet jclauseset;
IndexClauseSet eclauseset;
@@ -246,23 +243,6 @@ create_index_paths(PlannerInfo *root, RelOptInfo *rel)
if (rel->indexlist == NIL)
return;
- /*
- * If there are any rels that have LATERAL references to this one, we
- * cannot use join quals referencing them as index quals for this one,
- * since such rels would have to be on the inside not the outside of a
- * nestloop join relative to this one. Create a Relids set listing all
- * such rels, for use in checks of potential join clauses.
- */
- lateral_referencers = NULL;
- foreach(lc, root->lateral_info_list)
- {
- LateralJoinInfo *ljinfo = (LateralJoinInfo *) lfirst(lc);
-
- if (bms_is_member(rel->relid, ljinfo->lateral_lhs))
- lateral_referencers = bms_add_member(lateral_referencers,
- ljinfo->lateral_rhs);
- }
-
/* Bitmap paths are collected and then dealt with at the end */
bitindexpaths = bitjoinpaths = joinorclauses = NIL;
@@ -303,7 +283,7 @@ create_index_paths(PlannerInfo *root, RelOptInfo *rel)
* EquivalenceClasses. Also, collect join OR clauses for later.
*/
MemSet(&jclauseset, 0, sizeof(jclauseset));
- match_join_clauses_to_index(root, rel, index, lateral_referencers,
+ match_join_clauses_to_index(root, rel, index,
&jclauseset, &joinorclauses);
/*
@@ -311,7 +291,7 @@ create_index_paths(PlannerInfo *root, RelOptInfo *rel)
* the index.
*/
MemSet(&eclauseset, 0, sizeof(eclauseset));
- match_eclass_clauses_to_index(root, index, lateral_referencers,
+ match_eclass_clauses_to_index(root, index,
&eclauseset);
/*
@@ -1957,7 +1937,6 @@ match_restriction_clauses_to_index(RelOptInfo *rel, IndexOptInfo *index,
static void
match_join_clauses_to_index(PlannerInfo *root,
RelOptInfo *rel, IndexOptInfo *index,
- Relids lateral_referencers,
IndexClauseSet *clauseset,
List **joinorclauses)
{
@@ -1969,11 +1948,7 @@ match_join_clauses_to_index(PlannerInfo *root,
RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
/* Check if clause can be moved to this rel */
- if (!join_clause_is_movable_to(rinfo, rel->relid))
- continue;
-
- /* Not useful if it conflicts with any LATERAL references */
- if (bms_overlap(rinfo->clause_relids, lateral_referencers))
+ if (!join_clause_is_movable_to(rinfo, rel))
continue;
/* Potentially usable, so see if it matches the index or is an OR */
@@ -1991,7 +1966,6 @@ match_join_clauses_to_index(PlannerInfo *root,
*/
static void
match_eclass_clauses_to_index(PlannerInfo *root, IndexOptInfo *index,
- Relids lateral_referencers,
IndexClauseSet *clauseset)
{
int indexcol;
@@ -2012,7 +1986,7 @@ match_eclass_clauses_to_index(PlannerInfo *root, IndexOptInfo *index,
index->rel,
ec_member_matches_indexcol,
(void *) &arg,
- lateral_referencers);
+ index->rel->lateral_referencers);
/*
* We have to check whether the results actually do match the index,
@@ -2644,7 +2618,7 @@ check_partial_indexes(PlannerInfo *root, RelOptInfo *rel)
RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
/* Check if clause can be moved to this rel */
- if (!join_clause_is_movable_to(rinfo, rel->relid))
+ if (!join_clause_is_movable_to(rinfo, rel))
continue;
clauselist = lappend(clauselist, rinfo);
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c
index d6050a616c7..5b477e52d3f 100644
--- a/src/backend/optimizer/path/joinpath.c
+++ b/src/backend/optimizer/path/joinpath.c
@@ -29,19 +29,19 @@ static void sort_inner_and_outer(PlannerInfo *root, RelOptInfo *joinrel,
RelOptInfo *outerrel, RelOptInfo *innerrel,
List *restrictlist, List *mergeclause_list,
JoinType jointype, SpecialJoinInfo *sjinfo,
- Relids param_source_rels);
+ Relids param_source_rels, Relids extra_lateral_rels);
static void match_unsorted_outer(PlannerInfo *root, RelOptInfo *joinrel,
RelOptInfo *outerrel, RelOptInfo *innerrel,
List *restrictlist, List *mergeclause_list,
JoinType jointype, SpecialJoinInfo *sjinfo,
SemiAntiJoinFactors *semifactors,
- Relids param_source_rels);
+ Relids param_source_rels, Relids extra_lateral_rels);
static void hash_inner_and_outer(PlannerInfo *root, RelOptInfo *joinrel,
RelOptInfo *outerrel, RelOptInfo *innerrel,
List *restrictlist,
JoinType jointype, SpecialJoinInfo *sjinfo,
SemiAntiJoinFactors *semifactors,
- Relids param_source_rels);
+ Relids param_source_rels, Relids extra_lateral_rels);
static List *select_mergejoin_clauses(PlannerInfo *root,
RelOptInfo *joinrel,
RelOptInfo *outerrel,
@@ -87,6 +87,7 @@ add_paths_to_joinrel(PlannerInfo *root,
bool mergejoin_allowed = true;
SemiAntiJoinFactors semifactors;
Relids param_source_rels = NULL;
+ Relids extra_lateral_rels = NULL;
ListCell *lc;
/*
@@ -162,20 +163,58 @@ add_paths_to_joinrel(PlannerInfo *root,
{
LateralJoinInfo *ljinfo = (LateralJoinInfo *) lfirst(lc);
- if (bms_is_member(ljinfo->lateral_rhs, joinrel->relids))
+ if (bms_is_subset(ljinfo->lateral_rhs, joinrel->relids))
param_source_rels = bms_join(param_source_rels,
bms_difference(ljinfo->lateral_lhs,
joinrel->relids));
}
/*
+ * Another issue created by LATERAL references is that PlaceHolderVars
+ * that need to be computed at this join level might contain lateral
+ * references to rels not in the join, meaning that the paths for the join
+ * would need to be marked as parameterized by those rels, independently
+ * of all other considerations. Set extra_lateral_rels to the set of such
+ * rels. This will not affect our decisions as to which paths to
+ * generate; we merely add these rels to their required_outer sets.
+ */
+ foreach(lc, root->placeholder_list)
+ {
+ PlaceHolderInfo *phinfo = (PlaceHolderInfo *) lfirst(lc);
+
+ /* PHVs without lateral refs can be skipped over quickly */
+ if (phinfo->ph_lateral == NULL)
+ continue;
+ /* Is it due to be evaluated at this join, and not in either input? */
+ if (bms_is_subset(phinfo->ph_eval_at, joinrel->relids) &&
+ !bms_is_subset(phinfo->ph_eval_at, outerrel->relids) &&
+ !bms_is_subset(phinfo->ph_eval_at, innerrel->relids))
+ {
+ /* Yes, remember its lateral rels */
+ extra_lateral_rels = bms_add_members(extra_lateral_rels,
+ phinfo->ph_lateral);
+ }
+ }
+
+ /*
+ * Make sure extra_lateral_rels doesn't list anything within the join, and
+ * that it's NULL if empty. (This allows us to use bms_add_members to add
+ * it to required_outer below, while preserving the property that
+ * required_outer is exactly NULL if empty.)
+ */
+ extra_lateral_rels = bms_del_members(extra_lateral_rels, joinrel->relids);
+ if (bms_is_empty(extra_lateral_rels))
+ extra_lateral_rels = NULL;
+
+ /*
* 1. Consider mergejoin paths where both relations must be explicitly
* sorted. Skip this if we can't mergejoin.
*/
if (mergejoin_allowed)
sort_inner_and_outer(root, joinrel, outerrel, innerrel,
restrictlist, mergeclause_list, jointype,
- sjinfo, param_source_rels);
+ sjinfo,
+ param_source_rels, extra_lateral_rels);
/*
* 2. Consider paths where the outer relation need not be explicitly
@@ -187,7 +226,8 @@ add_paths_to_joinrel(PlannerInfo *root,
if (mergejoin_allowed)
match_unsorted_outer(root, joinrel, outerrel, innerrel,
restrictlist, mergeclause_list, jointype,
- sjinfo, &semifactors, param_source_rels);
+ sjinfo, &semifactors,
+ param_source_rels, extra_lateral_rels);
#ifdef NOT_USED
@@ -205,7 +245,8 @@ add_paths_to_joinrel(PlannerInfo *root,
if (mergejoin_allowed)
match_unsorted_inner(root, joinrel, outerrel, innerrel,
restrictlist, mergeclause_list, jointype,
- sjinfo, &semifactors, param_source_rels);
+ sjinfo, &semifactors,
+ param_source_rels, extra_lateral_rels);
#endif
/*
@@ -216,7 +257,8 @@ add_paths_to_joinrel(PlannerInfo *root,
if (enable_hashjoin || jointype == JOIN_FULL)
hash_inner_and_outer(root, joinrel, outerrel, innerrel,
restrictlist, jointype,
- sjinfo, &semifactors, param_source_rels);
+ sjinfo, &semifactors,
+ param_source_rels, extra_lateral_rels);
}
/*
@@ -231,6 +273,7 @@ try_nestloop_path(PlannerInfo *root,
SpecialJoinInfo *sjinfo,
SemiAntiJoinFactors *semifactors,
Relids param_source_rels,
+ Relids extra_lateral_rels,
Path *outer_path,
Path *inner_path,
List *restrict_clauses,
@@ -254,6 +297,12 @@ try_nestloop_path(PlannerInfo *root,
}
/*
+ * Independently of that, add parameterization needed for any
+ * PlaceHolderVars that need to be computed at the join.
+ */
+ required_outer = bms_add_members(required_outer, extra_lateral_rels);
+
+ /*
* Do a precheck to quickly eliminate obviously-inferior paths. We
* calculate a cheap lower bound on the path's cost and then use
* add_path_precheck() to see if the path is clearly going to be dominated
@@ -301,6 +350,7 @@ try_mergejoin_path(PlannerInfo *root,
JoinType jointype,
SpecialJoinInfo *sjinfo,
Relids param_source_rels,
+ Relids extra_lateral_rels,
Path *outer_path,
Path *inner_path,
List *restrict_clauses,
@@ -327,6 +377,12 @@ try_mergejoin_path(PlannerInfo *root,
}
/*
+ * Independently of that, add parameterization needed for any
+ * PlaceHolderVars that need to be computed at the join.
+ */
+ required_outer = bms_add_members(required_outer, extra_lateral_rels);
+
+ /*
* If the given paths are already well enough ordered, we can skip doing
* an explicit sort.
*/
@@ -383,6 +439,7 @@ try_hashjoin_path(PlannerInfo *root,
SpecialJoinInfo *sjinfo,
SemiAntiJoinFactors *semifactors,
Relids param_source_rels,
+ Relids extra_lateral_rels,
Path *outer_path,
Path *inner_path,
List *restrict_clauses,
@@ -406,6 +463,12 @@ try_hashjoin_path(PlannerInfo *root,
}
/*
+ * Independently of that, add parameterization needed for any
+ * PlaceHolderVars that need to be computed at the join.
+ */
+ required_outer = bms_add_members(required_outer, extra_lateral_rels);
+
+ /*
* See comments in try_nestloop_path(). Also note that hashjoin paths
* never have any output pathkeys, per comments in create_hashjoin_path.
*/
@@ -483,6 +546,7 @@ clause_sides_match_join(RestrictInfo *rinfo, RelOptInfo *outerrel,
* 'jointype' is the type of join to do
* 'sjinfo' is extra info about the join for selectivity estimation
* 'param_source_rels' are OK targets for parameterization of result paths
+ * 'extra_lateral_rels' are additional parameterization for result paths
*/
static void
sort_inner_and_outer(PlannerInfo *root,
@@ -493,7 +557,8 @@ sort_inner_and_outer(PlannerInfo *root,
List *mergeclause_list,
JoinType jointype,
SpecialJoinInfo *sjinfo,
- Relids param_source_rels)
+ Relids param_source_rels,
+ Relids extra_lateral_rels)
{
Path *outer_path;
Path *inner_path;
@@ -623,6 +688,7 @@ sort_inner_and_outer(PlannerInfo *root,
jointype,
sjinfo,
param_source_rels,
+ extra_lateral_rels,
outer_path,
inner_path,
restrictlist,
@@ -668,6 +734,7 @@ sort_inner_and_outer(PlannerInfo *root,
* 'sjinfo' is extra info about the join for selectivity estimation
* 'semifactors' contains valid data if jointype is SEMI or ANTI
* 'param_source_rels' are OK targets for parameterization of result paths
+ * 'extra_lateral_rels' are additional parameterization for result paths
*/
static void
match_unsorted_outer(PlannerInfo *root,
@@ -679,7 +746,8 @@ match_unsorted_outer(PlannerInfo *root,
JoinType jointype,
SpecialJoinInfo *sjinfo,
SemiAntiJoinFactors *semifactors,
- Relids param_source_rels)
+ Relids param_source_rels,
+ Relids extra_lateral_rels)
{
JoinType save_jointype = jointype;
bool nestjoinOK;
@@ -809,6 +877,7 @@ match_unsorted_outer(PlannerInfo *root,
sjinfo,
semifactors,
param_source_rels,
+ extra_lateral_rels,
outerpath,
inner_cheapest_total,
restrictlist,
@@ -834,6 +903,7 @@ match_unsorted_outer(PlannerInfo *root,
sjinfo,
semifactors,
param_source_rels,
+ extra_lateral_rels,
outerpath,
innerpath,
restrictlist,
@@ -848,6 +918,7 @@ match_unsorted_outer(PlannerInfo *root,
sjinfo,
semifactors,
param_source_rels,
+ extra_lateral_rels,
outerpath,
matpath,
restrictlist,
@@ -903,6 +974,7 @@ match_unsorted_outer(PlannerInfo *root,
jointype,
sjinfo,
param_source_rels,
+ extra_lateral_rels,
outerpath,
inner_cheapest_total,
restrictlist,
@@ -1001,6 +1073,7 @@ match_unsorted_outer(PlannerInfo *root,
jointype,
sjinfo,
param_source_rels,
+ extra_lateral_rels,
outerpath,
innerpath,
restrictlist,
@@ -1046,6 +1119,7 @@ match_unsorted_outer(PlannerInfo *root,
jointype,
sjinfo,
param_source_rels,
+ extra_lateral_rels,
outerpath,
innerpath,
restrictlist,
@@ -1080,6 +1154,7 @@ match_unsorted_outer(PlannerInfo *root,
* 'sjinfo' is extra info about the join for selectivity estimation
* 'semifactors' contains valid data if jointype is SEMI or ANTI
* 'param_source_rels' are OK targets for parameterization of result paths
+ * 'extra_lateral_rels' are additional parameterization for result paths
*/
static void
hash_inner_and_outer(PlannerInfo *root,
@@ -1090,7 +1165,8 @@ hash_inner_and_outer(PlannerInfo *root,
JoinType jointype,
SpecialJoinInfo *sjinfo,
SemiAntiJoinFactors *semifactors,
- Relids param_source_rels)
+ Relids param_source_rels,
+ Relids extra_lateral_rels)
{
bool isouterjoin = IS_OUTER_JOIN(jointype);
List *hashclauses;
@@ -1164,6 +1240,7 @@ hash_inner_and_outer(PlannerInfo *root,
sjinfo,
semifactors,
param_source_rels,
+ extra_lateral_rels,
cheapest_total_outer,
cheapest_total_inner,
restrictlist,
@@ -1183,6 +1260,7 @@ hash_inner_and_outer(PlannerInfo *root,
sjinfo,
semifactors,
param_source_rels,
+ extra_lateral_rels,
cheapest_total_outer,
cheapest_total_inner,
restrictlist,
@@ -1195,6 +1273,7 @@ hash_inner_and_outer(PlannerInfo *root,
sjinfo,
semifactors,
param_source_rels,
+ extra_lateral_rels,
cheapest_startup_outer,
cheapest_total_inner,
restrictlist,
@@ -1219,6 +1298,7 @@ hash_inner_and_outer(PlannerInfo *root,
sjinfo,
semifactors,
param_source_rels,
+ extra_lateral_rels,
cheapest_startup_outer,
cheapest_total_inner,
restrictlist,
@@ -1256,6 +1336,7 @@ hash_inner_and_outer(PlannerInfo *root,
sjinfo,
semifactors,
param_source_rels,
+ extra_lateral_rels,
outerpath,
innerpath,
restrictlist,
diff --git a/src/backend/optimizer/path/joinrels.c b/src/backend/optimizer/path/joinrels.c
index 819498a4281..d627f9e130c 100644
--- a/src/backend/optimizer/path/joinrels.c
+++ b/src/backend/optimizer/path/joinrels.c
@@ -526,7 +526,7 @@ join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
{
LateralJoinInfo *ljinfo = (LateralJoinInfo *) lfirst(l);
- if (bms_is_member(ljinfo->lateral_rhs, rel2->relids) &&
+ if (bms_is_subset(ljinfo->lateral_rhs, rel2->relids) &&
bms_overlap(ljinfo->lateral_lhs, rel1->relids))
{
/* has to be implemented as nestloop with rel1 on left */
@@ -539,7 +539,7 @@ join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
(reversed || match_sjinfo->jointype == JOIN_FULL))
return false; /* not implementable as nestloop */
}
- if (bms_is_member(ljinfo->lateral_rhs, rel1->relids) &&
+ if (bms_is_subset(ljinfo->lateral_rhs, rel1->relids) &&
bms_overlap(ljinfo->lateral_lhs, rel2->relids))
{
/* has to be implemented as nestloop with rel2 on left */
@@ -829,10 +829,10 @@ have_join_order_restriction(PlannerInfo *root,
{
LateralJoinInfo *ljinfo = (LateralJoinInfo *) lfirst(l);
- if (bms_is_member(ljinfo->lateral_rhs, rel2->relids) &&
+ if (bms_is_subset(ljinfo->lateral_rhs, rel2->relids) &&
bms_overlap(ljinfo->lateral_lhs, rel1->relids))
return true;
- if (bms_is_member(ljinfo->lateral_rhs, rel1->relids) &&
+ if (bms_is_subset(ljinfo->lateral_rhs, rel1->relids) &&
bms_overlap(ljinfo->lateral_lhs, rel2->relids))
return true;
}
@@ -928,7 +928,7 @@ has_join_restriction(PlannerInfo *root, RelOptInfo *rel)
{
LateralJoinInfo *ljinfo = (LateralJoinInfo *) lfirst(l);
- if (bms_is_member(ljinfo->lateral_rhs, rel->relids) ||
+ if (bms_is_subset(ljinfo->lateral_rhs, rel->relids) ||
bms_overlap(ljinfo->lateral_lhs, rel->relids))
return true;
}
diff --git a/src/backend/optimizer/path/orindxpath.c b/src/backend/optimizer/path/orindxpath.c
index e51e5c08b52..16f29d350fd 100644
--- a/src/backend/optimizer/path/orindxpath.c
+++ b/src/backend/optimizer/path/orindxpath.c
@@ -103,7 +103,7 @@ create_or_index_quals(PlannerInfo *root, RelOptInfo *rel)
RestrictInfo *rinfo = (RestrictInfo *) lfirst(i);
if (restriction_is_or_clause(rinfo) &&
- join_clause_is_movable_to(rinfo, rel->relid))
+ join_clause_is_movable_to(rinfo, rel))
{
/*
* Use the generate_bitmap_or_paths() machinery to estimate the
diff --git a/src/backend/optimizer/path/tidpath.c b/src/backend/optimizer/path/tidpath.c
index f49d0f96d04..256856da35e 100644
--- a/src/backend/optimizer/path/tidpath.c
+++ b/src/backend/optimizer/path/tidpath.c
@@ -255,8 +255,7 @@ create_tidscan_paths(PlannerInfo *root, RelOptInfo *rel)
/*
* We don't support pushing join clauses into the quals of a tidscan, but
* it could still have required parameterization due to LATERAL refs in
- * its tlist. (That can only happen if the tidscan is on a relation
- * pulled up out of a UNION ALL appendrel.)
+ * its tlist.
*/
required_outer = rel->lateral_relids;