From 854ff17ab90ce42d6851866fc23c752d8defaa5b Mon Sep 17 00:00:00 2001 From: Martin Kirilov Date: Fri, 12 Aug 2016 17:24:00 +0300 Subject: [PATCH 1/5] Should fix MySQL 5.7 issues caused by ONLY_FULL_GROUP_BY Should fix MySQL 5.7 issues caused by ONLY_FULL_GROUP_BY --- .../Pagination/LimitSubqueryOutputWalker.php | 41 +++++++++++++++---- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php b/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php index 5d59722ed..93618e770 100644 --- a/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php +++ b/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php @@ -354,33 +354,56 @@ class LimitSubqueryOutputWalker extends SqlWalker /** * Generates new SQL for statements with an order by clause * - * @param array $sqlIdentifier - * @param string $innerSql - * @param string $sql - * @param OrderByClause $orderByClause + * @param array $sqlIdentifier + * @param string $innerSql + * @param string $sql + * @param OrderByClause $orderByClause * * @return string */ - private function preserveSqlOrdering(array $sqlIdentifier, $innerSql, $sql, $orderByClause) - { + private function preserveSqlOrdering(array $sqlIdentifier, $innerSql, $sql, $orderByClause) { // If the sql statement has an order by clause, we need to wrap it in a new select distinct // statement - if (! $orderByClause instanceof OrderByClause) { + if (!$orderByClause instanceof OrderByClause) { return $sql; } // Rebuild the order by clause to work in the scope of the new select statement /* @var array $orderBy an array of rebuilt order by items */ $orderBy = $this->rebuildOrderByClauseForOuterScope($orderByClause); + $orderByFields = str_replace([' DESC', ' ASC'], ['', ''], $orderBy); + + $innerSqlIdentifier = []; + + foreach ($orderByFields as $k => $v) { + // remove fields that are selected by identifiers, + // if those are ordered by in the query + if (in_array($v, $sqlIdentifier)) { + unset($orderByFields[$k]); + } + } + + foreach ($sqlIdentifier as $k => $v) { + $innerSqlIdentifier[$k] = 'dctrn_result_inner.' . $v; + $sqlIdentifier[$k] = 'dctrn_result.' . $v; + } + + // add the + foreach ($orderByFields as $k => $v) { + $innerSqlIdentifier[$k] = 'dctrn_result_inner.' . $v; + } // Build the select distinct statement $sql = sprintf( - 'SELECT DISTINCT %s FROM (%s) dctrn_result ORDER BY %s', - implode(', ', $sqlIdentifier), + 'SELECT DISTINCT %s FROM (%s) dctrn_result_inner ORDER BY %s', + implode(', ', $innerSqlIdentifier), $innerSql, implode(', ', $orderBy) ); + // now only select distinct identifier + $sql = sprintf('SELECT DISTINCT %s FROM (%s) dctrn_result', implode(', ', $sqlIdentifier), $sql); + return $sql; } From 60601a932301672141fc1a21cf032a5bf5d4f3d6 Mon Sep 17 00:00:00 2001 From: chihiro-adachi Date: Tue, 22 Nov 2016 17:01:27 +0900 Subject: [PATCH 2/5] fix query and tests --- .../Pagination/LimitSubqueryOutputWalker.php | 39 ++++++++----------- .../LimitSubqueryOutputWalkerTest.php | 20 +++++----- 2 files changed, 26 insertions(+), 33 deletions(-) diff --git a/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php b/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php index 93618e770..2b984b846 100644 --- a/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php +++ b/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php @@ -354,46 +354,39 @@ class LimitSubqueryOutputWalker extends SqlWalker /** * Generates new SQL for statements with an order by clause * - * @param array $sqlIdentifier - * @param string $innerSql - * @param string $sql - * @param OrderByClause $orderByClause + * @param array $sqlIdentifier + * @param string $innerSql + * @param string $sql + * @param OrderByClause $orderByClause * * @return string */ - private function preserveSqlOrdering(array $sqlIdentifier, $innerSql, $sql, $orderByClause) { + private function preserveSqlOrdering(array $sqlIdentifier, $innerSql, $sql, $orderByClause) + { // If the sql statement has an order by clause, we need to wrap it in a new select distinct // statement - if (!$orderByClause instanceof OrderByClause) { + if (! $orderByClause instanceof OrderByClause) { return $sql; } // Rebuild the order by clause to work in the scope of the new select statement /* @var array $orderBy an array of rebuilt order by items */ $orderBy = $this->rebuildOrderByClauseForOuterScope($orderByClause); - $orderByFields = str_replace([' DESC', ' ASC'], ['', ''], $orderBy); - $innerSqlIdentifier = []; + $innerSqlIdentifier = $sqlIdentifier; - foreach ($orderByFields as $k => $v) { - // remove fields that are selected by identifiers, + foreach ($orderBy as $field) { + $field = preg_replace('/((\S+)\s+(ASC|DESC)\s*,?)*/', '${2}', $field); + + // skip fields that are selected by identifiers, // if those are ordered by in the query - if (in_array($v, $sqlIdentifier)) { - unset($orderByFields[$k]); + if (in_array($field, $sqlIdentifier, true)) { + continue; } + $innerSqlIdentifier[] = $field; } - foreach ($sqlIdentifier as $k => $v) { - $innerSqlIdentifier[$k] = 'dctrn_result_inner.' . $v; - $sqlIdentifier[$k] = 'dctrn_result.' . $v; - } - - // add the - foreach ($orderByFields as $k => $v) { - $innerSqlIdentifier[$k] = 'dctrn_result_inner.' . $v; - } - - // Build the select distinct statement + // Build the innner select statement $sql = sprintf( 'SELECT DISTINCT %s FROM (%s) dctrn_result_inner ORDER BY %s', implode(', ', $innerSqlIdentifier), diff --git a/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php b/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php index 7e65ab7bc..463c413d2 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, LimitSubqueryOutputWalker::class); $this->assertSame( - 'SELECT DISTINCT id_0 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 FROM (SELECT DISTINCT id_0, (1 - 1000) * 1 FROM (SELECT a0_.id AS id_0, a0_.name AS name_1 FROM Author a0_) dctrn_result_inner ORDER BY (1 - 1000) * 1 DESC) dctrn_result', $query->getSQL() ); } @@ -223,7 +223,7 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); $this->assertSame( - 'SELECT DISTINCT id_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 image_height_2 * image_width_3 DESC', + 'SELECT DISTINCT id_0 FROM (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_inner ORDER BY image_height_2 * image_width_3 DESC) dctrn_result', $query->getSQL() ); } @@ -238,7 +238,7 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); $this->assertSame( - 'SELECT DISTINCT id_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 image_height_1 * image_width_2 DESC', + 'SELECT DISTINCT id_0 FROM (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_inner ORDER BY image_height_1 * image_width_2 DESC) dctrn_result', $query->getSQL() ); } @@ -253,7 +253,7 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); $this->assertSame( - 'SELECT DISTINCT id_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 image_height_3 * image_width_4 DESC', + 'SELECT DISTINCT id_0 FROM (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_inner ORDER BY image_height_3 * image_width_4 DESC) dctrn_result', $query->getSQL() ); } @@ -285,7 +285,7 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); $this->assertEquals( - 'SELECT DISTINCT id_0 FROM (SELECT a0_.id AS id_0, a0_.name AS name_1, a0_.name AS name_2 FROM Author a0_) dctrn_result ORDER BY name_2 DESC', + 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, name_2 FROM (SELECT a0_.id AS id_0, a0_.name AS name_1, a0_.name AS name_2 FROM Author a0_) dctrn_result_inner ORDER BY name_2 DESC) dctrn_result', $query->getSQL() ); } @@ -300,7 +300,7 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); $this->assertSame( - 'SELECT DISTINCT id_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 image_alt_desc_4 DESC', + 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, image_alt_desc_4 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_inner ORDER BY image_alt_desc_4 DESC) dctrn_result', $query->getSQL() ); } @@ -314,7 +314,7 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); $this->assertEquals( - 'SELECT DISTINCT id_0 FROM (SELECT b0_.id AS id_0, a1_.name AS name_1, b0_.author_id AS author_id_2, b0_.category_id AS category_id_3 FROM BlogPost b0_ INNER JOIN Author a1_ ON b0_.author_id = a1_.id) dctrn_result ORDER BY name_1 ASC', + 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, name_1 FROM (SELECT b0_.id AS id_0, a1_.name AS name_1, b0_.author_id AS author_id_2, b0_.category_id AS category_id_3 FROM BlogPost b0_ INNER JOIN Author a1_ ON b0_.author_id = a1_.id) dctrn_result_inner ORDER BY name_1 ASC) dctrn_result', $query->getSQL() ); } @@ -330,7 +330,7 @@ ORDER BY b.id DESC' $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); $this->assertEquals( - 'SELECT DISTINCT id_0 FROM (SELECT b0_.id AS id_0, b0_.author_id AS author_id_1, b0_.category_id AS category_id_2 FROM BlogPost b0_ WHERE ((SELECT COUNT(b1_.id) AS sclr_3 FROM BlogPost b1_) = 1)) dctrn_result ORDER BY id_0 DESC', + 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0 FROM (SELECT b0_.id AS id_0, b0_.author_id AS author_id_1, b0_.category_id AS category_id_2 FROM BlogPost b0_ WHERE ((SELECT COUNT(b1_.id) AS sclr_3 FROM BlogPost b1_) = 1)) dctrn_result_inner ORDER BY id_0 DESC) dctrn_result', $query->getSQL() ); } @@ -365,7 +365,7 @@ ORDER BY b.id DESC' $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); $this->assertEquals( - 'SELECT DISTINCT id_0 FROM (SELECT b0_.id AS id_0, b0_.name AS name_1 FROM Banner b0_) dctrn_result ORDER BY id_0 DESC', + 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0 FROM (SELECT b0_.id AS id_0, b0_.name AS name_1 FROM Banner b0_) dctrn_result_inner ORDER BY id_0 DESC) dctrn_result', $query->getSQL() ); } @@ -390,7 +390,7 @@ ORDER BY b.id DESC' $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); $this->assertEquals( - 'SELECT DISTINCT id_0 FROM (SELECT a0_.id AS id_0, a0_.name AS name_1, (SELECT MIN(m1_.title) AS sclr_3 FROM MyBlogPost m1_ WHERE m1_.author_id = a0_.id) AS sclr_2 FROM Author a0_) dctrn_result ORDER BY sclr_2 DESC', + 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, sclr_2 FROM (SELECT a0_.id AS id_0, a0_.name AS name_1, (SELECT MIN(m1_.title) AS sclr_3 FROM MyBlogPost m1_ WHERE m1_.author_id = a0_.id) AS sclr_2 FROM Author a0_) dctrn_result_inner ORDER BY sclr_2 DESC) dctrn_result', $query->getSQL() ); } From 4a736f48f82c1e555bbe0e477fcacf80fcd0444f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Cobucci?= Date: Sat, 1 Jul 2017 14:22:40 +0200 Subject: [PATCH 3/5] Add MySQL 5.7 to Travis configuration Following the same setup of doctrine/dbal#2764. --- .travis.yml | 8 ++++++++ tests/travis/install-mysql-5.7.sh | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 tests/travis/install-mysql-5.7.sh diff --git a/.travis.yml b/.travis.yml index e88053559..57b2cb1f6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,6 +20,7 @@ before_script: - if [ "$DEPENDENCIES" != "low" ]; then composer update; fi; - if [ "$DEPENDENCIES" == "low" ]; then composer update --prefer-lowest; fi; - if [[ $PHPSTAN = 1 ]]; then composer require --dev --prefer-stable phpstan/phpstan:^0.7 symfony/console:^3.0; fi + - if [ "$MYSQL_VERSION" == "5.7" ]; then bash ./tests/travis/install-mysql-5.7.sh; fi; - if [[ $DB == "mysql" || $DB == "mariadb" ]]; then mysql -e "CREATE SCHEMA doctrine_tests; GRANT ALL PRIVILEGES ON doctrine_tests.* to travis@'%'"; fi; script: @@ -47,6 +48,13 @@ matrix: - DB=pgsql - PHPSTAN=1 + - php: 7.1 + env: DB=mysql MYSQL_VERSION=5.7 + sudo: required + - php: nightly + env: DB=mysql MYSQL_VERSION=5.7 + sudo: required + allow_failures: - php: nightly diff --git a/tests/travis/install-mysql-5.7.sh b/tests/travis/install-mysql-5.7.sh new file mode 100644 index 000000000..66b0d1ecf --- /dev/null +++ b/tests/travis/install-mysql-5.7.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +set -ex + +echo "Installing MySQL 5.7..." + +sudo service mysql stop +sudo apt-get remove "^mysql.*" +sudo apt-get autoremove +sudo apt-get autoclean +echo mysql-apt-config mysql-apt-config/select-server select mysql-5.7 | sudo debconf-set-selections +wget http://dev.mysql.com/get/mysql-apt-config_0.8.6-1_all.deb +sudo DEBIAN_FRONTEND=noninteractive dpkg -i mysql-apt-config_0.8.6-1_all.deb +sudo rm -rf /var/lib/apt/lists/* +sudo apt-get clean +sudo apt-get update -q +sudo apt-get install -q -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" mysql-server libmysqlclient-dev +sudo mysql_upgrade + +echo "Restart mysql..." +sudo mysql -e "use mysql; update user set authentication_string=PASSWORD('') where User='root'; update user set plugin='mysql_native_password';FLUSH PRIVILEGES;" + From 3d5acd607ba51fec5a1f79208b1fe507cc6be0cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Cobucci?= Date: Sat, 22 Jul 2017 19:30:47 +0200 Subject: [PATCH 4/5] Bump up doctrine/instantiator version --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index a4b43de3b..d320b0b4d 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "ext-pdo": "*", "doctrine/collections": "^1.4", "doctrine/dbal": ">=2.5-dev,<2.7-dev", - "doctrine/instantiator": "~1.0.1", + "doctrine/instantiator": "~1.1", "doctrine/common": "^2.7.1", "doctrine/cache": "~1.6", "doctrine/annotations": "~1.4", From 5389ad72615a613dc01ce65b257147d5b698fd41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Cobucci?= Date: Sat, 22 Jul 2017 20:34:18 +0200 Subject: [PATCH 5/5] Make LimitSubqueryOutputWalker a bit more readable Also simplifying the REGEX to remove the ORDER BY type (ASC/DESC) with a substr() since OrderByItem#type is always defined. --- .../Pagination/LimitSubqueryOutputWalker.php | 156 +++++++++--------- .../LimitSubqueryOutputWalkerTest.php | 88 +++++----- 2 files changed, 124 insertions(+), 120 deletions(-) diff --git a/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php b/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php index 2b984b846..034b33b2c 100644 --- a/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php +++ b/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php @@ -43,6 +43,8 @@ use Doctrine\ORM\Query\AST\SelectStatement; */ class LimitSubqueryOutputWalker extends SqlWalker { + private const ORDER_BY_PATH_EXPRESSION = '/(?rebuildOrderByClauseForOuterScope($orderByClause); - - $innerSqlIdentifier = $sqlIdentifier; - - foreach ($orderBy as $field) { - $field = preg_replace('/((\S+)\s+(ASC|DESC)\s*,?)*/', '${2}', $field); - - // skip fields that are selected by identifiers, - // if those are ordered by in the query - if (in_array($field, $sqlIdentifier, true)) { - continue; - } - $innerSqlIdentifier[] = $field; - } - - // Build the innner select statement - $sql = sprintf( - 'SELECT DISTINCT %s FROM (%s) dctrn_result_inner ORDER BY %s', - implode(', ', $innerSqlIdentifier), - $innerSql, - implode(', ', $orderBy) - ); - // now only select distinct identifier - $sql = sprintf('SELECT DISTINCT %s FROM (%s) dctrn_result', implode(', ', $sqlIdentifier), $sql); - - return $sql; + return \sprintf( + 'SELECT DISTINCT %s FROM (%s) dctrn_result', + \implode(', ', $sqlIdentifier), + $this->recreateInnerSql($orderByClause, $sqlIdentifier, $innerSql) + ); } /** - * Generates a new order by clause that works in the scope of a select query wrapping the original + * Generates a new SQL statement for the inner query to keep the correct sorting * * @param OrderByClause $orderByClause - * @return array + * @param array $identifiers + * @param string $innerSql + * + * @return string */ - private function rebuildOrderByClauseForOuterScope(OrderByClause $orderByClause) - { - $dqlAliasToSqlTableAliasMap - = $searchPatterns - = $replacements - = $dqlAliasToClassMap - = $selectListAdditions - = $orderByItems - = []; + private function recreateInnerSql( + OrderByClause $orderByClause, + array $identifiers, + string $innerSql + ) : string { + [$searchPatterns, $replacements] = $this->generateSqlAliasReplacements(); - // Generate DQL alias -> SQL table alias mapping - foreach(array_keys($this->rsm->aliasMap) as $dqlAlias) { - $dqlAliasToClassMap[$dqlAlias] = $class = $this->queryComponents[$dqlAlias]['metadata']; - $dqlAliasToSqlTableAliasMap[$dqlAlias] = $this->getSQLTableAlias($class->getTableName(), $dqlAlias); + $orderByItems = []; + + foreach ($orderByClause->orderByItems as $orderByItem) { + // Walk order by item to get string representation of it and + // replace path expressions in the order by clause with their column alias + $orderByItemString = \preg_replace( + $searchPatterns, + $replacements, + $this->walkOrderByItem($orderByItem) + ); + + $orderByItems[] = $orderByItemString; + $identifier = \substr($orderByItemString, 0, \strrpos($orderByItemString, ' ')); + + if (! \in_array($identifier, $identifiers, true)) { + $identifiers[] = $identifier; + } } - // Pattern to find table path expressions in the order by clause - $fieldSearchPattern = '/(? SQL table alias mapping + foreach (\array_keys($this->rsm->aliasMap) as $dqlAlias) { + $metadataList[$dqlAlias] = $class = $this->queryComponents[$dqlAlias]['metadata']; + $aliasMap[$dqlAlias] = $this->getSQLTableAlias($class->getTableName(), $dqlAlias); + } // Generate search patterns for each field's path expression in the order by clause - foreach($this->rsm->fieldMappings as $fieldAlias => $fieldName) { + foreach ($this->rsm->fieldMappings as $fieldAlias => $fieldName) { $dqlAliasForFieldAlias = $this->rsm->columnOwnerMap[$fieldAlias]; - $class = $dqlAliasToClassMap[$dqlAliasForFieldAlias]; + $class = $metadataList[$dqlAliasForFieldAlias]; - // If the field is from a joined child table, we won't be ordering - // on it. - if (!isset($class->fieldMappings[$fieldName])) { + // If the field is from a joined child table, we won't be ordering on it. + if (! isset($class->fieldMappings[$fieldName])) { continue; } @@ -441,37 +453,29 @@ class LimitSubqueryOutputWalker extends SqlWalker // Get the proper column name as will appear in the select list $columnName = $this->quoteStrategy->getColumnName( $fieldName, - $dqlAliasToClassMap[$dqlAliasForFieldAlias], + $metadataList[$dqlAliasForFieldAlias], $this->em->getConnection()->getDatabasePlatform() ); // Get the SQL table alias for the entity and field - $sqlTableAliasForFieldAlias = $dqlAliasToSqlTableAliasMap[$dqlAliasForFieldAlias]; + $sqlTableAliasForFieldAlias = $aliasMap[$dqlAliasForFieldAlias]; + if (isset($fieldMapping['declared']) && $fieldMapping['declared'] !== $class->name) { // Field was declared in a parent class, so we need to get the proper SQL table alias // for the joined parent table. $otherClassMetadata = $this->em->getClassMetadata($fieldMapping['declared']); - if (!$otherClassMetadata->isMappedSuperclass) { + + if (! $otherClassMetadata->isMappedSuperclass) { $sqlTableAliasForFieldAlias = $this->getSQLTableAlias($otherClassMetadata->getTableName(), $dqlAliasForFieldAlias); } } - // Compose search/replace patterns - $searchPatterns[] = sprintf($fieldSearchPattern, $sqlTableAliasForFieldAlias, $columnName); - $replacements[] = $fieldAlias; + // Compose search and replace patterns + $searchPatterns[] = \sprintf(self::ORDER_BY_PATH_EXPRESSION, $sqlTableAliasForFieldAlias, $columnName); + $replacements[] = $fieldAlias; } - foreach($orderByClause->orderByItems as $orderByItem) { - // Walk order by item to get string representation of it - $orderByItemString = $this->walkOrderByItem($orderByItem); - - // Replace path expressions in the order by clause with their column alias - $orderByItemString = preg_replace($searchPatterns, $replacements, $orderByItemString); - - $orderByItems[] = $orderByItemString; - } - - return $orderByItems; + return [$searchPatterns, $replacements]; } /** diff --git a/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php b/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php index 463c413d2..39ee1360d 100644 --- a/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php +++ b/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php @@ -8,9 +8,9 @@ use Doctrine\DBAL\Platforms\PostgreSqlPlatform; use Doctrine\ORM\Query; use Doctrine\ORM\Tools\Pagination\LimitSubqueryOutputWalker; -class LimitSubqueryOutputWalkerTest extends PaginationTestCase +final class LimitSubqueryOutputWalkerTest extends PaginationTestCase { - public function testLimitSubquery() + public function testLimitSubquery() : void { $query = $this->entityManager->createQuery( 'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a'); @@ -18,12 +18,12 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase $limitQuery = clone $query; $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); - $this->assertEquals( + self::assertSame( "SELECT DISTINCT id_0 FROM (SELECT m0_.id AS id_0, m0_.title AS title_1, c1_.id AS id_2, a2_.id AS id_3, a2_.name AS name_4, m0_.author_id AS author_id_5, m0_.category_id AS category_id_6 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id) dctrn_result", $limitQuery->getSQL() ); } - public function testLimitSubqueryWithSortPg() + public function testLimitSubqueryWithSortPg() : void { $odp = $this->entityManager->getConnection()->getDatabasePlatform(); $this->entityManager->getConnection()->setDatabasePlatform(new PostgreSqlPlatform); @@ -33,14 +33,14 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase $limitQuery = clone $query; $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); - $this->assertEquals( + self::assertSame( "SELECT DISTINCT id_0, MIN(sclr_5) AS dctrn_minrownum FROM (SELECT m0_.id AS id_0, m0_.title AS title_1, c1_.id AS id_2, a2_.id AS id_3, a2_.name AS name_4, ROW_NUMBER() OVER(ORDER BY m0_.title ASC) AS sclr_5, m0_.author_id AS author_id_6, m0_.category_id AS category_id_7 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id) dctrn_result GROUP BY id_0 ORDER BY dctrn_minrownum ASC", $limitQuery->getSQL() ); $this->entityManager->getConnection()->setDatabasePlatform($odp); } - public function testLimitSubqueryWithScalarSortPg() + public function testLimitSubqueryWithScalarSortPg() : void { $odp = $this->entityManager->getConnection()->getDatabasePlatform(); $this->entityManager->getConnection()->setDatabasePlatform(new PostgreSqlPlatform); @@ -51,7 +51,7 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase $limitQuery = clone $query; $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); - $this->assertEquals( + self::assertSame( "SELECT DISTINCT id_1, MIN(sclr_3) AS dctrn_minrownum FROM (SELECT COUNT(g0_.id) AS sclr_0, u1_.id AS id_1, g0_.id AS id_2, ROW_NUMBER() OVER(ORDER BY COUNT(g0_.id) ASC) AS sclr_3 FROM User u1_ INNER JOIN user_group u2_ ON u1_.id = u2_.user_id INNER JOIN groups g0_ ON g0_.id = u2_.group_id) dctrn_result GROUP BY id_1 ORDER BY dctrn_minrownum ASC", $limitQuery->getSQL() ); @@ -59,7 +59,7 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase $this->entityManager->getConnection()->setDatabasePlatform($odp); } - public function testLimitSubqueryWithMixedSortPg() + public function testLimitSubqueryWithMixedSortPg() : void { $odp = $this->entityManager->getConnection()->getDatabasePlatform(); $this->entityManager->getConnection()->setDatabasePlatform(new PostgreSqlPlatform); @@ -70,7 +70,7 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase $limitQuery = clone $query; $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); - $this->assertEquals( + self::assertSame( "SELECT DISTINCT id_1, MIN(sclr_3) AS dctrn_minrownum FROM (SELECT COUNT(g0_.id) AS sclr_0, u1_.id AS id_1, g0_.id AS id_2, ROW_NUMBER() OVER(ORDER BY COUNT(g0_.id) ASC, u1_.id DESC) AS sclr_3 FROM User u1_ INNER JOIN user_group u2_ ON u1_.id = u2_.user_id INNER JOIN groups g0_ ON g0_.id = u2_.group_id) dctrn_result GROUP BY id_1 ORDER BY dctrn_minrownum ASC", $limitQuery->getSQL() ); @@ -78,7 +78,7 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase $this->entityManager->getConnection()->setDatabasePlatform($odp); } - public function testLimitSubqueryWithHiddenScalarSortPg() + public function testLimitSubqueryWithHiddenScalarSortPg() : void { $odp = $this->entityManager->getConnection()->getDatabasePlatform(); $this->entityManager->getConnection()->setDatabasePlatform(new PostgreSqlPlatform); @@ -89,7 +89,7 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase $limitQuery = clone $query; $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); - $this->assertEquals( + self::assertSame( "SELECT DISTINCT id_1, MIN(sclr_3) AS dctrn_minrownum FROM (SELECT COUNT(g0_.id) AS sclr_0, u1_.id AS id_1, g0_.id AS id_2, ROW_NUMBER() OVER(ORDER BY COUNT(g0_.id) ASC, u1_.id DESC) AS sclr_3 FROM User u1_ INNER JOIN user_group u2_ ON u1_.id = u2_.user_id INNER JOIN groups g0_ ON g0_.id = u2_.group_id) dctrn_result GROUP BY id_1 ORDER BY dctrn_minrownum ASC", $limitQuery->getSQL() ); @@ -97,7 +97,7 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase $this->entityManager->getConnection()->setDatabasePlatform($odp); } - public function testLimitSubqueryPg() + public function testLimitSubqueryPg() : void { $odp = $this->entityManager->getConnection()->getDatabasePlatform(); $this->entityManager->getConnection()->setDatabasePlatform(new PostgreSqlPlatform); @@ -107,7 +107,7 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase $this->entityManager->getConnection()->setDatabasePlatform($odp); } - public function testLimitSubqueryWithSortOracle() + public function testLimitSubqueryWithSortOracle() : void { $odp = $this->entityManager->getConnection()->getDatabasePlatform(); $this->entityManager->getConnection()->setDatabasePlatform(new OraclePlatform); @@ -118,14 +118,14 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase $limitQuery = clone $query; $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); - $this->assertEquals( + self::assertSame( "SELECT DISTINCT ID_0, MIN(SCLR_5) AS dctrn_minrownum FROM (SELECT m0_.id AS ID_0, m0_.title AS TITLE_1, c1_.id AS ID_2, a2_.id AS ID_3, a2_.name AS NAME_4, ROW_NUMBER() OVER(ORDER BY m0_.title ASC) AS SCLR_5, m0_.author_id AS AUTHOR_ID_6, m0_.category_id AS CATEGORY_ID_7 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id) dctrn_result GROUP BY ID_0 ORDER BY dctrn_minrownum ASC", $limitQuery->getSQL() ); $this->entityManager->getConnection()->setDatabasePlatform($odp); } - public function testLimitSubqueryWithScalarSortOracle() + public function testLimitSubqueryWithScalarSortOracle() : void { $odp = $this->entityManager->getConnection()->getDatabasePlatform(); $this->entityManager->getConnection()->setDatabasePlatform(new OraclePlatform); @@ -137,7 +137,7 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase $limitQuery = clone $query; $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); - $this->assertEquals( + self::assertSame( "SELECT DISTINCT ID_1, MIN(SCLR_3) AS dctrn_minrownum FROM (SELECT COUNT(g0_.id) AS SCLR_0, u1_.id AS ID_1, g0_.id AS ID_2, ROW_NUMBER() OVER(ORDER BY COUNT(g0_.id) ASC) AS SCLR_3 FROM User u1_ INNER JOIN user_group u2_ ON u1_.id = u2_.user_id INNER JOIN groups g0_ ON g0_.id = u2_.group_id) dctrn_result GROUP BY ID_1 ORDER BY dctrn_minrownum ASC", $limitQuery->getSQL() ); @@ -145,7 +145,7 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase $this->entityManager->getConnection()->setDatabasePlatform($odp); } - public function testLimitSubqueryWithMixedSortOracle() + public function testLimitSubqueryWithMixedSortOracle() : void { $odp = $this->entityManager->getConnection()->getDatabasePlatform(); $this->entityManager->getConnection()->setDatabasePlatform(new OraclePlatform); @@ -157,7 +157,7 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase $limitQuery = clone $query; $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); - $this->assertEquals( + self::assertSame( "SELECT DISTINCT ID_1, MIN(SCLR_3) AS dctrn_minrownum FROM (SELECT COUNT(g0_.id) AS SCLR_0, u1_.id AS ID_1, g0_.id AS ID_2, ROW_NUMBER() OVER(ORDER BY COUNT(g0_.id) ASC, u1_.id DESC) AS SCLR_3 FROM User u1_ INNER JOIN user_group u2_ ON u1_.id = u2_.user_id INNER JOIN groups g0_ ON g0_.id = u2_.group_id) dctrn_result GROUP BY ID_1 ORDER BY dctrn_minrownum ASC", $limitQuery->getSQL() ); @@ -165,7 +165,7 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase $this->entityManager->getConnection()->setDatabasePlatform($odp); } - public function testLimitSubqueryOracle() + public function testLimitSubqueryOracle() : void { $odp = $this->entityManager->getConnection()->getDatabasePlatform(); $this->entityManager->getConnection()->setDatabasePlatform(new OraclePlatform); @@ -176,21 +176,21 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase $limitQuery = clone $query; $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); - $this->assertEquals( + self::assertSame( "SELECT DISTINCT ID_0 FROM (SELECT m0_.id AS ID_0, m0_.title AS TITLE_1, c1_.id AS ID_2, a2_.id AS ID_3, a2_.name AS NAME_4, m0_.author_id AS AUTHOR_ID_5, m0_.category_id AS CATEGORY_ID_6 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id) dctrn_result", $limitQuery->getSQL() ); $this->entityManager->getConnection()->setDatabasePlatform($odp); } - public function testCountQueryMixedResultsWithName() + public function testCountQueryMixedResultsWithName() : void { $query = $this->entityManager->createQuery( 'SELECT a, sum(a.name) as foo FROM Doctrine\Tests\ORM\Tools\Pagination\Author a'); $limitQuery = clone $query; $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); - $this->assertEquals( + self::assertSame( "SELECT DISTINCT id_0 FROM (SELECT a0_.id AS id_0, a0_.name AS name_1, sum(a0_.name) AS sclr_2 FROM Author a0_) dctrn_result", $limitQuery->getSQL() ); } @@ -198,7 +198,7 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase /** * @group DDC-3336 */ - public function testCountQueryWithArithmeticOrderByCondition() + public function testCountQueryWithArithmeticOrderByCondition() : void { $query = $this->entityManager->createQuery( 'SELECT a FROM Doctrine\Tests\ORM\Tools\Pagination\Author a ORDER BY (1 - 1000) * 1 DESC' @@ -213,7 +213,7 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase ); } - public function testCountQueryWithComplexScalarOrderByItem() + public function testCountQueryWithComplexScalarOrderByItem() : void { $query = $this->entityManager->createQuery( 'SELECT a FROM Doctrine\Tests\ORM\Tools\Pagination\Avatar a ORDER BY a.image_height * a.image_width DESC' @@ -228,7 +228,7 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase ); } - public function testCountQueryWithComplexScalarOrderByItemJoined() + public function testCountQueryWithComplexScalarOrderByItemJoined() : void { $query = $this->entityManager->createQuery( 'SELECT u FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.avatar a ORDER BY a.image_height * a.image_width DESC' @@ -243,7 +243,7 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase ); } - public function testCountQueryWithComplexScalarOrderByItemJoinedWithPartial() + public function testCountQueryWithComplexScalarOrderByItemJoinedWithPartial() : void { $query = $this->entityManager->createQuery( 'SELECT u, partial a.{id, image_alt_desc} FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.avatar a ORDER BY a.image_height * a.image_width DESC' @@ -258,7 +258,7 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase ); } - public function testCountQueryWithComplexScalarOrderByItemOracle() + public function testCountQueryWithComplexScalarOrderByItemOracle() : void { $query = $this->entityManager->createQuery( 'SELECT a FROM Doctrine\Tests\ORM\Tools\Pagination\Avatar a ORDER BY a.image_height * a.image_width DESC' @@ -276,7 +276,7 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase /** * @group DDC-3434 */ - public function testLimitSubqueryWithHiddenSelectionInOrderBy() + public function testLimitSubqueryWithHiddenSelectionInOrderBy() : void { $query = $this->entityManager->createQuery( 'SELECT a, a.name AS HIDDEN ord FROM Doctrine\Tests\ORM\Tools\Pagination\Author a ORDER BY ord DESC' @@ -284,13 +284,13 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); - $this->assertEquals( + self::assertSame( 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, name_2 FROM (SELECT a0_.id AS id_0, a0_.name AS name_1, a0_.name AS name_2 FROM Author a0_) dctrn_result_inner ORDER BY name_2 DESC) dctrn_result', $query->getSQL() ); } - public function testLimitSubqueryWithColumnWithSortDirectionInName() + public function testLimitSubqueryWithColumnWithSortDirectionInName() : void { $query = $this->entityManager->createQuery( 'SELECT a FROM Doctrine\Tests\ORM\Tools\Pagination\Avatar a ORDER BY a.image_alt_desc DESC' @@ -305,7 +305,7 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase ); } - public function testLimitSubqueryWithOrderByInnerJoined() + public function testLimitSubqueryWithOrderByInnerJoined() : void { $query = $this->entityManager->createQuery( 'SELECT b FROM Doctrine\Tests\ORM\Tools\Pagination\BlogPost b JOIN b.author a ORDER BY a.name ASC' @@ -313,13 +313,13 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); - $this->assertEquals( + self::assertSame( 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, name_1 FROM (SELECT b0_.id AS id_0, a1_.name AS name_1, b0_.author_id AS author_id_2, b0_.category_id AS category_id_3 FROM BlogPost b0_ INNER JOIN Author a1_ ON b0_.author_id = a1_.id) dctrn_result_inner ORDER BY name_1 ASC) dctrn_result', $query->getSQL() ); } - public function testLimitSubqueryWithOrderByAndSubSelectInWhereClauseMySql() + public function testLimitSubqueryWithOrderByAndSubSelectInWhereClauseMySql() : void { $this->entityManager->getConnection()->setDatabasePlatform(new MySqlPlatform()); $query = $this->entityManager->createQuery( @@ -329,13 +329,13 @@ ORDER BY b.id DESC' ); $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); - $this->assertEquals( + self::assertSame( 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0 FROM (SELECT b0_.id AS id_0, b0_.author_id AS author_id_1, b0_.category_id AS category_id_2 FROM BlogPost b0_ WHERE ((SELECT COUNT(b1_.id) AS sclr_3 FROM BlogPost b1_) = 1)) dctrn_result_inner ORDER BY id_0 DESC) dctrn_result', $query->getSQL() ); } - public function testLimitSubqueryWithOrderByAndSubSelectInWhereClausePgSql() + public function testLimitSubqueryWithOrderByAndSubSelectInWhereClausePgSql() : void { $this->entityManager->getConnection()->setDatabasePlatform(new PostgreSqlPlatform()); $query = $this->entityManager->createQuery( @@ -345,7 +345,7 @@ ORDER BY b.id DESC' ); $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); - $this->assertEquals( + self::assertSame( 'SELECT DISTINCT id_0, MIN(sclr_1) AS dctrn_minrownum FROM (SELECT b0_.id AS id_0, ROW_NUMBER() OVER(ORDER BY b0_.id DESC) AS sclr_1, b0_.author_id AS author_id_2, b0_.category_id AS category_id_3 FROM BlogPost b0_ WHERE ((SELECT COUNT(b1_.id) AS sclr_4 FROM BlogPost b1_) = 1)) dctrn_result GROUP BY id_0 ORDER BY dctrn_minrownum ASC', $query->getSQL() ); @@ -354,7 +354,7 @@ ORDER BY b.id DESC' /** * This tests ordering by property that has the 'declared' field. */ - public function testLimitSubqueryOrderByFieldFromMappedSuperclass() + public function testLimitSubqueryOrderByFieldFromMappedSuperclass() : void { $this->entityManager->getConnection()->setDatabasePlatform(new MySqlPlatform()); @@ -364,7 +364,7 @@ ORDER BY b.id DESC' ); $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); - $this->assertEquals( + self::assertSame( 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0 FROM (SELECT b0_.id AS id_0, b0_.name AS name_1 FROM Banner b0_) dctrn_result_inner ORDER BY id_0 DESC) dctrn_result', $query->getSQL() ); @@ -373,7 +373,7 @@ ORDER BY b.id DESC' /** * Tests order by on a subselect expression (mysql). */ - public function testLimitSubqueryOrderBySubSelectOrderByExpression() + public function testLimitSubqueryOrderBySubSelectOrderByExpression() : void { $this->entityManager->getConnection()->setDatabasePlatform(new MySqlPlatform()); @@ -389,7 +389,7 @@ ORDER BY b.id DESC' ); $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); - $this->assertEquals( + self::assertSame( 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, sclr_2 FROM (SELECT a0_.id AS id_0, a0_.name AS name_1, (SELECT MIN(m1_.title) AS sclr_3 FROM MyBlogPost m1_ WHERE m1_.author_id = a0_.id) AS sclr_2 FROM Author a0_) dctrn_result_inner ORDER BY sclr_2 DESC) dctrn_result', $query->getSQL() ); @@ -398,7 +398,7 @@ ORDER BY b.id DESC' /** * Tests order by on a subselect expression invoking RowNumberOverFunction (postgres). */ - public function testLimitSubqueryOrderBySubSelectOrderByExpressionPg() + public function testLimitSubqueryOrderBySubSelectOrderByExpressionPg() : void { $this->entityManager->getConnection()->setDatabasePlatform(new PostgreSqlPlatform()); @@ -414,7 +414,7 @@ ORDER BY b.id DESC' ); $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); - $this->assertEquals( + self::assertSame( 'SELECT DISTINCT id_0, MIN(sclr_4) AS dctrn_minrownum FROM (SELECT a0_.id AS id_0, a0_.name AS name_1, (SELECT MIN(m1_.title) AS sclr_3 FROM MyBlogPost m1_ WHERE m1_.author_id = a0_.id) AS sclr_2, ROW_NUMBER() OVER(ORDER BY (SELECT MIN(m1_.title) AS sclr_5 FROM MyBlogPost m1_ WHERE m1_.author_id = a0_.id) DESC) AS sclr_4 FROM Author a0_) dctrn_result GROUP BY id_0 ORDER BY dctrn_minrownum ASC', $query->getSQL() ); @@ -423,7 +423,7 @@ ORDER BY b.id DESC' /** * Tests order by on a subselect expression invoking RowNumberOverFunction (oracle). */ - public function testLimitSubqueryOrderBySubSelectOrderByExpressionOracle() + public function testLimitSubqueryOrderBySubSelectOrderByExpressionOracle() : void { $this->entityManager->getConnection()->setDatabasePlatform(new OraclePlatform()); @@ -439,7 +439,7 @@ ORDER BY b.id DESC' ); $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); - $this->assertEquals( + self::assertSame( 'SELECT DISTINCT ID_0, MIN(SCLR_4) AS dctrn_minrownum FROM (SELECT a0_.id AS ID_0, a0_.name AS NAME_1, (SELECT MIN(m1_.title) AS SCLR_3 FROM MyBlogPost m1_ WHERE m1_.author_id = a0_.id) AS SCLR_2, ROW_NUMBER() OVER(ORDER BY (SELECT MIN(m1_.title) AS SCLR_5 FROM MyBlogPost m1_ WHERE m1_.author_id = a0_.id) DESC) AS SCLR_4 FROM Author a0_) dctrn_result GROUP BY ID_0 ORDER BY dctrn_minrownum ASC', $query->getSQL() );