|
| 1 | +<?php |
| 2 | + |
| 3 | +declare(strict_types=1); |
| 4 | + |
| 5 | +namespace Doctrine\Tests\ORM\Functional\Ticket; |
| 6 | + |
| 7 | +use Doctrine\Tests\Models\CMS\CmsUser; |
| 8 | +use Doctrine\Tests\OrmFunctionalTestCase; |
| 9 | +use Symfony\Component\Cache\Adapter\ArrayAdapter; |
| 10 | + |
| 11 | +class GH11112Test extends OrmFunctionalTestCase |
| 12 | +{ |
| 13 | + protected function setUp(): void |
| 14 | + { |
| 15 | + $this->useModelSet('cms'); |
| 16 | + self::$queryCache = new ArrayAdapter(); |
| 17 | + |
| 18 | + parent::setUp(); |
| 19 | + } |
| 20 | + |
| 21 | + public function testSimpleQueryHasLimitAndOffsetApplied(): void |
| 22 | + { |
| 23 | + $platform = $this->_em->getConnection()->getDatabasePlatform(); |
| 24 | + $query = $this->_em->createQuery('SELECT u FROM ' . CmsUser::class . ' u'); |
| 25 | + $originalSql = $query->getSQL(); |
| 26 | + |
| 27 | + $query->setMaxResults(10); |
| 28 | + $query->setFirstResult(20); |
| 29 | + $sql10_20 = $query->getSQL(); |
| 30 | + |
| 31 | + $query->setMaxResults(30); |
| 32 | + $query->setFirstResult(40); |
| 33 | + $sql30_40 = $query->getSQL(); |
| 34 | + |
| 35 | + // The SQL is platform specific and may even be something with outer SELECTS being added. So, |
| 36 | + // derive the expected value at runtime through the platform. |
| 37 | + self::assertSame($platform->modifyLimitQuery($originalSql, 10, 20), $sql10_20); |
| 38 | + self::assertSame($platform->modifyLimitQuery($originalSql, 30, 40), $sql30_40); |
| 39 | + |
| 40 | + $cacheEntries = self::$queryCache->getValues(); |
| 41 | + self::assertCount(1, $cacheEntries); |
| 42 | + } |
| 43 | + |
| 44 | + public function testSubqueryLimitAndOffsetAreIgnored(): void |
| 45 | + { |
| 46 | + // Not sure what to do about this test. Basically, I want to make sure that |
| 47 | + // firstResult/maxResult for subqueries are not relevant, they do not make it |
| 48 | + // into the final query at all. That would give us the guarantee that the |
| 49 | + // "sql finalizer" step is sufficient for the final, "outer" query and we |
| 50 | + // do not need to run finalizers for the subqueries. |
| 51 | + |
| 52 | + // This DQL/query makes no sense, it's just about creating a subquery in the first place |
| 53 | + $queryBuilder = $this->_em->createQueryBuilder(); |
| 54 | + $queryBuilder |
| 55 | + ->select('o') |
| 56 | + ->from(CmsUser::class, 'o') |
| 57 | + ->where($queryBuilder->expr()->exists( |
| 58 | + $this->_em->createQueryBuilder() |
| 59 | + ->select('u') |
| 60 | + ->from(CmsUser::class, 'u') |
| 61 | + ->setFirstResult(10) |
| 62 | + ->setMaxResults(20) |
| 63 | + )); |
| 64 | + |
| 65 | + $query = $queryBuilder->getQuery(); |
| 66 | + $originalSql = $query->getSQL(); |
| 67 | + |
| 68 | + $clone = clone $query; |
| 69 | + $clone->setFirstResult(24); |
| 70 | + $clone->setMaxResults(42); |
| 71 | + $limitedSql = $clone->getSQL(); |
| 72 | + |
| 73 | + $platform = $this->_em->getConnection()->getDatabasePlatform(); |
| 74 | + |
| 75 | + // The SQL is platform specific and may even be something with outer SELECTS being added. So, |
| 76 | + // derive the expected value at runtime through the platform. |
| 77 | + self::assertSame($platform->modifyLimitQuery($originalSql, 42, 24), $limitedSql); |
| 78 | + } |
| 79 | +} |
0 commit comments