@@ -2091,6 +2091,95 @@ SELECT (SELECT v FROM (SELECT 1 AS v UNION ALL SELECT 2) AS t ORDER BY v LIMIT 1
20912091----
209220921
20932093
2094+ #############
2095+ ## End-to-end correctness coverage for the flag-off path.
2096+ ## When `datafusion.optimizer.physical_uncorrelated_scalar_subquery` is false,
2097+ ## uncorrelated scalar subqueries are rewritten to left joins by
2098+ ## `ScalarSubqueryToJoin` instead of executed by `ScalarSubqueryExec`. This
2099+ ## restores pre-PR-21240 behavior, which has three known shortcomings the
2100+ ## physical-execution path was built to fix: multi-row subqueries silently
2101+ ## return wrong results, and uncorrelated scalar subqueries do not work in
2102+ ## ORDER BY / JOIN ON / aggregate-function arguments. Those cases are
2103+ ## intentionally not covered here; the queries below are the ones where both
2104+ ## paths agree.
2105+ #############
2106+
2107+ statement ok
2108+ set datafusion.optimizer.physical_uncorrelated_scalar_subquery = false;
2109+
2110+ # Scalar subquery returning exactly one row → success
2111+ query I
2112+ SELECT (SELECT v FROM sq_values LIMIT 1);
2113+ ----
2114+ 1
2115+
2116+ # Scalar subquery returning exactly one row in WHERE → success
2117+ query I rowsort
2118+ SELECT x FROM sq_main WHERE x > (SELECT v FROM sq_values LIMIT 1);
2119+ ----
2120+ 10
2121+ 20
2122+
2123+ # Scalar subquery returning zero rows → NULL
2124+ query I
2125+ SELECT (SELECT v FROM sq_empty);
2126+ ----
2127+ NULL
2128+
2129+ # Scalar subquery returning zero rows in arithmetic → NULL propagation
2130+ query I
2131+ SELECT x + (SELECT v FROM sq_empty) FROM sq_main;
2132+ ----
2133+ NULL
2134+ NULL
2135+
2136+ # Scalar subquery returning zero rows in WHERE comparison → no matching rows
2137+ query I
2138+ SELECT x FROM sq_main WHERE x > (SELECT v FROM sq_empty);
2139+ ----
2140+
2141+ # Aggregated subquery always returns one row, even on empty input → success
2142+ query I
2143+ SELECT (SELECT count(*) FROM sq_empty);
2144+ ----
2145+ 0
2146+
2147+ # Aggregated subquery on multi-row table → success
2148+ query I
2149+ SELECT (SELECT max(v) FROM sq_values);
2150+ ----
2151+ 3
2152+
2153+ # HAVING clause with uncorrelated scalar subquery
2154+ query II rowsort
2155+ SELECT x, count(*) AS cnt FROM sq_main GROUP BY x
2156+ HAVING count(*) > (SELECT min(v) FROM sq_values);
2157+ ----
2158+
2159+ # CASE WHEN with uncorrelated scalar subquery as condition
2160+ query T rowsort
2161+ SELECT CASE WHEN x > (SELECT min(v) FROM sq_values)
2162+ THEN 'big' ELSE 'small' END AS label
2163+ FROM sq_main;
2164+ ----
2165+ big
2166+ big
2167+
2168+ # Doubly-nested constant subquery
2169+ query I
2170+ SELECT (SELECT (SELECT 42));
2171+ ----
2172+ 42
2173+
2174+ # NULL comparison semantics through subquery boundary
2175+ query B
2176+ SELECT 1 = (SELECT CAST(NULL AS INT));
2177+ ----
2178+ NULL
2179+
2180+ statement ok
2181+ RESET datafusion.optimizer.physical_uncorrelated_scalar_subquery;
2182+
20942183statement count 0
20952184DROP TABLE sq_values;
20962185
0 commit comments