From 4c84f544931edec5b9dce346b150c0fbd7220de4 Mon Sep 17 00:00:00 2001 From: Bill Schaller Date: Thu, 19 Mar 2015 17:09:10 -0400 Subject: [PATCH] Fix failures on SQL Server due to scalar select items not having an alias --- .../Pagination/LimitSubqueryOutputWalker.php | 19 +++++++++++++++---- .../LimitSubqueryOutputWalkerTest.php | 10 +++++----- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php b/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php index 2366b5b63..8ff3630a5 100644 --- a/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php +++ b/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php @@ -13,6 +13,8 @@ namespace Doctrine\ORM\Tools\Pagination; +use Doctrine\ORM\Query\AST\ArithmeticExpression; +use Doctrine\ORM\Query\AST\ArithmeticTerm; use Doctrine\ORM\Query\AST\OrderByClause; use Doctrine\ORM\Query\AST\PartialObjectExpression; use Doctrine\ORM\Query\AST\PathExpression; @@ -353,18 +355,27 @@ class LimitSubqueryOutputWalker extends SqlWalker $replacements[] = $fieldAlias; } + $complexAddedOrderByAliases = 0; foreach($orderByClause->orderByItems as $orderByItem) { // Walk order by item to get string representation of it - $orderByItem = $this->walkOrderByItem($orderByItem); + $orderByItemString = $this->walkOrderByItem($orderByItem); // Replace path expressions in the order by clause with their column alias - $orderByItem = preg_replace($searchPatterns, $replacements, $orderByItem); + $orderByItemString = preg_replace($searchPatterns, $replacements, $orderByItemString); // The order by items are not required to be in the select list on Oracle and PostgreSQL, but // for the sake of simplicity, order by items will be included in the select list on all platforms. // This doesn't impact functionality. - $selectListAdditions[] = trim(preg_replace('/([^ ]+) (?:asc|desc)/i', '$1', $orderByItem)); - $orderByItems[] = $orderByItem; + $selectListAddition = trim(preg_replace('/([^ ]+) (?:asc|desc)/i', '$1', $orderByItemString)); + + // If the expression is an arithmetic expression, we need to create an alias for it. + if ($orderByItem->expression instanceof ArithmeticTerm) { + $orderByAlias = "ordr_" . $complexAddedOrderByAliases++; + $orderByItemString = $orderByAlias . " " . $orderByItem->type; + $selectListAddition .= " AS $orderByAlias"; + } + $selectListAdditions[] = $selectListAddition; + $orderByItems[] = $orderByItemString; } return array($selectListAdditions, $orderByItems); diff --git a/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php b/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php index 78394c603..c733c228b 100644 --- a/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php +++ b/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php @@ -208,7 +208,7 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubqueryOutputWalker'); $this->assertSame( - 'SELECT DISTINCT id_0, (1 - 1000) * 1 FROM (SELECT a0_.id AS id_0, a0_.name AS name_1 FROM Author a0_) dctrn_result ORDER BY (1 - 1000) * 1 DESC', + 'SELECT DISTINCT id_0, (1 - 1000) * 1 AS ordr_0 FROM (SELECT a0_.id AS id_0, a0_.name AS name_1 FROM Author a0_) dctrn_result ORDER BY ordr_0 DESC', $query->getSQL() ); } @@ -223,7 +223,7 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubqueryOutputWalker'); $this->assertSame( - 'SELECT DISTINCT id_0, image_height_2 * image_width_3 FROM (SELECT a0_.id AS id_0, a0_.image AS image_1, a0_.image_height AS image_height_2, a0_.image_width AS image_width_3, a0_.image_alt_desc AS image_alt_desc_4, a0_.user_id AS user_id_5 FROM Avatar a0_) dctrn_result ORDER BY image_height_2 * image_width_3 DESC', + 'SELECT DISTINCT id_0, image_height_2 * image_width_3 AS ordr_0 FROM (SELECT a0_.id AS id_0, a0_.image AS image_1, a0_.image_height AS image_height_2, a0_.image_width AS image_width_3, a0_.image_alt_desc AS image_alt_desc_4, a0_.user_id AS user_id_5 FROM Avatar a0_) dctrn_result ORDER BY ordr_0 DESC', $query->getSQL() ); } @@ -238,7 +238,7 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubqueryOutputWalker'); $this->assertSame( - 'SELECT DISTINCT id_0, image_height_1 * image_width_2 FROM (SELECT u0_.id AS id_0, a1_.image_height AS image_height_1, a1_.image_width AS image_width_2, a1_.user_id AS user_id_3 FROM User u0_ INNER JOIN Avatar a1_ ON u0_.id = a1_.user_id) dctrn_result ORDER BY image_height_1 * image_width_2 DESC', + 'SELECT DISTINCT id_0, image_height_1 * image_width_2 AS ordr_0 FROM (SELECT u0_.id AS id_0, a1_.image_height AS image_height_1, a1_.image_width AS image_width_2, a1_.user_id AS user_id_3 FROM User u0_ INNER JOIN Avatar a1_ ON u0_.id = a1_.user_id) dctrn_result ORDER BY ordr_0 DESC', $query->getSQL() ); } @@ -253,7 +253,7 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubqueryOutputWalker'); $this->assertSame( - 'SELECT DISTINCT id_0, image_height_3 * image_width_4 FROM (SELECT u0_.id AS id_0, a1_.id AS id_1, a1_.image_alt_desc AS image_alt_desc_2, a1_.image_height AS image_height_3, a1_.image_width AS image_width_4, a1_.user_id AS user_id_5 FROM User u0_ INNER JOIN Avatar a1_ ON u0_.id = a1_.user_id) dctrn_result ORDER BY image_height_3 * image_width_4 DESC', + 'SELECT DISTINCT id_0, image_height_3 * image_width_4 AS ordr_0 FROM (SELECT u0_.id AS id_0, a1_.id AS id_1, a1_.image_alt_desc AS image_alt_desc_2, a1_.image_height AS image_height_3, a1_.image_width AS image_width_4, a1_.user_id AS user_id_5 FROM User u0_ INNER JOIN Avatar a1_ ON u0_.id = a1_.user_id) dctrn_result ORDER BY ordr_0 DESC', $query->getSQL() ); } @@ -268,7 +268,7 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubqueryOutputWalker'); $this->assertSame( - 'SELECT DISTINCT ID_0, IMAGE_HEIGHT_2 * IMAGE_WIDTH_3 FROM (SELECT a0_.id AS ID_0, a0_.image AS IMAGE_1, a0_.image_height AS IMAGE_HEIGHT_2, a0_.image_width AS IMAGE_WIDTH_3, a0_.image_alt_desc AS IMAGE_ALT_DESC_4, a0_.user_id AS USER_ID_5 FROM Avatar a0_) dctrn_result ORDER BY IMAGE_HEIGHT_2 * IMAGE_WIDTH_3 DESC', + 'SELECT DISTINCT ID_0, IMAGE_HEIGHT_2 * IMAGE_WIDTH_3 AS ordr_0 FROM (SELECT a0_.id AS ID_0, a0_.image AS IMAGE_1, a0_.image_height AS IMAGE_HEIGHT_2, a0_.image_width AS IMAGE_WIDTH_3, a0_.image_alt_desc AS IMAGE_ALT_DESC_4, a0_.user_id AS USER_ID_5 FROM Avatar a0_) dctrn_result ORDER BY ordr_0 DESC', $query->getSQL() ); }