Skip to content

Introduced finalizeAndExecute to the AbstractSqlWalker, unified SingleStatementExecutor #11558

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 0 additions & 14 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -861,20 +861,6 @@
<code><![CDATA[$this->sqlStatements]]></code>
</PossiblyInvalidArgument>
</file>
<file src="src/Query/Exec/SingleTableDeleteUpdateExecutor.php">
<InvalidReturnStatement>
<code><![CDATA[$conn->executeStatement($this->sqlStatements, $params, $types)]]></code>
</InvalidReturnStatement>
<InvalidReturnType>
<code><![CDATA[int]]></code>
</InvalidReturnType>
<PossiblyInvalidArgument>
<code><![CDATA[$this->sqlStatements]]></code>
</PossiblyInvalidArgument>
<PropertyNotSetInConstructor>
<code><![CDATA[SingleTableDeleteUpdateExecutor]]></code>
</PropertyNotSetInConstructor>
</file>
<file src="src/Query/Expr/Andx.php">
<NonInvariantDocblockPropertyType>
<code><![CDATA[$allowedClasses]]></code>
Expand Down
3 changes: 1 addition & 2 deletions src/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ protected function _doExecute(): Result|int
$this->em->getConnection()->getParams(),
);

return $executor->execute($this->em->getConnection(), $sqlParams, $types);
return $executor->finalizeAndExecute($this, $this->em->getConnection(), $sqlParams, $types);
}

/**
Expand Down Expand Up @@ -660,7 +660,6 @@ protected function getQueryCacheId(): string
$this->getDQL() . serialize($this->hints) .
'&platform=' . get_debug_type($this->getEntityManager()->getConnection()->getDatabasePlatform()) .
($this->em->hasFilters() ? $this->em->getFilters()->getHash() : '') .
'&firstResult=' . $this->firstResult . '&maxResult=' . $this->maxResults .
'&hydrationMode=' . $this->hydrationMode . '&types=' . serialize($this->parsedTypes) . 'DOCTRINE_QUERY_CACHE_SALT',
);
}
Expand Down
18 changes: 15 additions & 3 deletions src/Query/Exec/AbstractSqlExecutor.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@

namespace Doctrine\ORM\Query\Exec;

use Doctrine\DBAL\ArrayParameterType;
use Doctrine\DBAL\Cache\QueryCacheProfile;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Result;
use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\Query;
use Doctrine\ORM\Query\SqlWalker;

Check failure on line 11 in src/Query/Exec/AbstractSqlExecutor.php

View workflow job for this annotation

GitHub Actions / coding-standards / Coding Standards (8.3)

Type Doctrine\ORM\Query\SqlWalker is not used in this file.

/**
* Base class for SQL statement executors.
Expand All @@ -20,7 +19,7 @@
* @psalm-type WrapperParameterType = string|Type|ParameterType::*|ArrayParameterType::*
* @psalm-type WrapperParameterTypeArray = array<int<0, max>, WrapperParameterType>|array<string, WrapperParameterType>
*/
abstract class AbstractSqlExecutor

Check failure on line 22 in src/Query/Exec/AbstractSqlExecutor.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (default, phpstan.neon)

Invalid type definition detected in type alias WrapperParameterType.

Check failure on line 22 in src/Query/Exec/AbstractSqlExecutor.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (default, phpstan.neon)

Invalid type definition detected in type alias WrapperParameterTypeArray.

Check failure on line 22 in src/Query/Exec/AbstractSqlExecutor.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (3.8.2, phpstan-dbal3.neon)

Invalid type definition detected in type alias WrapperParameterType.

Check failure on line 22 in src/Query/Exec/AbstractSqlExecutor.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (3.8.2, phpstan-dbal3.neon)

Invalid type definition detected in type alias WrapperParameterTypeArray.
{
/** @var list<string>|string */
protected array|string $sqlStatements;
Expand Down Expand Up @@ -50,12 +49,25 @@
$this->queryCacheProfile = null;
}

