From 91408a3a54c007be72f2f1f65d4b694f90dd28c4 Mon Sep 17 00:00:00 2001 From: Pierre-Louis FORT Date: Thu, 9 Nov 2017 14:10:36 +0100 Subject: [PATCH] #6819 Optimize LimitSubqueryWalker when resultVariable are involved and they are not used in "order by" --- .../Tools/Pagination/LimitSubqueryWalker.php | 31 ++++++++----------- .../Pagination/LimitSubqueryWalkerTest.php | 30 +++++++++++++++++- 2 files changed, 42 insertions(+), 19 deletions(-) diff --git a/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryWalker.php b/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryWalker.php index aceeb5c09..fd90a27f2 100644 --- a/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryWalker.php +++ b/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryWalker.php @@ -69,18 +69,8 @@ class LimitSubqueryWalker extends TreeWalkerAdapter $fromRoot = reset($from); $rootAlias = $fromRoot->rangeVariableDeclaration->aliasIdentificationVariable; $rootClass = $queryComponents[$rootAlias]['metadata']; - $selectExpressions = []; $this->validate($AST); - - foreach ($queryComponents as $dqlAlias => $qComp) { - // Preserve mixed data in query for ordering. - if (isset($qComp['resultVariable'])) { - $selectExpressions[] = new SelectExpression($qComp['resultVariable'], $dqlAlias); - continue; - } - } - $identifier = $rootClass->getSingleIdentifierFieldName(); if (isset($rootClass->associationMappings[$identifier])) { @@ -100,20 +90,25 @@ class LimitSubqueryWalker extends TreeWalkerAdapter $pathExpression->type = PathExpression::TYPE_STATE_FIELD; - array_unshift($selectExpressions, new SelectExpression($pathExpression, '_dctrn_id')); - - $AST->selectClause->selectExpressions = $selectExpressions; + $AST->selectClause->selectExpressions = array(new SelectExpression($pathExpression, '_dctrn_id')); if (isset($AST->orderByClause)) { foreach ($AST->orderByClause->orderByItems as $item) { if ( ! $item->expression instanceof PathExpression) { - continue; + if(isset($queryComponents[$item->expression])) { + $qComp = $queryComponents[$item->expression]; + if (isset($qComp['resultVariable'])) { + $AST->selectClause->selectExpressions[] = new SelectExpression($qComp['resultVariable'], $item->expression); + } + } + } else { + + $AST->selectClause->selectExpressions[] = new SelectExpression( + $this->createSelectExpressionItem($item->expression), + '_dctrn_ord' . $this->_aliasCounter++ + ); } - $AST->selectClause->selectExpressions[] = new SelectExpression( - $this->createSelectExpressionItem($item->expression), - '_dctrn_ord' . $this->_aliasCounter++ - ); } } diff --git a/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryWalkerTest.php b/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryWalkerTest.php index 8ddc158b9..7bde63895 100644 --- a/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryWalkerTest.php +++ b/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryWalkerTest.php @@ -47,7 +47,35 @@ class LimitSubqueryWalkerTest extends PaginationTestCase $limitQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, [LimitSubqueryWalker::class]); $this->assertEquals( - "SELECT DISTINCT a0_.id AS id_0, sum(a0_.name) AS sclr_1 FROM Author a0_", + "SELECT DISTINCT a0_.id AS id_0 FROM Author a0_", + $limitQuery->getSQL() + ); + } + + public function testAggQuery_MixedResultsWithNameAndSort() + { + $dql = 'SELECT a, sum(a.name) as foo FROM Doctrine\Tests\ORM\Tools\Pagination\Author a ORDER BY foo DESC'; + $query = $this->entityManager->createQuery($dql); + $limitQuery = clone $query; + + $limitQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, [LimitSubqueryWalker::class]); + + $this->assertEquals( + "SELECT DISTINCT a0_.id AS id_0, sum(a0_.name) AS sclr_1 FROM Author a0_ ORDER BY sclr_1 DESC", + $limitQuery->getSQL() + ); + } + + public function testAggQuery_MultipleMixedResultsWithSort() + { + $dql = 'SELECT a, sum(a.name) as foo, (SELECT count(subA.id) FROM Doctrine\Tests\ORM\Tools\Pagination\Author subA WHERE subA.id = a.id ) as bar FROM Doctrine\Tests\ORM\Tools\Pagination\Author a ORDER BY foo DESC, bar ASC'; + $query = $this->entityManager->createQuery($dql); + $limitQuery = clone $query; + + $limitQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, [LimitSubqueryWalker::class]); + + $this->assertEquals( + "SELECT DISTINCT a0_.id AS id_0, sum(a0_.name) AS sclr_1, (SELECT count(a1_.id) AS sclr_3 FROM Author a1_ WHERE a1_.id = a0_.id) AS sclr_2 FROM Author a0_ ORDER BY sclr_1 DESC, sclr_2 ASC", $limitQuery->getSQL() ); }