diff --git a/sqlglot/optimizer/unnest_subqueries.py b/sqlglot/optimizer/unnest_subqueries.py index f88a520f46..a56ad06db9 100644 --- a/sqlglot/optimizer/unnest_subqueries.py +++ b/sqlglot/optimizer/unnest_subqueries.py @@ -193,6 +193,11 @@ def decorrelate(select, parent_select, external_columns, next_alias_name): parent_predicate = select.find_ancestor(exp.Predicate) + # When the subquery is embedded inside a function (e.g. COALESCE, TRIM) in the SELECT list, + # the ancestor chain contains no Predicate node AND the subquery is not a direct projection. + if parent_predicate is None and not is_subquery_projection: + return + # if the value of the subquery is not an agg or a key, we need to collect it into an array # so that it can be grouped. For subquery projections, we use a MAX aggregation instead. agg_func = exp.Max if is_subquery_projection else exp.ArrayAgg diff --git a/tests/fixtures/optimizer/unnest_subqueries.sql b/tests/fixtures/optimizer/unnest_subqueries.sql index ebe1c0b2da..5e778c015f 100644 --- a/tests/fixtures/optimizer/unnest_subqueries.sql +++ b/tests/fixtures/optimizer/unnest_subqueries.sql @@ -109,3 +109,7 @@ WITH t2 AS (SELECT t1.c1 FROM UNNEST((SELECT ARRAY(x.a) FROM x)) AS t1(c1)) SELE # title: Skip unnesting GENERATE_SERIES but unnesting the rest in the query SELECT t1.c1 > (SELECT SUM(y.a) AS b FROM y) FROM x JOIN GENERATE_SERIES((SELECT MAX(x.a) FROM x AS x), 10, 1) AS t1(c1) ON t1.c1 > x.a; SELECT t1.c1 > _u_0.b FROM x JOIN GENERATE_SERIES((SELECT MAX(x.a) FROM x AS x), 10, 1) AS t1(c1) ON t1.c1 > x.a CROSS JOIN (SELECT SUM(y.a) AS b FROM y) AS _u_0; + +# title: correlated scalar subquery with EQ + range predicates inside a function in SELECT should not crash (issue #7295) +SELECT COALESCE((SELECT MAX(b.val) FROM t b WHERE b.val < a.val AND b.id = a.id), a.val) AS result FROM t a; +SELECT COALESCE((SELECT MAX(b.val) FROM t AS b WHERE b.val < a.val AND b.id = a.id), a.val) AS result FROM t AS a;