orm: Paginator breaks when DQL query is re-used with different identifier parameters that require conversion
Bug Report
Q | A |
---|---|
BC Break | no |
Version | 2.6.4 |
Summary
#7820 and #7821 fix pagination issues happening when the paginator is relying on identifiers that require custom DBAL type conversion.
The type conversion works, but since it has been performed inside the WhereInWalker
(to keep things a bit simpler), it is only performed when the query is in Doctrine\ORM\Query::STATE_DIRTY
.
If the parameters are changed on a Doctrine\ORM\Query
, the query doesn’t change parser state, and therefore the WhereInWalker
is completely skipped.
I will try to write a small reproducer and fix ASAP, hoping to not cause too big performance regressions in the ORM. I think it may come down to forcing query parsing to be repeated.
Current behavior
$id = generateCustomId();
$a = new A($id);
$this->em->persist($a);
$this->em->flush();
$query = $this->em->createQuery('SELECT a FROM ' . A::class);
$paginator = new Paginator($query);
$query->setFirstResult(1);
Assert::count(0, \iterator_to_array($paginator));
$query->setFirstResult(0);
Assert::same([$a], \iterator_to_array($paginator));
Expected behavior
The last assertion in the test above fails: this is an unfortunate case of mutable state shared inside Doctrine\ORM\Query
.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 1
- Comments: 20 (19 by maintainers)
Commits related to this issue
- #7837 reproduced issue: DQL caching prevents `WhereInWalker` run Since `WhereInWalker` does not run, query parameters are not translated from their in-memory type to the expected SQL type when the pa... — committed to Ocramius/doctrine2 by Ocramius 5 years ago
- #7837 force expiry of query cache when `WhereInWalker` is being used In order to figure out the paginated query identifier type, we would have to parse the DQL query into an AST+SQL anyway, so we'd h... — committed to Ocramius/doctrine2 by Ocramius 5 years ago
- Merge pull request #7865 from Ocramius/fix/#7837-paginate-with-custom-identifier-types-even-with-cached-dql-parsing #7837 paginate with custom identifier types even with enabled DQL query cache — committed to doctrine/orm by lcobucci 5 years ago
- Merge pull request #10433 from mpdude/re-enable-tests-7820 Make sure tests from #7837 are actually run — committed to doctrine/orm by greg0ire a year ago
- Avoid wasting Opcache memory with Paginator queries This PR prevents the Paginator from causing OpCache "wasted memory" to increase _on every request_ when used with Symfony's `PhpFilesAdapter` as th... — committed to mpdude/doctrine2 by mpdude a year ago
- Make Paginator-internal query cacheable in the query cache Make the `Paginator`-internal query (`... WHERE ... IN (id, id2, id3...)`) cacheable in the query cache again. When the Paginator creates t... — committed to mpdude/doctrine2 by mpdude a year ago
- Avoid wasting Opcache memory with Paginator queries (#10434) This PR prevents the Paginator from causing OpCache "wasted memory" to increase _on every request_ when used with Symfony's `PhpFilesAdapt... — committed to doctrine/orm by mpdude a year ago
- Make Paginator-internal query cacheable in the query cache Make the `Paginator`-internal query (`... WHERE ... IN (id, id2, id3...)`) cacheable in the query cache again. When the Paginator creates t... — committed to mpdude/doctrine2 by mpdude a year ago
- Make Paginator-internal query cacheable in the query cache Make the `Paginator`-internal query (`... WHERE ... IN (id, id2, id3...)`) cacheable in the query cache again. When the Paginator creates t... — committed to mpdude/doctrine2 by mpdude a year ago
- Make Paginator-internal query cacheable in the query cache Make the `Paginator`-internal query (`... WHERE ... IN (id, id2, id3...)`) cacheable in the query cache again. When the Paginator creates t... — committed to mpdude/doctrine2 by mpdude a year ago
- Make Paginator-internal query cacheable in the query cache Make the `Paginator`-internal query (`... WHERE ... IN (id, id2, id3...)`) cacheable in the query cache again. When the Paginator creates t... — committed to mpdude/doctrine2 by mpdude a year ago
- Make Paginator-internal query cacheable in the query cache Make the `Paginator`-internal query (`... WHERE ... IN (id, id2, id3...)`) cacheable in the query cache again. When the Paginator creates t... — committed to mpdude/doctrine2 by mpdude a year ago
- Make Paginator-internal query cacheable in the query cache Make the `Paginator`-internal query (`... WHERE ... IN (id, id2, id3...)`) cacheable in the query cache again. When the Paginator creates t... — committed to mpdude/doctrine2 by mpdude a year ago
- Make Paginator-internal query cacheable in the query cache Make the `Paginator`-internal query (`... WHERE ... IN (id, id2, id3...)`) cacheable in the query cache again. When the Paginator creates t... — committed to Gwemox/orm by mpdude a year ago
Ok, the bug is related to caching: the
WhereInWalker
is only hit if the query is not present in the query cache.If there’s a cache hit for the parser result, then the walker is not reached, and parameters aren’t converted.
I’ll write up a test case tonight.
I will try to restrict this to a more specific use-case 👌
On Wed, Oct 2, 2019, 00:55 Luís Cobucci notifications@github.com wrote: