diff --git a/src/backend/optimizer/path/pathkeys.c b/src/backend/optimizer/path/pathkeys.c index 5eb71635d15..c87793d9ad8 100644 --- a/src/backend/optimizer/path/pathkeys.c +++ b/src/backend/optimizer/path/pathkeys.c @@ -1262,10 +1262,18 @@ find_var_for_subquery_tle(RelOptInfo *rel, TargetEntry *tle) { Var *var = (Var *) lfirst(lc); - /* Ignore placeholders */ + /* Ignore placeholders and other non-Var expressions */ if (!IsA(var, Var)) continue; - Assert(var->varno == rel->relid); + + /* + * Ordinarily, a Var in a rel's targetlist must belong to that rel; + * but there are corner cases involving LATERAL references where that + * isn't so. If the Var has the wrong varno, ignore it, since it + * cannot be referencing the subquery's output. + */ + if (var->varno != rel->relid) + continue; /* If we find a Var referencing this TLE, we're good */ if (var->varattno == tle->resno) diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out index a13b0469ec0..d289e53a039 100644 --- a/src/test/regress/expected/join.out +++ b/src/test/regress/expected/join.out @@ -9591,6 +9591,24 @@ select * from generate_series(100,200) g, 123 | 4567890123456789 | 123 (3 rows) +-- lateral with UNION ALL subselect, where a member is a subquery whose +-- output contains a lateral reference +explain (costs off) + select ss.v from int8_tbl x, + lateral (select x.q1 from (select distinct q2 from int8_tbl) s union all + select q2 from int8_tbl) ss(v); + QUERY PLAN +--------------------------------------------------------- + Nested Loop + -> Seq Scan on int8_tbl x + -> Append + -> Subquery Scan on s + -> HashAggregate + Group Key: int8_tbl_1.q2 + -> Seq Scan on int8_tbl int8_tbl_1 + -> Seq Scan on int8_tbl +(8 rows) + -- lateral with VALUES explain (costs off) select count(*) from tenk1 a, diff --git a/src/test/regress/sql/join.sql b/src/test/regress/sql/join.sql index a40a4b853f4..4dcf185a6eb 100644 --- a/src/test/regress/sql/join.sql +++ b/src/test/regress/sql/join.sql @@ -3754,6 +3754,13 @@ select * from generate_series(100,200) g, lateral (select * from int8_tbl a where g = q1 union all select * from int8_tbl b where g = q2) ss; +-- lateral with UNION ALL subselect, where a member is a subquery whose +-- output contains a lateral reference +explain (costs off) + select ss.v from int8_tbl x, + lateral (select x.q1 from (select distinct q2 from int8_tbl) s union all + select q2 from int8_tbl) ss(v); + -- lateral with VALUES explain (costs off) select count(*) from tenk1 a,