Skip to content

Commit 3bef56e

Browse files
committed
Invent "join domains" to replace the below_outer_join hack.
EquivalenceClasses are now understood as applying within a "join domain", which is a set of inner-joined relations (possibly underneath an outer join). We no longer need to treat an EC from below an outer join as a second-class citizen. I have hopes of eventually being able to treat outer-join clauses via EquivalenceClasses, by means of only applying deductions within the EC's join domain. There are still problems in the way of that, though, so for now the reconsider_outer_join_clause logic is still here. I haven't been able to get rid of RestrictInfo.is_pushed_down either, but I wonder if that could be recast using JoinDomains. I had to hack one test case in postgres_fdw.sql to make it still test what it was meant to, because postgres_fdw is inconsistent about how it deals with quals containing non-shippable expressions; see https://postgr.es/m/1691374.1671659838@sss.pgh.pa.us. That should be improved, but I don't think it's within the scope of this patch series. Patch by me; thanks to Richard Guo for review. Discussion: https://postgr.es/m/830269.1656693747@sss.pgh.pa.us
1 parent b448f1c commit 3bef56e

File tree

12 files changed

+269
-193
lines changed

12 files changed

+269
-193
lines changed

contrib/postgres_fdw/expected/postgres_fdw.out

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2513,7 +2513,7 @@ SELECT * FROM local_tbl LEFT JOIN (SELECT ft1.*, COALESCE(ft1.c3 || ft2.c3, 'foo
25132513
ALTER SERVER loopback OPTIONS (DROP extensions);
25142514
ALTER SERVER loopback OPTIONS (ADD fdw_startup_cost '10000.0');
25152515
EXPLAIN (VERBOSE, COSTS OFF)
2516-
SELECT * FROM local_tbl LEFT JOIN (SELECT ft1.* FROM ft1 INNER JOIN ft2 ON (ft1.c1 = ft2.c1 AND ft1.c1 < 100 AND ft1.c1 = postgres_fdw_abs(ft2.c2))) ss ON (local_tbl.c3 = ss.c3) ORDER BY local_tbl.c1 FOR UPDATE OF local_tbl;
2516+
SELECT * FROM local_tbl LEFT JOIN (SELECT ft1.* FROM ft1 INNER JOIN ft2 ON (ft1.c1 = ft2.c1 AND ft1.c1 < 100 AND (ft1.c1 - postgres_fdw_abs(ft2.c2)) = 0)) ss ON (local_tbl.c3 = ss.c3) ORDER BY local_tbl.c1 FOR UPDATE OF local_tbl;
25172517
QUERY PLAN
25182518
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
25192519
LockRows
@@ -2527,26 +2527,26 @@ SELECT * FROM local_tbl LEFT JOIN (SELECT ft1.* FROM ft1 INNER JOIN ft2 ON (ft1.
25272527
Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft1.*, ft2.*
25282528
-> Foreign Scan
25292529
Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft1.*, ft2.*
2530-
Filter: (ft1.c1 = postgres_fdw_abs(ft2.c2))
2530+
Filter: ((ft1.c1 - postgres_fdw_abs(ft2.c2)) = 0)
25312531
Relations: (public.ft1) INNER JOIN (public.ft2)
25322532
Remote SQL: SELECT r4."C 1", r4.c2, r4.c3, r4.c4, r4.c5, r4.c6, r4.c7, r4.c8, CASE WHEN (r4.*)::text IS NOT NULL THEN ROW(r4."C 1", r4.c2, r4.c3, r4.c4, r4.c5, r4.c6, r4.c7, r4.c8) END, CASE WHEN (r5.*)::text IS NOT NULL THEN ROW(r5."C 1", r5.c2, r5.c3, r5.c4, r5.c5, r5.c6, r5.c7, r5.c8) END, r5.c2 FROM ("S 1"."T 1" r4 INNER JOIN "S 1"."T 1" r5 ON (((r5."C 1" = r4."C 1")) AND ((r4."C 1" < 100)))) ORDER BY r4.c3 ASC NULLS LAST
25332533
-> Sort
25342534
Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft1.*, ft2.*, ft2.c2
25352535
Sort Key: ft1.c3
25362536
-> Merge Join
25372537
Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft1.*, ft2.*, ft2.c2
2538-
Merge Cond: ((ft1.c1 = (postgres_fdw_abs(ft2.c2))) AND (ft1.c1 = ft2.c1))
2538+
Merge Cond: (ft1.c1 = ft2.c1)
2539+
Join Filter: ((ft1.c1 - postgres_fdw_abs(ft2.c2)) = 0)
25392540
-> Sort
25402541
Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft1.*
25412542
Sort Key: ft1.c1
25422543
-> Foreign Scan on public.ft1
25432544
Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft1.*
25442545
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" < 100))
2545-
-> Sort
2546-
Output: ft2.*, ft2.c1, ft2.c2, (postgres_fdw_abs(ft2.c2))
2547-
Sort Key: (postgres_fdw_abs(ft2.c2)), ft2.c1
2546+
-> Materialize
2547+
Output: ft2.*, ft2.c1, ft2.c2
25482548
-> Foreign Scan on public.ft2
2549-
Output: ft2.*, ft2.c1, ft2.c2, postgres_fdw_abs(ft2.c2)
2549+
Output: ft2.*, ft2.c1, ft2.c2
25502550
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" ORDER BY "C 1" ASC NULLS LAST
25512551
(32 rows)
25522552

contrib/postgres_fdw/sql/postgres_fdw.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -681,7 +681,7 @@ SELECT * FROM local_tbl LEFT JOIN (SELECT ft1.*, COALESCE(ft1.c3 || ft2.c3, 'foo
681681
ALTER SERVER loopback OPTIONS (DROP extensions);
682682
ALTER SERVER loopback OPTIONS (ADD fdw_startup_cost '10000.0');
683683
EXPLAIN (VERBOSE, COSTS OFF)
684-
SELECT * FROM local_tbl LEFT JOIN (SELECT ft1.* FROM ft1 INNER JOIN ft2 ON (ft1.c1 = ft2.c1 AND ft1.c1 < 100 AND ft1.c1 = postgres_fdw_abs(ft2.c2))) ss ON (local_tbl.c3 = ss.c3) ORDER BY local_tbl.c1 FOR UPDATE OF local_tbl;
684+
SELECT * FROM local_tbl LEFT JOIN (SELECT ft1.* FROM ft1 INNER JOIN ft2 ON (ft1.c1 = ft2.c1 AND ft1.c1 < 100 AND (ft1.c1 - postgres_fdw_abs(ft2.c2)) = 0)) ss ON (local_tbl.c3 = ss.c3) ORDER BY local_tbl.c1 FOR UPDATE OF local_tbl;
685685
ALTER SERVER loopback OPTIONS (DROP fdw_startup_cost);
686686
ALTER SERVER loopback OPTIONS (ADD extensions 'postgres_fdw');
687687

src/backend/nodes/outfuncs.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,6 @@ _outEquivalenceClass(StringInfo str, const EquivalenceClass *node)
468468
WRITE_BITMAPSET_FIELD(ec_relids);
469469
WRITE_BOOL_FIELD(ec_has_const);
470470
WRITE_BOOL_FIELD(ec_has_volatile);
471-
WRITE_BOOL_FIELD(ec_below_outer_join);
472471
WRITE_BOOL_FIELD(ec_broken);
473472
WRITE_UINT_FIELD(ec_sortref);
474473
WRITE_UINT_FIELD(ec_min_security);

0 commit comments

Comments
 (0)