aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/optimizer/path/joinrels.c13
-rw-r--r--src/test/regress/expected/rangefuncs.out25
-rw-r--r--src/test/regress/sql/rangefuncs.sql15
3 files changed, 44 insertions, 9 deletions
diff --git a/src/backend/optimizer/path/joinrels.c b/src/backend/optimizer/path/joinrels.c
index 801458a60bf..e0cf2ee7ff9 100644
--- a/src/backend/optimizer/path/joinrels.c
+++ b/src/backend/optimizer/path/joinrels.c
@@ -609,6 +609,10 @@ join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
{
SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) lfirst(l);
+ /* ignore full joins --- their ordering is predetermined */
+ if (sjinfo->jointype == JOIN_FULL)
+ continue;
+
if (bms_overlap(sjinfo->min_lefthand, join_plus_rhs) &&
!bms_is_subset(sjinfo->min_righthand, join_plus_rhs))
{
@@ -616,15 +620,6 @@ join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
sjinfo->min_righthand);
more = true;
}
- /* full joins constrain both sides symmetrically */
- if (sjinfo->jointype == JOIN_FULL &&
- bms_overlap(sjinfo->min_righthand, join_plus_rhs) &&
- !bms_is_subset(sjinfo->min_lefthand, join_plus_rhs))
- {
- join_plus_rhs = bms_add_members(join_plus_rhs,
- sjinfo->min_lefthand);
- more = true;
- }
}
} while (more);
if (bms_overlap(join_plus_rhs, join_lateral_rels))
diff --git a/src/test/regress/expected/rangefuncs.out b/src/test/regress/expected/rangefuncs.out
index 6dabe503cc0..80aeba36873 100644
--- a/src/test/regress/expected/rangefuncs.out
+++ b/src/test/regress/expected/rangefuncs.out
@@ -1407,6 +1407,31 @@ SELECT * FROM (VALUES (1),(2),(3)) v1(r1),
3 | 3 | 30 | 8
(45 rows)
+-- check handling of FULL JOIN with multiple lateral references (bug #15741)
+SELECT *
+FROM (VALUES (1),(2)) v1(r1)
+ LEFT JOIN LATERAL (
+ SELECT *
+ FROM generate_series(1, v1.r1) AS gs1
+ LEFT JOIN LATERAL (
+ SELECT *
+ FROM generate_series(1, gs1) AS gs2
+ LEFT JOIN generate_series(1, gs2) AS gs3 ON TRUE
+ ) AS ss1 ON TRUE
+ FULL JOIN generate_series(1, v1.r1) AS gs4 ON FALSE
+ ) AS ss0 ON TRUE;
+ r1 | gs1 | gs2 | gs3 | gs4
+----+-----+-----+-----+-----
+ 1 | | | | 1
+ 1 | 1 | 1 | 1 |
+ 2 | | | | 1
+ 2 | | | | 2
+ 2 | 1 | 1 | 1 |
+ 2 | 2 | 1 | 1 |
+ 2 | 2 | 2 | 1 |
+ 2 | 2 | 2 | 2 |
+(8 rows)
+
DROP FUNCTION foo_sql(int,int);
DROP FUNCTION foo_mat(int,int);
DROP SEQUENCE foo_rescan_seq1;
diff --git a/src/test/regress/sql/rangefuncs.sql b/src/test/regress/sql/rangefuncs.sql
index 9484023f97b..d115a6b0942 100644
--- a/src/test/regress/sql/rangefuncs.sql
+++ b/src/test/regress/sql/rangefuncs.sql
@@ -321,6 +321,21 @@ SELECT * FROM (VALUES (1),(2),(3)) v1(r1),
LATERAL (SELECT r1, * FROM (VALUES (10),(20),(30)) v2(r2)
LEFT JOIN generate_series(r1,2+r2/5) f(i) ON ((r2+i)<100) OFFSET 0) s1;
+-- check handling of FULL JOIN with multiple lateral references (bug #15741)
+
+SELECT *
+FROM (VALUES (1),(2)) v1(r1)
+ LEFT JOIN LATERAL (
+ SELECT *
+ FROM generate_series(1, v1.r1) AS gs1
+ LEFT JOIN LATERAL (
+ SELECT *
+ FROM generate_series(1, gs1) AS gs2
+ LEFT JOIN generate_series(1, gs2) AS gs3 ON TRUE
+ ) AS ss1 ON TRUE
+ FULL JOIN generate_series(1, v1.r1) AS gs4 ON FALSE
+ ) AS ss0 ON TRUE;
+
DROP FUNCTION foo_sql(int,int);
DROP FUNCTION foo_mat(int,int);
DROP SEQUENCE foo_rescan_seq1;