Undo faulty attempt at not relying on RINFO_IS_PUSHED_DOWN.
authorTom Lane <[email protected]>
Thu, 11 May 2023 17:44:25 +0000 (13:44 -0400)
committerTom Lane <[email protected]>
Thu, 11 May 2023 17:44:25 +0000 (13:44 -0400)
I've had a bee in my bonnet for some time about getting rid of
RestrictInfo.is_pushed_down, because it's squishily defined and
requires not-inexpensive extra tests to use (cf RINFO_IS_PUSHED_DOWN).
In commit 2489d76c4, I tried to make remove_rel_from_query() not
depend on that macro; but the replacement test is buggy,
as exposed by a report from Rushabh Lathia and Robert Haas.
That change was pretty incidental to the main goal of 2489d76c4,
so let's just revert it for now.  (Getting rid of is_pushed_down
is still far away, anyway.)

Discussion: https://postgr.es/m/CA+TgmoYco=hmg+iX1CW9Y1_CzNoSL81J03wUG-d2_3=rue+L2A@mail.gmail.com

src/backend/optimizer/plan/analyzejoins.c
src/test/regress/expected/join.out
src/test/regress/sql/join.sql

index 98cf3494e6fc454f36814b556aa34be1b2e431ca..657b6e59074a97577b62b2fa792d4271a577e305 100644 (file)
@@ -466,12 +466,7 @@ remove_rel_from_query(PlannerInfo *root, int relid, int ojrelid,
 
                remove_join_clause_from_rels(root, rinfo, rinfo->required_relids);
 
-               /*
-                * If the qual lists ojrelid in its required_relids, it must have come
-                * from above the outer join we're removing (so we need to keep it);
-                * if it does not, then it didn't and we can discard it.
-                */
-               if (bms_is_member(ojrelid, rinfo->required_relids))
+               if (RINFO_IS_PUSHED_DOWN(rinfo, joinrelids))
                {
                        /*
                         * There might be references to relid or ojrelid in the
index 5d59ed7890f0c6c6d834d60e8d0a4f7ffe353f05..b5f440e43e53c4eab86829a2986d8863b454170a 100644 (file)
@@ -5320,6 +5320,22 @@ select 1 from (select a.id FROM a left join b on a.b_id = b.id) q,
          Filter: (a.id = i)
 (4 rows)
 
+-- check join removal within RHS of an outer join
+explain (costs off)
+select c.id, ss.a from c
+  left join (select d.a from onerow, d left join b on d.a = b.id) ss
+  on c.id = ss.a;
+           QUERY PLAN           
+--------------------------------
+ Hash Right Join
+   Hash Cond: (d.a = c.id)
+   ->  Nested Loop
+         ->  Seq Scan on onerow
+         ->  Seq Scan on d
+   ->  Hash
+         ->  Seq Scan on c
+(7 rows)
+
 CREATE TEMP TABLE parted_b (id int PRIMARY KEY) partition by range(id);
 CREATE TEMP TABLE parted_b1 partition of parted_b for values from (0) to (10);
 -- test join removals on a partitioned table
index a630f58b57180aa4c741858bd219090bde5aa893..437934e80b6d4ac76b6e0c945b9ae3c75344fa7d 100644 (file)
@@ -1927,6 +1927,12 @@ explain (costs off)
 select 1 from (select a.id FROM a left join b on a.b_id = b.id) q,
                          lateral generate_series(1, q.id) gs(i) where q.id = gs.i;
 
+-- check join removal within RHS of an outer join
+explain (costs off)
+select c.id, ss.a from c
+  left join (select d.a from onerow, d left join b on d.a = b.id) ss
+  on c.id = ss.a;
+
 CREATE TEMP TABLE parted_b (id int PRIMARY KEY) partition by range(id);
 CREATE TEMP TABLE parted_b1 partition of parted_b for values from (0) to (10);