From fb0b27e1801e0fc5422ed6a9f856f54bd7b7a21f Mon Sep 17 00:00:00 2001 From: Matthias Pigulla Date: Sat, 27 Jan 2024 14:48:49 +0100 Subject: [PATCH] Add a test covering the #11112 issue --- .../ORM/Functional/Ticket/GH11112Test.php | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/GH11112Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11112Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11112Test.php new file mode 100644 index 00000000000..4ecbea9d3e3 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11112Test.php @@ -0,0 +1,79 @@ +useModelSet('cms'); + self::$queryCache = new ArrayAdapter(); + + parent::setUp(); + } + + public function testSimpleQueryHasLimitAndOffsetApplied(): void + { + $platform = $this->_em->getConnection()->getDatabasePlatform(); + $query = $this->_em->createQuery('SELECT u FROM ' . CmsUser::class . ' u'); + $originalSql = $query->getSQL(); + + $query->setMaxResults(10); + $query->setFirstResult(20); + $sql10_20 = $query->getSQL(); + + $query->setMaxResults(30); + $query->setFirstResult(40); + $sql30_40 = $query->getSQL(); + + // The SQL is platform specific and may even be something with outer SELECTS being added. So, + // derive the expected value at runtime through the platform. + self::assertSame($platform->modifyLimitQuery($originalSql, 10, 20), $sql10_20); + self::assertSame($platform->modifyLimitQuery($originalSql, 30, 40), $sql30_40); + + $cacheEntries = self::$queryCache->getValues(); + self::assertCount(1, $cacheEntries); + } + + public function testSubqueryLimitAndOffsetAreIgnored(): void + { + // Not sure what to do about this test. Basically, I want to make sure that + // firstResult/maxResult for subqueries are not relevant, they do not make it + // into the final query at all. That would give us the guarantee that the + // "sql finalizer" step is sufficient for the final, "outer" query and we + // do not need to run finalizers for the subqueries. + + // This DQL/query makes no sense, it's just about creating a subquery in the first place + $queryBuilder = $this->_em->createQueryBuilder(); + $queryBuilder + ->select('o') + ->from(CmsUser::class, 'o') + ->where($queryBuilder->expr()->exists( + $this->_em->createQueryBuilder() + ->select('u') + ->from(CmsUser::class, 'u') + ->setFirstResult(10) + ->setMaxResults(20) + )); + + $query = $queryBuilder->getQuery(); + $originalSql = $query->getSQL(); + + $clone = clone $query; + $clone->setFirstResult(24); + $clone->setMaxResults(42); + $limitedSql = $clone->getSQL(); + + $platform = $this->_em->getConnection()->getDatabasePlatform(); + + // The SQL is platform specific and may even be something with outer SELECTS being added. So, + // derive the expected value at runtime through the platform. + self::assertSame($platform->modifyLimitQuery($originalSql, 42, 24), $limitedSql); + } +}