From e39d14d9d38682e0c1622c6cfb2f0caf5180979b Mon Sep 17 00:00:00 2001 From: Geng Lei Date: Thu, 22 Oct 2026 14:16:51 +0000 Subject: [RFC PATCH] Skip LATERAL check in join_clause_is_movable_to() during OR-clause restriction extraction --- contrib/postgres_fdw/postgres_fdw.c | 4 ++-- src/backend/optimizer/path/indxpath.c | 4 ++-- src/backend/optimizer/path/tidpath.c | 2 +- src/backend/optimizer/util/orclauses.c | 2 +- src/backend/optimizer/util/restrictinfo.c | 7 +++++-- src/include/optimizer/restrictinfo.h | 4 +++- 6 files changed, 14 insertions(+), 9 deletions(-) diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c index 6757ee923cb..963e8663669 100644 --- a/contrib/postgres_fdw/postgres_fdw.c +++ b/contrib/postgres_fdw/postgres_fdw.c @@ -1203,7 +1203,7 @@ postgresGetForeignPaths(PlannerInfo *root, ParamPathInfo *param_info; /* Check if clause can be moved to this rel */ - if (!join_clause_is_movable_to(rinfo, baserel)) + if (!join_clause_is_movable_to(rinfo, baserel, false)) continue; /* See if it is safe to send to remote */ @@ -1279,7 +1279,7 @@ postgresGetForeignPaths(PlannerInfo *root, ParamPathInfo *param_info; /* Check if clause can be moved to this rel */ - if (!join_clause_is_movable_to(rinfo, baserel)) + if (!join_clause_is_movable_to(rinfo, baserel, false)) continue; /* See if it is safe to send to remote */ diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c index 3f5d4fa3182..a97297dd459 100644 --- a/src/backend/optimizer/path/indxpath.c +++ b/src/backend/optimizer/path/indxpath.c @@ -2490,7 +2490,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)) + if (!join_clause_is_movable_to(rinfo, rel, false)) continue; /* @@ -3980,7 +3980,7 @@ check_index_predicates(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)) + if (!join_clause_is_movable_to(rinfo, rel, false)) continue; clauselist = lappend(clauselist, rinfo); diff --git a/src/backend/optimizer/path/tidpath.c b/src/backend/optimizer/path/tidpath.c index 18a3654720b..ddf8be4e334 100644 --- a/src/backend/optimizer/path/tidpath.c +++ b/src/backend/optimizer/path/tidpath.c @@ -457,7 +457,7 @@ BuildParameterizedTidPaths(PlannerInfo *root, RelOptInfo *rel, List *clauses) * redundant when considering EC-derived clauses, but we must check it * for "loose" join clauses. */ - if (!join_clause_is_movable_to(rinfo, rel)) + if (!join_clause_is_movable_to(rinfo, rel, false)) continue; /* OK, make list of clauses for this path */ diff --git a/src/backend/optimizer/util/orclauses.c b/src/backend/optimizer/util/orclauses.c index 0751c84e045..f2df21e012a 100644 --- a/src/backend/optimizer/util/orclauses.c +++ b/src/backend/optimizer/util/orclauses.c @@ -103,7 +103,7 @@ extract_restriction_or_clauses(PlannerInfo *root) RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc); if (restriction_is_or_clause(rinfo) && - join_clause_is_movable_to(rinfo, rel)) + join_clause_is_movable_to(rinfo, rel, true)) { /* Try to extract a qual for this rel only */ Expr *orclause = extract_or_clause(rinfo, rel); diff --git a/src/backend/optimizer/util/restrictinfo.c b/src/backend/optimizer/util/restrictinfo.c index 713518b8564..09c98d51fed 100644 --- a/src/backend/optimizer/util/restrictinfo.c +++ b/src/backend/optimizer/util/restrictinfo.c @@ -572,7 +572,9 @@ extract_actual_join_clauses(List *restrictinfo_list, * is sufficient. */ bool -join_clause_is_movable_to(RestrictInfo *rinfo, RelOptInfo *baserel) +join_clause_is_movable_to(RestrictInfo *rinfo, + RelOptInfo *baserel, + bool lateral_referencers_allowed ) { /* Clause must physically reference target rel */ if (!bms_is_member(baserel->relid, rinfo->clause_relids)) @@ -596,7 +598,8 @@ join_clause_is_movable_to(RestrictInfo *rinfo, RelOptInfo *baserel) return false; /* Clause must not use any rels with LATERAL references to this rel */ - if (bms_overlap(baserel->lateral_referencers, rinfo->clause_relids)) + if (!lateral_referencers_allowed && + bms_overlap(baserel->lateral_referencers, rinfo->clause_relids)) return false; /* Ignore clones, too */ diff --git a/src/include/optimizer/restrictinfo.h b/src/include/optimizer/restrictinfo.h index 72e9410d580..796ab5d9149 100644 --- a/src/include/optimizer/restrictinfo.h +++ b/src/include/optimizer/restrictinfo.h @@ -54,7 +54,9 @@ extern void extract_actual_join_clauses(List *restrictinfo_list, Relids joinrelids, List **joinquals, List **otherquals); -extern bool join_clause_is_movable_to(RestrictInfo *rinfo, RelOptInfo *baserel); +extern bool join_clause_is_movable_to(RestrictInfo *rinfo, + RelOptInfo *baserel, + bool lateral_referencers_allowed); extern bool join_clause_is_movable_into(RestrictInfo *rinfo, Relids currentrelids, Relids current_and_outer); base-commit: f2edf5dd00d174c7b1396f0a777375368a26c752 -- 2.53.0