From 713c9858a182d056096ae55e88b98ba6d1322938 Mon Sep 17 00:00:00 2001 From: Matthias Pigulla Date: Wed, 8 Oct 2025 22:54:33 +0200 Subject: [PATCH] Remove deprecated methods from `ParserResult` and the `SingleSelectExecutor` class This removes methods that have been deprecated in 2.20.x via #11188 and/or got deprecation notices added in #12196. --- UPGRADE.md | 11 +++++ phpstan-baseline.neon | 6 --- src/Query/Exec/SingleSelectExecutor.php | 31 ------------ src/Query/ParserResult.php | 44 ++---------------- .../ParserResultSerializationTest.php | 21 --------- .../ParserResults/single_select_2_17_0.txt | Bin 2369 -> 0 bytes tests/Tests/ORM/Functional/QueryCacheTest.php | 6 ++- tests/Tests/ORM/Query/ParserResultTest.php | 19 -------- 8 files changed, 19 insertions(+), 119 deletions(-) delete mode 100644 src/Query/Exec/SingleSelectExecutor.php delete mode 100644 tests/Tests/ORM/Functional/ParserResults/single_select_2_17_0.txt diff --git a/UPGRADE.md b/UPGRADE.md index c5c9f854b97..6736e87e941 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -1,5 +1,16 @@ # Upgrade to 4.0 +## BC BREAK: Internal structure of `Doctrine\ORM\Query\ParserResult` changed + +The internal structure of `Doctrine\ORM\Query\ParserResult` changed. Thus, it is no longer possible to unserialize cached parser result instances that +were created and serialized with the previous major version of the ORM. + +You need to clear your query cache when upgrading to the new major version. + +## BC BREAK: `Doctrine\ORM\Query\ParserResult` no longer holds `AbstractSqlExecutor`, `Doctrine\ORM\Query\Exec\SingleSelectExecutor` is removed + +This finishes the refactoring started in https://github.com/doctrine/orm/pull/11188: `ParserResult` has to be provided with an `Doctrine\ORM\Query\Exec\SqlFinalizer`. The `SingleSelectExecutor` is removed since it has been replaced by `SingleSelectSqlFinalizer`. + ## BC BREAK: throw on `nullable` on columns that end up being used in a primary key Specifying `nullable` on join columns that are part of a primary key is diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index a122b7caca2..a97ca680785 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -2280,12 +2280,6 @@ parameters: count: 1 path: src/Query/Exec/MultiTableUpdateExecutor.php - - - message: '#^Parameter \#1 \$sql of method Doctrine\\DBAL\\Connection\:\:executeQuery\(\) expects string, list\\|string given\.$#' - identifier: argument.type - count: 1 - path: src/Query/Exec/SingleSelectExecutor.php - - message: '#^Method Doctrine\\ORM\\Query\\Exec\\SingleTableDeleteUpdateExecutor\:\:execute\(\) should return int but returns int\|string\.$#' identifier: return.type diff --git a/src/Query/Exec/SingleSelectExecutor.php b/src/Query/Exec/SingleSelectExecutor.php deleted file mode 100644 index 5445edb9994..00000000000 --- a/src/Query/Exec/SingleSelectExecutor.php +++ /dev/null @@ -1,31 +0,0 @@ -sqlStatements = $sqlWalker->walkSelectStatement($AST); - } - - /** - * {@inheritDoc} - */ - public function execute(Connection $conn, array $params, array $types): Result - { - return $conn->executeQuery($this->sqlStatements, $params, $types, $this->queryCacheProfile); - } -} diff --git a/src/Query/ParserResult.php b/src/Query/ParserResult.php index 34225e046e4..936ab49a05b 100644 --- a/src/Query/ParserResult.php +++ b/src/Query/ParserResult.php @@ -9,8 +9,6 @@ use Doctrine\ORM\Query\Exec\SqlFinalizer; use LogicException; -use function sprintf; - /** * Encapsulates the resulting components from a DQL query parsing process that * can be serialized. @@ -19,11 +17,6 @@ */ class ParserResult { - /** - * The SQL executor used for executing the SQL. - */ - private AbstractSqlExecutor|null $sqlExecutor = null; - /** * The SQL executor used for executing the SQL. */ @@ -68,33 +61,6 @@ public function setResultSetMapping(ResultSetMapping $rsm): void $this->resultSetMapping = $rsm; } - /** - * Sets the SQL executor that should be used for this ParserResult. - * - * @deprecated - */ - public function setSqlExecutor(AbstractSqlExecutor $executor): void - { - $this->sqlExecutor = $executor; - } - - /** - * Gets the SQL executor used by this ParserResult. - * - * @deprecated - */ - public function getSqlExecutor(): AbstractSqlExecutor - { - if ($this->sqlExecutor === null) { - throw new LogicException(sprintf( - 'Executor not set yet. Call %s::setSqlExecutor() first.', - self::class, - )); - } - - return $this->sqlExecutor; - } - public function setSqlFinalizer(SqlFinalizer $finalizer): void { $this->sqlFinalizer = $finalizer; @@ -102,15 +68,11 @@ public function setSqlFinalizer(SqlFinalizer $finalizer): void public function prepareSqlExecutor(Query $query): AbstractSqlExecutor { - if ($this->sqlFinalizer !== null) { - return $this->sqlFinalizer->createExecutor($query); - } - - if ($this->sqlExecutor !== null) { - return $this->sqlExecutor; + if ($this->sqlFinalizer === null) { + throw new LogicException('No SqlFinalizer has been set; this ParserResult is incomplete.'); } - throw new LogicException('This ParserResult lacks both the SqlFinalizer as well as the (legacy) SqlExecutor'); + return $this->sqlFinalizer->createExecutor($query); } /** diff --git a/tests/Tests/ORM/Functional/ParserResultSerializationTest.php b/tests/Tests/ORM/Functional/ParserResultSerializationTest.php index ed21cd93d0b..95e4785e8ee 100644 --- a/tests/Tests/ORM/Functional/ParserResultSerializationTest.php +++ b/tests/Tests/ORM/Functional/ParserResultSerializationTest.php @@ -8,7 +8,6 @@ use Doctrine\ORM\Query; use Doctrine\ORM\Query\Exec\FinalizedSelectExecutor; use Doctrine\ORM\Query\Exec\PreparedExecutorFinalizer; -use Doctrine\ORM\Query\Exec\SingleSelectExecutor; use Doctrine\ORM\Query\ParserResult; use Doctrine\ORM\Query\ResultSetMapping; use Doctrine\Tests\OrmFunctionalTestCase; @@ -18,8 +17,6 @@ use Symfony\Component\VarExporter\Instantiator; use Symfony\Component\VarExporter\VarExporter; -use function file_get_contents; -use function rtrim; use function serialize; use function unserialize; @@ -69,24 +66,6 @@ static function (ParserResult $parserResult): ParserResult { ]; } - #[DataProvider('provideSerializedSingleSelectResults')] - public function testUnserializeSingleSelectResult(string $serialized): void - { - $unserialized = unserialize($serialized); - - $this->assertInstanceOf(ParserResult::class, $unserialized); - $this->assertInstanceOf(ResultSetMapping::class, $unserialized->getResultSetMapping()); - $this->assertEquals(['name' => [0]], $unserialized->getParameterMappings()); - $this->assertInstanceOf(SingleSelectExecutor::class, $unserialized->getSqlExecutor()); - $this->assertIsString($unserialized->getSqlExecutor()->getSqlStatements()); - } - - /** @return Generator */ - public static function provideSerializedSingleSelectResults(): Generator - { - yield '2.17.0' => [rtrim(file_get_contents(__DIR__ . '/ParserResults/single_select_2_17_0.txt'), "\n")]; - } - public function testSymfony44ProvidedData(): void { $sqlExecutor = new FinalizedSelectExecutor('test'); diff --git a/tests/Tests/ORM/Functional/ParserResults/single_select_2_17_0.txt b/tests/Tests/ORM/Functional/ParserResults/single_select_2_17_0.txt deleted file mode 100644 index aa854bfab92d1b06105aeefae72af587f45e042d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2369 zcmbW3TW{Jh6vz9#PZ8yDnkoYHGNWngDAhU**r3v0kSsSj?L6f|W1|*T{qFl8I|-r7 zZhb)5=h!~C-?1|ngGhwuMQlr*(`vq$uD))l+^)W;(one|vq^0z2IA3(;ZTGJe_489 z?$XHv#T#3c;b`vmbZp@ztEJ9wQ(96=v2FHwzSGpM!7ZN$cVuSyj@N{ zPsUe4+>?ho3C@;*PGs+mo98McmhiufAdBRoQK>4oEcGMV_wt0+svl6asPPvL7yiVSNj_> zm8)B9;z0IyATVtG_HnY9?DF|8c+a`-_gqcx7>}`vztfkpxX~$vquJ;QbiDlsI!edW zlI&Ei*C;2M4waBlv_FV0`x)*YT9 zEbnNO!MI2_Sw6qdiPOj+IGmB&8Uz%{0lLRQEqn$+E$*y;bq*uj)L0H(AeCyr+Vx@k zm8qrfm^xH>(mv){Is6V3g0BjfJe}!W;VBrq;2r+0ayaT57Px@er}Km!K5zv&M-^pA zNkTCQ1SsQF8AF||^n%uY-gf_gIsDR~FY=o7||0vI?Igc+#!w9sh9DZ1i!*?y=S^ pb%^j$AnS-9uO@)*&zu8X<9kMSyuuT{n%Q;mtMTmc@9F93)lWDO6tVyS diff --git a/tests/Tests/ORM/Functional/QueryCacheTest.php b/tests/Tests/ORM/Functional/QueryCacheTest.php index d5290add28b..fab3122ceee 100644 --- a/tests/Tests/ORM/Functional/QueryCacheTest.php +++ b/tests/Tests/ORM/Functional/QueryCacheTest.php @@ -7,6 +7,7 @@ use Doctrine\DBAL\Connection; use Doctrine\ORM\Query; use Doctrine\ORM\Query\Exec\AbstractSqlExecutor; +use Doctrine\ORM\Query\Exec\SqlFinalizer; use Doctrine\ORM\Query\ParserResult; use Doctrine\Tests\OrmFunctionalTestCase; use PHPUnit\Framework\Attributes\Depends; @@ -130,8 +131,11 @@ public function execute(Connection $conn, array $params, array $types): int } }; + $sqlFinalizerMock = $this->createMock(SqlFinalizer::class); + $sqlFinalizerMock->method('createExecutor')->with($query)->willReturn($sqlExecutorStub); + $parserResultMock = new ParserResult(); - $parserResultMock->setSqlExecutor($sqlExecutorStub); + $parserResultMock->setSqlFinalizer($sqlFinalizerMock); $cache = $this->createMock(CacheItemPoolInterface::class); diff --git a/tests/Tests/ORM/Query/ParserResultTest.php b/tests/Tests/ORM/Query/ParserResultTest.php index b18d0830574..918b356827b 100644 --- a/tests/Tests/ORM/Query/ParserResultTest.php +++ b/tests/Tests/ORM/Query/ParserResultTest.php @@ -4,10 +4,8 @@ namespace Doctrine\Tests\ORM\Query; -use Doctrine\ORM\Query\Exec\AbstractSqlExecutor; use Doctrine\ORM\Query\ParserResult; use Doctrine\ORM\Query\ResultSetMapping; -use LogicException; use PHPUnit\Framework\TestCase; class ParserResultTest extends TestCase @@ -25,23 +23,6 @@ public function testGetRsm(): void self::assertInstanceOf(ResultSetMapping::class, $this->parserResult->getResultSetMapping()); } - public function testItThrowsWhenAttemptingToAccessTheExecutorBeforeItIsSet(): void - { - $this->expectException(LogicException::class); - $this->expectExceptionMessage( - 'Executor not set yet. Call Doctrine\ORM\Query\ParserResult::setSqlExecutor() first.', - ); - - $this->parserResult->getSqlExecutor(); - } - - public function testSetGetSqlExecutor(): void - { - $executor = $this->createMock(AbstractSqlExecutor::class); - $this->parserResult->setSqlExecutor($executor); - self::assertSame($executor, $this->parserResult->getSqlExecutor()); - } - public function testGetSqlParameterPosition(): void { $this->parserResult->addParameterMapping(1, 1);