Skip to content

Commit 5f1fe15

Browse files
authored
Merge pull request #11557 from d-ph/feature/make-count-walker-use-count-star-query-sometimes
Make CountWalker use COUNT(*) when $distinct is explicitly set to false (#11552)
2 parents 56cd688 + 57247ed commit 5f1fe15

File tree

2 files changed

+34
-16
lines changed

2 files changed

+34
-16
lines changed

src/Tools/Pagination/CountWalker.php

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,27 +37,31 @@ public function walkSelectStatement(SelectStatement $selectStatement): void
3737
throw new RuntimeException('Cannot count query which selects two FROM components, cannot make distinction');
3838
}
3939

40-
$fromRoot = reset($from);
41-
$rootAlias = $fromRoot->rangeVariableDeclaration->aliasIdentificationVariable;
42-
$rootClass = $this->getMetadataForDqlAlias($rootAlias);
43-
$identifierFieldName = $rootClass->getSingleIdentifierFieldName();
40+
$distinct = $this->_getQuery()->getHint(self::HINT_DISTINCT);
4441

45-
$pathType = PathExpression::TYPE_STATE_FIELD;
46-
if (isset($rootClass->associationMappings[$identifierFieldName])) {
47-
$pathType = PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION;
48-
}
42+
$countPathExpressionOrLiteral = '*';
43+
if ($distinct) {
44+
$fromRoot = reset($from);
45+
$rootAlias = $fromRoot->rangeVariableDeclaration->aliasIdentificationVariable;
46+
$rootClass = $this->getMetadataForDqlAlias($rootAlias);
47+
$identifierFieldName = $rootClass->getSingleIdentifierFieldName();
48+
49+
$pathType = PathExpression::TYPE_STATE_FIELD;
50+
if (isset($rootClass->associationMappings[$identifierFieldName])) {
51+
$pathType = PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION;
52+
}
4953

50-
$pathExpression = new PathExpression(
51-
PathExpression::TYPE_STATE_FIELD | PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION,
52-
$rootAlias,
53-
$identifierFieldName,
54-
);
55-
$pathExpression->type = $pathType;
54+
$countPathExpressionOrLiteral = new PathExpression(
55+
PathExpression::TYPE_STATE_FIELD | PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION,
56+
$rootAlias,
57+
$identifierFieldName,
58+
);
59+
$countPathExpressionOrLiteral->type = $pathType;
60+
}
5661

57-
$distinct = $this->_getQuery()->getHint(self::HINT_DISTINCT);
5862
$selectStatement->selectClause->selectExpressions = [
5963
new SelectExpression(
60-
new AggregateExpression('count', $pathExpression, $distinct),
64+
new AggregateExpression('count', $countPathExpressionOrLiteral, $distinct),
6165
null,
6266
),
6367
];

tests/Tests/ORM/Tools/Pagination/CountWalkerTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,20 @@ public function testCountQuery(): void
2727
);
2828
}
2929

30+
public function testCountQueryWithoutDistinctUsesCountStar(): void
31+
{
32+
$query = $this->entityManager->createQuery(
33+
'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\BlogPost p JOIN p.category c JOIN p.author a',
34+
);
35+
$query->setHint(Query::HINT_CUSTOM_TREE_WALKERS, [CountWalker::class]);
36+
$query->setHint(CountWalker::HINT_DISTINCT, false);
37+
38+
self::assertEquals(
39+
'SELECT count(*) AS sclr_0 FROM BlogPost b0_ INNER JOIN Category c1_ ON b0_.category_id = c1_.id INNER JOIN Author a2_ ON b0_.author_id = a2_.id',
40+
$query->getSQL(),
41+
);
42+
}
43+
3044
public function testCountQueryMixedResultsWithName(): void
3145
{
3246
$query = $this->entityManager->createQuery(

0 commit comments

Comments
 (0)