From 0f20013dc2ba44e5b9c94421c02483e556f7a59c Mon Sep 17 00:00:00 2001
From: Tomas Vondra <tomas@vondra.me>
Date: Wed, 22 Jul 2026 21:16:48 +0200
Subject: [PATCH v7 11/12] Fix filters on joins in
 compute_join_expected_filters

The code worked fine for singleton build relids (filters working on
baserels), but with joins we need to be careful about subsets vs.
intersection. We must disallow "partial" filter matches, and not
propagate them further.
---
 src/backend/optimizer/path/joinpath.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c
index a3e16b5d23c..b661a5b800f 100644
--- a/src/backend/optimizer/path/joinpath.c
+++ b/src/backend/optimizer/path/joinpath.c
@@ -1051,21 +1051,21 @@ compute_join_expected_filters(PlannerInfo *root,
 			owner_relids = owner_in_outer ? outer_relids : inner_relids;
 			other_relids = owner_in_outer ? inner_relids : outer_relids;
 
-			if (bms_is_subset(f->build_relids, owner_relids))
+			/*
+			 * Build side already sits with the owner; this shouldn't
+			 * normally happen (such a filter would have been resolved or
+			 * discarded at a lower join).
+			 */
+			Assert(!bms_is_subset(f->build_relids, owner_relids));
+
+			if (bms_overlap(f->build_relids, owner_relids))
 			{
 				/*
-				 * Build side already sits with the owner; this shouldn't
-				 * normally happen (such a filter would have been resolved at
-				 * a lower join), but if it does, just propagate it unchanged.
-				 *
-				 * We still must be able to reach the owner's scan from above,
-				 * so the owner has to be on a side this join preserves (see
-				 * bloom_join_side_preserved); otherwise the filter could not
-				 * be pushed to a recipient and this path must be rejected.
+				 * We should not see a filter intersecting with the owner
+				 * We need all the build relids on the other side of the join,
+				 * and if the owner already has some, that can't happen.
 				 */
-				if (!bloom_join_side_preserved(jointype, owner_in_outer))
-					goto contradiction;
-				result = lappend(result, f);
+				goto contradiction;
 			}
 			else if (bms_is_subset(f->build_relids, join_relids))
 			{
-- 
2.55.0

