@@ -1409,6 +1409,57 @@ public function testSelectOrderByAmbiguousColumnResolution(): void {
14091409 'SELECT `t1`.`name` AS `t1_name` FROM `t1` JOIN `t2` ON `t2`.`id` = `t1`.`id` ORDER BY `t1_name` DESC ' ,
14101410 'SELECT t1.name AS t1_name FROM t1 JOIN t2 ON t2.id = t1.id ORDER BY `t1_name` DESC '
14111411 );
1412+
1413+ // With a parenthesized query body, the column should be disambiguated.
1414+ $ this ->assertQuery (
1415+ '( ( ( SELECT `t1`.`name` FROM `t1` ) ) ) ORDER BY `t1`.`name` ' ,
1416+ '(((SELECT t1.name FROM t1))) ORDER BY name '
1417+ );
1418+
1419+ // The root query should not disambiguate from a nested SELECT item.
1420+ $ this ->assertQuery (
1421+ 'SELECT ( SELECT `t1`.`name` FROM `t1` ) AS `t1_name` ORDER BY `name` ' ,
1422+ 'SELECT (SELECT t1.name FROM t1) AS t1_name ORDER BY name '
1423+ );
1424+
1425+ // With UNION, the column should not be disambiguated.
1426+ $ this ->assertQuery (
1427+ 'SELECT `t1`.`name` FROM `t1` UNION ALL SELECT `t2`.`name` FROM `t2` ORDER BY `name` ' ,
1428+ 'SELECT t1.name FROM t1 UNION ALL SELECT t2.name FROM t2 ORDER BY name '
1429+ );
1430+
1431+ // With EXCEPT, the column should not be disambiguated.
1432+ $ this ->assertQuery (
1433+ 'SELECT `t1`.`name` FROM `t1` EXCEPT SELECT `t2`.`name` FROM `t2` ORDER BY `name` ' ,
1434+ 'SELECT t1.name FROM t1 EXCEPT SELECT t2.name FROM t2 ORDER BY name '
1435+ );
1436+
1437+ // With INTERSECT, the column should not be disambiguated.
1438+ $ this ->assertQuery (
1439+ 'SELECT `t1`.`name` FROM `t1` INTERSECT SELECT `t2`.`name` FROM `t2` ORDER BY `name` ' ,
1440+ 'SELECT t1.name FROM t1 INTERSECT SELECT t2.name FROM t2 ORDER BY name '
1441+ );
1442+
1443+ // Test a complex query with CTEs.
1444+ $ this ->assertQuery (
1445+ 'WITH '
1446+ . " `cte1` ( `name` ) AS ( SELECT 'a' UNION ALL SELECT 'b' ) , "
1447+ . ' `cte2` ( `name` ) AS ( SELECT `t2`.`name` FROM `t2` JOIN `t1` ON `t1`.`id` = `t2`.`id` ORDER BY `t2`.`name` ) '
1448+ . ' SELECT `t1`.`name` , ( SELECT `name` FROM `cte1` WHERE `id` = 1 ) AS `cte1_name` , ( SELECT `name` FROM `cte2` WHERE `id` = 2 ) AS `cte2_name` '
1449+ . ' FROM `t1` '
1450+ . ' ORDER BY `t1`.`name` ' ,
1451+ "
1452+ WITH
1453+ cte1(name) AS (SELECT 'a' UNION ALL SELECT 'b'),
1454+ cte2(name) AS (SELECT t2.name FROM t2 JOIN t1 ON t1.id = t2.id ORDER BY name)
1455+ SELECT
1456+ t1.name,
1457+ (SELECT name FROM cte1 WHERE id = 1) AS cte1_name,
1458+ (SELECT name FROM cte2 WHERE id = 2) AS cte2_name
1459+ FROM t1
1460+ ORDER BY name
1461+ "
1462+ );
14121463 }
14131464
14141465 public function testSelectGroupByAmbiguousColumnResolution (): void {
@@ -1494,6 +1545,24 @@ public function testSelectGroupByAmbiguousColumnResolution(): void {
14941545 'SELECT `t1`.`name` AS `t1_name` FROM `t1` JOIN `t2` ON `t2`.`id` = `t1`.`id` GROUP BY `t1_name` ' ,
14951546 'SELECT t1.name AS t1_name FROM t1 JOIN t2 ON t2.id = t1.id GROUP BY `t1_name` '
14961547 );
1548+
1549+ // With UNION, the column should be disambiguated in its subquery (differs from ORDER BY).
1550+ $ this ->assertQuery (
1551+ 'SELECT `t1`.`name` FROM `t1` UNION ALL SELECT `t2`.`name` FROM `t2` GROUP BY `t2`.`name` ' ,
1552+ 'SELECT t1.name FROM t1 UNION ALL SELECT t2.name FROM t2 GROUP BY name '
1553+ );
1554+
1555+ // With EXCEPT, the column should be disambiguated in its subquery (differs from ORDER BY).
1556+ $ this ->assertQuery (
1557+ 'SELECT `t1`.`name` FROM `t1` EXCEPT SELECT `t2`.`name` FROM `t2` GROUP BY `t2`.`name` ' ,
1558+ 'SELECT t1.name FROM t1 EXCEPT SELECT t2.name FROM t2 GROUP BY name '
1559+ );
1560+
1561+ // With INTERSECT, the column should be disambiguated in its subquery (differs from ORDER BY).
1562+ $ this ->assertQuery (
1563+ 'SELECT `t1`.`name` FROM `t1` INTERSECT SELECT `t2`.`name` FROM `t2` GROUP BY `t2`.`name` ' ,
1564+ 'SELECT t1.name FROM t1 INTERSECT SELECT t2.name FROM t2 GROUP BY name '
1565+ );
14971566 }
14981567
14991568 public function testSelectHavingAmbiguousColumnResolution (): void {
@@ -1581,6 +1650,24 @@ public function testSelectHavingAmbiguousColumnResolution(): void {
15811650 'SELECT `t1`.`name` FROM `t1` JOIN `t2` ON `t2`.`id` = `t1`.`id` GROUP BY 1 HAVING `name` = 1 ' ,
15821651 'SELECT t1.name FROM t1 JOIN t2 ON t2.id = t1.id HAVING name = 1 '
15831652 );
1653+
1654+ // With UNION, the column should be disambiguated in its subquery (differs from ORDER BY).
1655+ $ this ->assertQuery (
1656+ 'SELECT `t1`.`name` FROM `t1` UNION ALL SELECT `t2`.`name` FROM `t2` GROUP BY 1 HAVING `t2`.`name` ' ,
1657+ 'SELECT t1.name FROM t1 UNION ALL SELECT t2.name FROM t2 HAVING name '
1658+ );
1659+
1660+ // With EXCEPT, the column should be disambiguated in its subquery (differs from ORDER BY).
1661+ $ this ->assertQuery (
1662+ 'SELECT `t1`.`name` FROM `t1` EXCEPT SELECT `t2`.`name` FROM `t2` GROUP BY 1 HAVING `t2`.`name` ' ,
1663+ 'SELECT t1.name FROM t1 EXCEPT SELECT t2.name FROM t2 HAVING name '
1664+ );
1665+
1666+ // With INTERSECT, the column should be disambiguated in its subquery (differs from ORDER BY).
1667+ $ this ->assertQuery (
1668+ 'SELECT `t1`.`name` FROM `t1` INTERSECT SELECT `t2`.`name` FROM `t2` GROUP BY 1 HAVING `t2`.`name` ' ,
1669+ 'SELECT t1.name FROM t1 INTERSECT SELECT t2.name FROM t2 HAVING name '
1670+ );
15841671 }
15851672
15861673 private function assertQuery ( $ expected , string $ query ): void {
0 commit comments