Skip to content

Commit

Permalink
[PG15] Fix assertion failure on lateral_relids in foreign scan
Browse files Browse the repository at this point in the history
Summary:
`get_baserel_parampathinfo` expects `baserel->lateral_relids` to be a subset of `required_outer`. In PG11, `create_foreignscan_path` forcibly adds `lateral_relids` to `required_outer` if that is not the case already. This force addition is removed in upstream PG15 (commit hash is unavailable).

Consequently, foreign scan queries with lateral reference fail at assertion `Assert(bms_is_subset(baserel->lateral_relids, required_outer));`. This diff fixes the issue by passing the proper value for argument `required_outer` of function `create_foreignscan_path` from `ybcGetForeignPaths`.

Test Plan: Jenkins: rebase: pg15, test regex: org.yb.pgsql.TestPgRegress.*

Reviewers: jason

Reviewed By: jason

Subscribers: yql

Tags: #jenkins-ready

Differential Revision: https://phorge.dev.yugabyte.com/D29587
arpang committed Oct 24, 2023
1 parent f5398e9 commit 09554f7
Showing 3 changed files with 35 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/postgres/src/backend/executor/ybc_fdw.c
Original file line number Diff line number Diff line change
@@ -148,7 +148,7 @@ ybcGetForeignPaths(PlannerInfo *root,
startup_cost,
total_cost,
NIL, /* no pathkeys */
NULL, /* no outer rel either */
baserel->lateral_relids,
NULL, /* no extra plan */
NULL /* no options yet */ ));

24 changes: 24 additions & 0 deletions src/postgres/src/test/regress/expected/yb_pg15.out
Original file line number Diff line number Diff line change
@@ -485,3 +485,27 @@ SELECT last_value, is_called FROM public.serial_test_v_seq;
100 | t
(1 row)

-- lateral join
CREATE TABLE tlateral1 (a int, b int, c varchar);
INSERT INTO tlateral1 SELECT i, i % 25, to_char(i % 4, 'FM0000') FROM generate_series(0, 599, 2) i;
CREATE TABLE tlateral2 (a int, b int, c varchar);
INSERT INTO tlateral2 SELECT i % 25, i, to_char(i % 4, 'FM0000') FROM generate_series(0, 599, 3) i;
ANALYZE tlateral1, tlateral2;
-- YB_TODO: pg15 used merge join, whereas hash join is expected.
-- EXPLAIN (COSTS FALSE) SELECT * FROM tlateral1 t1 LEFT JOIN LATERAL (SELECT t2.a AS t2a, t2.c AS t2c, t2.b AS t2b, t3.b AS t3b, least(t1.a,t2.a,t3.b) FROM tlateral1 t2 JOIN tlateral2 t3 ON (t2.a = t3.b AND t2.c = t3.c)) ss ON t1.a = ss.t2a WHERE t1.b = 0 ORDER BY t1.a;
SELECT * FROM tlateral1 t1 LEFT JOIN LATERAL (SELECT t2.a AS t2a, t2.c AS t2c, t2.b AS t2b, t3.b AS t3b, least(t1.a,t2.a,t3.b) FROM tlateral1 t2 JOIN tlateral2 t3 ON (t2.a = t3.b AND t2.c = t3.c)) ss ON t1.a = ss.t2a WHERE t1.b = 0 ORDER BY t1.a;
a | b | c | t2a | t2c | t2b | t3b | least
-----+---+------+-----+------+-----+-----+-------
0 | 0 | 0000 | 0 | 0000 | 0 | 0 | 0
50 | 0 | 0002 | | | | |
100 | 0 | 0000 | | | | |
150 | 0 | 0002 | 150 | 0002 | 0 | 150 | 150
200 | 0 | 0000 | | | | |
250 | 0 | 0002 | | | | |
300 | 0 | 0000 | 300 | 0000 | 0 | 300 | 300
350 | 0 | 0002 | | | | |
400 | 0 | 0000 | | | | |
450 | 0 | 0002 | 450 | 0002 | 0 | 450 | 450
500 | 0 | 0000 | | | | |
550 | 0 | 0002 | | | | |
(12 rows)
10 changes: 10 additions & 0 deletions src/postgres/src/test/regress/sql/yb_pg15.sql
Original file line number Diff line number Diff line change
@@ -192,3 +192,13 @@ CREATE TABLE serial_test (k int, v SERIAL);
INSERT INTO serial_test VALUES (1), (1), (1);
SELECT * FROM serial_test ORDER BY v;
SELECT last_value, is_called FROM public.serial_test_v_seq;

-- lateral join
CREATE TABLE tlateral1 (a int, b int, c varchar);
INSERT INTO tlateral1 SELECT i, i % 25, to_char(i % 4, 'FM0000') FROM generate_series(0, 599, 2) i;
CREATE TABLE tlateral2 (a int, b int, c varchar);
INSERT INTO tlateral2 SELECT i % 25, i, to_char(i % 4, 'FM0000') FROM generate_series(0, 599, 3) i;
ANALYZE tlateral1, tlateral2;
-- YB_TODO: pg15 used merge join, whereas hash join is expected.
-- EXPLAIN (COSTS FALSE) SELECT * FROM tlateral1 t1 LEFT JOIN LATERAL (SELECT t2.a AS t2a, t2.c AS t2c, t2.b AS t2b, t3.b AS t3b, least(t1.a,t2.a,t3.b) FROM tlateral1 t2 JOIN tlateral2 t3 ON (t2.a = t3.b AND t2.c = t3.c)) ss ON t1.a = ss.t2a WHERE t1.b = 0 ORDER BY t1.a;
SELECT * FROM tlateral1 t1 LEFT JOIN LATERAL (SELECT t2.a AS t2a, t2.c AS t2c, t2.b AS t2b, t3.b AS t3b, least(t1.a,t2.a,t3.b) FROM tlateral1 t2 JOIN tlateral2 t3 ON (t2.a = t3.b AND t2.c = t3.c)) ss ON t1.a = ss.t2a WHERE t1.b = 0 ORDER BY t1.a;

0 comments on commit 09554f7

Please sign in to comment.