/**
* Finalize and executes all sql statements.
*
* @param Query $query The query to be finalized and executed.
* @param Connection $conn The database connection that is used to execute the queries.
* @param list<mixed>|array<string, mixed> $params The parameters.
* @psalm-param WrapperParameterTypeArray $types The parameter types.

Check failure on line 58 in src/Query/Exec/AbstractSqlExecutor.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (default)

UndefinedDocblockClass

src/Query/Exec/AbstractSqlExecutor.php:58:21: UndefinedDocblockClass: Docblock-defined class, interface or enum named Doctrine\ORM\Query\Exec\ParameterType does not exist (see https://psalm.dev/200)

Check failure on line 58 in src/Query/Exec/AbstractSqlExecutor.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (default)

UndefinedDocblockClass

src/Query/Exec/AbstractSqlExecutor.php:58:21: UndefinedDocblockClass: Docblock-defined class, interface or enum named Doctrine\ORM\Query\Exec\ArrayParameterType does not exist (see https://psalm.dev/200)

Check failure on line 58 in src/Query/Exec/AbstractSqlExecutor.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (default)

UndefinedDocblockClass

src/Query/Exec/AbstractSqlExecutor.php:58:21: UndefinedDocblockClass: Docblock-defined class, interface or enum named Doctrine\ORM\Query\Exec\Type does not exist (see https://psalm.dev/200)

Check failure on line 58 in src/Query/Exec/AbstractSqlExecutor.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (3.8.2)

UndefinedDocblockClass

src/Query/Exec/AbstractSqlExecutor.php:58:21: UndefinedDocblockClass: Docblock-defined class, interface or enum named Doctrine\ORM\Query\Exec\ParameterType does not exist (see https://psalm.dev/200)

Check failure on line 58 in src/Query/Exec/AbstractSqlExecutor.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (3.8.2)

UndefinedDocblockClass

src/Query/Exec/AbstractSqlExecutor.php:58:21: UndefinedDocblockClass: Docblock-defined class, interface or enum named Doctrine\ORM\Query\Exec\ArrayParameterType does not exist (see https://psalm.dev/200)

Check failure on line 58 in src/Query/Exec/AbstractSqlExecutor.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (3.8.2)

UndefinedDocblockClass

src/Query/Exec/AbstractSqlExecutor.php:58:21: UndefinedDocblockClass: Docblock-defined class, interface or enum named Doctrine\ORM\Query\Exec\Type does not exist (see https://psalm.dev/200)
*/
public function finalizeAndExecute(Query $query, Connection $connection, array $params, array $types)

Check failure on line 60 in src/Query/Exec/AbstractSqlExecutor.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (default)

MissingReturnType

