LazyCriteriaCollection::count returns ambiguous results when paired with Criteria::setMaxResults #7016

Open
opened 2026-01-22 15:43:13 +01:00 by admin · 3 comments
Owner

Originally created by @ScopeyNZ on GitHub (Aug 3, 2022).

Bug Report

Q A
BC Break no
Version 2.x

Summary

When using LazyCriteriaCollection::count() when a criteria with setMaxResults is configured, the result is ambiguous, depending on whether the collection has been initialized or not.

How to reproduce

Assuming you have an entity MyEntity with at least 2 records:

$criteria = (new Criteria())->setMaxResults(1);

$repo = $em->getRepository(MyEntity::class);
$collection = $repo->matching($criteria)

var_dump($collection->count()); // Shows 2 (or however many records you have)
$collection->toArray(); // Force initialization
var_dump($collection->count()); // Shows 1

Expected behavior

Either 2 or 1 shows every time, but ideally it's consistent. Either always perform a query for count, or do a min($count, $criteria->getMaxResults());, I'm not sure which is intended.

Happy to put forward a PR if there's a preferred expected behaviour. I'd also like to know if it would have to go against 3.x as I'm not sure sure if it'd be considered as a BC break to fix.

Originally created by @ScopeyNZ on GitHub (Aug 3, 2022). ### Bug Report <!-- Fill in the relevant information below to help triage your issue. --> | Q | A |------------ | ------ | BC Break | no | Version | 2.x #### Summary When using `LazyCriteriaCollection::count()` when a criteria with `setMaxResults` is configured, the result is ambiguous, depending on whether the collection has been initialized or not. #### How to reproduce Assuming you have an entity `MyEntity` with at least 2 records: ```php $criteria = (new Criteria())->setMaxResults(1); $repo = $em->getRepository(MyEntity::class); $collection = $repo->matching($criteria) var_dump($collection->count()); // Shows 2 (or however many records you have) $collection->toArray(); // Force initialization var_dump($collection->count()); // Shows 1 ``` #### Expected behavior Either 2 or 1 shows every time, but ideally it's consistent. Either always perform a query for count, or do a `min($count, $criteria->getMaxResults());`, I'm not sure which is intended. Happy to put forward a PR if there's a preferred expected behaviour. I'd also like to know if it would have to go against 3.x as I'm not sure sure if it'd be considered as a BC break to fix.
admin added the Bug label 2026-01-22 15:43:13 +01:00
Author
Owner

@derrabus commented on GitHub (Aug 7, 2022):

First of all, please be a bit more precise about the ORM version you're using. "2.x" is literally every Doctrine ORM release we've ever had. 😬

My expectation would be that count() consistently returns $maxResults if the actual count is higher. A PR would be welcome.

@derrabus commented on GitHub (Aug 7, 2022): First of all, please be a bit more precise about the ORM version you're using. "2.x" is literally every Doctrine ORM release we've ever had. 😬 My expectation would be that `count()` consistently returns `$maxResults` if the actual count is higher. A PR would be welcome.
Author
Owner

@ScopeyNZ commented on GitHub (Aug 8, 2022):

First of all, please be a bit more precise about the ORM version you're using.

Sorry I discovered the problem in 2.7.5. Verified it still appeared to be an issue in 2.12.3, and looking back it appeared to be an issue before 2.7.5 as well.

I probably should've put >2.7.5 (at least)

@ScopeyNZ commented on GitHub (Aug 8, 2022): > First of all, please be a bit more precise about the ORM version you're using. Sorry I discovered the problem in 2.7.5. Verified it still appeared to be an issue in 2.12.3, and looking back it appeared to be an issue before 2.7.5 as well. I probably should've put `>2.7.5 (at least)`
Author
Owner

@Aweptimum commented on GitHub (Jun 7, 2023):

For what it's worth, I had noticed this behavior as well and made a dupe (#10766) and jumped the gun on submitting #10767. I changed the BasicEntityPersister->getCountSQL to use a subselect + limit in my fork so that the count would be consistent with the criteria's max results if set. If maxResults isn't set, it makes sense to count the entire table because that's effectively what the user is asking for. I had to change the expected results in BasicEntityPersisterTypeValueSqlTest->testCountCondition, but it didn't break any other tests.

@Aweptimum commented on GitHub (Jun 7, 2023): For what it's worth, I had noticed this behavior as well and made a dupe (#10766) and jumped the gun on submitting #10767. I changed the `BasicEntityPersister->getCountSQL` to use a subselect + limit in my fork so that the count would be consistent with the criteria's max results if set. If maxResults isn't set, it makes sense to count the entire table because that's effectively what the user is asking for. I had to change the expected results in [BasicEntityPersisterTypeValueSqlTest->testCountCondition](https://github.com/doctrine/orm/blob/3827dd769edf25d59fa29a7d63efd6ba15b3a789/tests/Doctrine/Tests/ORM/Persisters/BasicEntityPersisterTypeValueSqlTest.php#L140), but it didn't break any other tests.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#7016