src/Query/Exec/AbstractSqlExecutor.php:60:21: MissingReturnType: Method Doctrine\ORM\Query\Exec\AbstractSqlExecutor::finalizeAndExecute does not have a return type (see https://psalm.dev/050)

Check failure on line 60 in src/Query/Exec/AbstractSqlExecutor.php

View workflow job for this annotation

GitHub Actions / coding-standards / Coding Standards (8.3)

Method \Doctrine\ORM\Query\Exec\AbstractSqlExecutor::finalizeAndExecute() does not have return type hint nor @return annotation for its return value.

Check failure on line 60 in src/Query/Exec/AbstractSqlExecutor.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (default, phpstan.neon)

PHPDoc tag @param references unknown parameter: $conn

Check failure on line 60 in src/Query/Exec/AbstractSqlExecutor.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (3.8.2, phpstan-dbal3.neon)

PHPDoc tag @param references unknown parameter: $conn

Check failure on line 60 in src/Query/Exec/AbstractSqlExecutor.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (3.8.2)

MissingReturnType

src/Query/Exec/AbstractSqlExecutor.php:60:21: MissingReturnType: Method Doctrine\ORM\Query\Exec\AbstractSqlExecutor::finalizeAndExecute does not have a return type (see https://psalm.dev/050)
{
return $this->execute($connection, $params, $types);
}

/**
* Executes all sql statements.
*
* @param Connection $conn The database connection that is used to execute the queries.
* @param list<mixed>|array<string, mixed> $params The parameters.
* @psalm-param WrapperParameterTypeArray $types The parameter types.

Check failure on line 70 in src/Query/Exec/AbstractSqlExecutor.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (default)

UndefinedDocblockClass

src/Query/Exec/AbstractSqlExecutor.php:70:21: UndefinedDocblockClass: Docblock-defined class, interface or enum named Doctrine\ORM\Query\Exec\ParameterType does not exist (see https://psalm.dev/200)

Check failure on line 70 in src/Query/Exec/AbstractSqlExecutor.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (default)

UndefinedDocblockClass

src/Query/Exec/AbstractSqlExecutor.php:70:21: UndefinedDocblockClass: Docblock-defined class, interface or enum named Doctrine\ORM\Query\Exec\ArrayParameterType does not exist (see https://psalm.dev/200)

Check failure on line 70 in src/Query/Exec/AbstractSqlExecutor.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (default)

UndefinedDocblockClass

src/Query/Exec/AbstractSqlExecutor.php:70:21: UndefinedDocblockClass: Docblock-defined class, interface or enum named Doctrine\ORM\Query\Exec\Type does not exist (see https://psalm.dev/200)

Check failure on line 70 in src/Query/Exec/AbstractSqlExecutor.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (3.8.2)

UndefinedDocblockClass

src/Query/Exec/AbstractSqlExecutor.php:70:21: UndefinedDocblockClass: Docblock-defined class, interface or enum named Doctrine\ORM\Query\Exec\ParameterType does not exist (see https://psalm.dev/200)

Check failure on line 70 in src/Query/Exec/AbstractSqlExecutor.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (3.8.2)

UndefinedDocblockClass

src/Query/Exec/AbstractSqlExecutor.php:70:21: UndefinedDocblockClass: Docblock-defined class, interface or enum named Doctrine\ORM\Query\Exec\ArrayParameterType does not exist (see https://psalm.dev/200)

Check failure on line 70 in src/Query/Exec/AbstractSqlExecutor.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (3.8.2)

UndefinedDocblockClass

src/Query/Exec/AbstractSqlExecutor.php:70:21: UndefinedDocblockClass: Docblock-defined class, interface or enum named Doctrine\ORM\Query\Exec\Type does not exist (see https://psalm.dev/200)
*/
abstract public function execute(Connection $conn, array $params, array $types): Result|int;
}
31 changes: 0 additions & 31 deletions src/Query/Exec/SingleSelectExecutor.php

This file was deleted.

76 changes: 76 additions & 0 deletions src/Query/Exec/SingleStatementExecutor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

declare(strict_types=1);

namespace Doctrine\ORM\Query\Exec;

use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Connections\PrimaryReadReplicaConnection;
use Doctrine\DBAL\LockMode;
use Doctrine\DBAL\Result;
use Doctrine\ORM\OptimisticLockException;
use Doctrine\ORM\Query;
use Doctrine\ORM\Query\SqlWalker;
use Doctrine\ORM\Query\AST;

Check failure on line 14 in src/Query/Exec/SingleStatementExecutor.php

View workflow job for this annotation

GitHub Actions / coding-standards / Coding Standards (8.3)

Use statements should be sorted alphabetically. The first wrong one is Doctrine\ORM\Query\AST.
use Doctrine\ORM\Utility\LockSqlHelper;

/**
* Executor that executes the SQL statement for simple DQL SELECT/UPDATE/DELETE statements.
*
* @link www.doctrine-project.org
*/
class SingleStatementExecutor extends AbstractSqlExecutor

Check failure on line 22 in src/Query/Exec/SingleStatementExecutor.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (default)

PropertyNotSetInConstructor

src/Query/Exec/SingleStatementExecutor.php:22:7: PropertyNotSetInConstructor: Property Doctrine\ORM\Query\Exec\SingleStatementExecutor::$sqlStatements is not defined in constructor of Doctrine\ORM\Query\Exec\SingleStatementExecutor or in any private or final methods called in the constructor (see https://psalm.dev/074)

Check failure on line 22 in src/Query/Exec/SingleStatementExecutor.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (3.8.2)

PropertyNotSetInConstructor

src/Query/Exec/SingleStatementExecutor.php:22:7: PropertyNotSetInConstructor: Property Doctrine\ORM\Query\Exec\SingleStatementExecutor::$sqlStatements is not defined in constructor of Doctrine\ORM\Query\Exec\SingleStatementExecutor or in any private or final methods called in the constructor (see https://psalm.dev/074)
{
use LockSqlHelper;

private array $selectedClasses;

Check failure on line 26 in src/Query/Exec/SingleStatementExecutor.php

View workflow job for this annotation

GitHub Actions / coding-standards / Coding Standards (8.3)

@var annotation of property \Doctrine\ORM\Query\Exec\SingleStatementExecutor::$selectedClasses does not specify type hint for its items.

public function __construct(AST\Node $AST, SqlWalker $sqlWalker)
{
$this->selectedClasses = $sqlWalker->getSelectedClasses();
if ($AST instanceof AST\SelectStatement) {
$this->sqlStatements = $sqlWalker->walkSelectStatement($AST);
} elseif ($AST instanceof AST\UpdateStatement) {
$this->sqlStatements = $sqlWalker->walkUpdateStatement($AST);
} elseif ($AST instanceof AST\DeleteStatement) {
$this->sqlStatements = $sqlWalker->walkDeleteStatement($AST);
}
}

public function finalizeAndExecute(Query $query, Connection $connection, array $params, array $types)

Check failure on line 40 in src/Query/Exec/SingleStatementExecutor.php

View workflow job for this annotation

GitHub Actions / coding-standards / Coding Standards (8.3)

Method \Doctrine\ORM\Query\Exec\SingleStatementExecutor::finalizeAndExecute() does not have @param annotation for its traversable parameter $params.

Check failure on line 40 in src/Query/Exec/SingleStatementExecutor.php

View workflow job for this annotation

GitHub Actions / coding-standards / Coding Standards (8.3)

Method \Doctrine\ORM\Query\Exec\SingleStatementExecutor::finalizeAndExecute() does not have @param annotation for its traversable parameter $types.

Check failure on line 40 in src/Query/Exec/SingleStatementExecutor.php

View workflow job for this annotation

GitHub Actions / coding-standards / Coding Standards (8.3)

Method \Doctrine\ORM\Query\Exec\SingleStatementExecutor::finalizeAndExecute() does not have return type hint nor @return annotation for its return value.
{
$platform = $connection->getDatabasePlatform();
$lockMode = $query->getHint(Query::HINT_LOCK_MODE) ?: LockMode::NONE;

$this->sqlStatements = $platform->modifyLimitQuery(
$this->sqlStatements,
$query->getFirstResult(),
$query->getMaxResults()

Check failure on line 48 in src/Query/Exec/SingleStatementExecutor.php

View workflow job for this annotation

GitHub Actions / coding-standards / Coding Standards (8.3)

Multi-line function calls must have a trailing comma after the last parameter.
);

if ($lockMode === LockMode::PESSIMISTIC_READ) {
$this->sqlStatements = $this->sqlStatements . ' ' . $this->getReadLockSQL($platform);

Check failure on line 52 in src/Query/Exec/SingleStatementExecutor.php

View workflow job for this annotation

GitHub Actions / coding-standards / Coding Standards (8.3)

Use ".=" operator instead of "=" and ".".
} elseif ($lockMode === LockMode::PESSIMISTIC_WRITE) {
$this->sqlStatements = $this->sqlStatements . ' ' . $this->getWriteLockSQL($platform);

Check failure on line 54 in src/Query/Exec/SingleStatementExecutor.php

View workflow job for this annotation

GitHub Actions / coding-standards / Coding Standards (8.3)

Use ".=" operator instead of "=" and ".".
} elseif ($lockMode === LockMode::OPTIMISTIC) {
foreach ($this->selectedClasses as $selectedClass) {
if (!$selectedClass['class']->isVersioned) {
throw OptimisticLockException::lockFailed($selectedClass['class']->name);
}
}
}

return parent::finalizeAndExecute($query, $connection, $params, $types);
}

/**
* {@inheritDoc}
*/
public function execute(Connection $conn, array $params, array $types): Result
{
if ($conn instanceof PrimaryReadReplicaConnection) {
$conn->ensureConnectedToPrimary();
}
return $conn->executeQuery($this->sqlStatements, $params, $types, $this->queryCacheProfile);
}
}
42 changes: 0 additions & 42 deletions src/Query/Exec/SingleTableDeleteUpdateExecutor.php

This file was deleted.

43 changes: 12 additions & 31 deletions src/Query/SqlWalker.php
Original file line number Diff line number Diff line change
Expand Up @@ -225,15 +225,15 @@ public function getExecutor(AST\SelectStatement|AST\UpdateStatement|AST\DeleteSt
{
return match (true) {
$statement instanceof AST\SelectStatement
=> new Exec\SingleSelectExecutor($statement, $this),
=> new Exec\SingleStatementExecutor($statement, $this),
$statement instanceof AST\UpdateStatement
=> $this->em->getClassMetadata($statement->updateClause->abstractSchemaName)->isInheritanceTypeJoined()
? new Exec\MultiTableUpdateExecutor($statement, $this)
: new Exec\SingleTableDeleteUpdateExecutor($statement, $this),
: new Exec\SingleStatementExecutor($statement, $this),
$statement instanceof AST\DeleteStatement
=> $this->em->getClassMetadata($statement->deleteClause->abstractSchemaName)->isInheritanceTypeJoined()
? new Exec\MultiTableDeleteExecutor($statement, $this)
: new Exec\SingleTableDeleteUpdateExecutor($statement, $this),
: new Exec\SingleStatementExecutor($statement, $this),
};
}

Expand Down Expand Up @@ -464,10 +464,7 @@ private function generateFilterConditionSQL(
*/
public function walkSelectStatement(AST\SelectStatement $selectStatement): string
{
$limit = $this->query->getMaxResults();
$offset = $this->query->getFirstResult();
$lockMode = $this->query->getHint(Query::HINT_LOCK_MODE) ?: LockMode::NONE;
$sql = $this->walkSelectClause($selectStatement->selectClause)
$sql = $this->walkSelectClause($selectStatement->selectClause)
. $this->walkFromClause($selectStatement->fromClause)
. $this->walkWhereClause($selectStatement->whereClause);

Expand All @@ -488,30 +485,6 @@ public function walkSelectStatement(AST\SelectStatement $selectStatement): strin
$sql .= ' ORDER BY ' . $orderBySql;
}

$sql = $this->platform->modifyLimitQuery($sql, $limit, $offset);

if ($lockMode === LockMode::NONE) {
return $sql;
}

if ($lockMode === LockMode::PESSIMISTIC_READ) {
return $sql . ' ' . $this->getReadLockSQL($this->platform);
}

if ($lockMode === LockMode::PESSIMISTIC_WRITE) {
return $sql . ' ' . $this->getWriteLockSQL($this->platform);
}

if ($lockMode !== LockMode::OPTIMISTIC) {
throw QueryException::invalidLockMode();
}

foreach ($this->selectedClasses as $selectedClass) {
if (! $selectedClass['class']->isVersioned) {
throw OptimisticLockException::lockFailed($selectedClass['class']->name);
}
}

return $sql;
}

Expand Down Expand Up @@ -2226,6 +2199,14 @@ public function walkResultVariable(string $resultVariable): string
return $resultAlias;
}

/**
* @return array A list of classes that appear in non-scalar SelectExpressions.
*/
public function getSelectedClasses(): array
{
return $this->selectedClasses;
}

/**
* @return string The list in parentheses of valid child discriminators from the given class
*
Expand Down
10 changes: 5 additions & 5 deletions tests/Tests/ORM/Functional/ParserResultSerializationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use Closure;
use Doctrine\ORM\Query;
use Doctrine\ORM\Query\Exec\SingleSelectExecutor;
use Doctrine\ORM\Query\Exec\SingleStatementExecutor;
use Doctrine\ORM\Query\ParserResult;
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\Tests\OrmFunctionalTestCase;
Expand Down Expand Up @@ -43,7 +43,7 @@ public function testSerializeParserResult(Closure $toSerializedAndBack): void
$this->assertInstanceOf(ParserResult::class, $unserialized);
$this->assertInstanceOf(ResultSetMapping::class, $unserialized->getResultSetMapping());
$this->assertEquals(['name' => [0]], $unserialized->getParameterMappings());
$this->assertInstanceOf(SingleSelectExecutor::class, $unserialized->getSqlExecutor());
$this->assertInstanceOf(SingleStatementExecutor::class, $unserialized->getSqlExecutor());
}

/** @return Generator<string, array{Closure(ParserResult): ParserResult}> */
Expand Down Expand Up @@ -75,7 +75,7 @@ public function testUnserializeSingleSelectResult(string $serialized): void
$this->assertInstanceOf(ParserResult::class, $unserialized);
$this->assertInstanceOf(ResultSetMapping::class, $unserialized->getResultSetMapping());
$this->assertEquals(['name' => [0]], $unserialized->getParameterMappings());
$this->assertInstanceOf(SingleSelectExecutor::class, $unserialized->getSqlExecutor());
$this->assertInstanceOf(SingleStatementExecutor::class, $unserialized->getSqlExecutor());
$this->assertIsString($unserialized->getSqlExecutor()->getSqlStatements());
}

Expand All @@ -87,7 +87,7 @@ public static function provideSerializedSingleSelectResults(): Generator

public function testSymfony44ProvidedData(): void
{
$sqlExecutor = $this->createMock(SingleSelectExecutor::class);
$sqlExecutor = $this->createMock(SingleStatementExecutor::class);
$resultSetMapping = $this->createMock(ResultSetMapping::class);

$parserResult = new ParserResult();
Expand All @@ -101,7 +101,7 @@ public function testSymfony44ProvidedData(): void
$this->assertInstanceOf(ParserResult::class, $unserialized);
$this->assertInstanceOf(ResultSetMapping::class, $unserialized->getResultSetMapping());
$this->assertEquals(['name' => [0]], $unserialized->getParameterMappings());
$this->assertInstanceOf(SingleSelectExecutor::class, $unserialized->getSqlExecutor());
$this->assertInstanceOf(SingleStatementExecutor::class, $unserialized->getSqlExecutor());
}

private static function parseQuery(Query $query): ParserResult
Expand Down
Loading