From 7b53545e1e46e87ff5505d0f1914977bc9a0684f Mon Sep 17 00:00:00 2001 From: "m.guihini" Date: Wed, 24 May 2023 15:16:59 +0000 Subject: [PATCH] Adding ORDER support for UNION queries --- .../FindObjectsFromRawSqlQueryFactory.php | 29 ++++++++++++++++--- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/src/QueryFactory/FindObjectsFromRawSqlQueryFactory.php b/src/QueryFactory/FindObjectsFromRawSqlQueryFactory.php index 6f1de3ed..457b7bd4 100644 --- a/src/QueryFactory/FindObjectsFromRawSqlQueryFactory.php +++ b/src/QueryFactory/FindObjectsFromRawSqlQueryFactory.php @@ -6,6 +6,8 @@ use Doctrine\DBAL\Platforms\MySqlPlatform; use Doctrine\DBAL\Schema\Schema; +use PHPSQLParser\builders\OrderByBuilder; +use PHPSQLParser\builders\SelectStatementBuilder; use TheCodingMachine\TDBM\TDBMException; use TheCodingMachine\TDBM\TDBMService; use PHPSQLParser\PHPSQLCreator; @@ -106,7 +108,7 @@ private function compute(string $sql, ?string $sqlCount): array * @param mixed[] $parsedSql * @param null|string $sqlCount * @return mixed[] An array of 3 elements: [$processedSql, $processedSqlCount, $columnDescriptors] - * @throws \PHPSQLParser\exceptions\UnsupportedFeatureException + * @throws \PHPSQLParser\exceptions\UnsupportedFeatureException|\PHPSQLParser\exceptions\UnableToCreateSQLException */ private function processParsedUnionQuery(array $parsedSql, ?string $sqlCount): array { @@ -120,9 +122,9 @@ private function processParsedUnionQuery(array $parsedSql, ?string $sqlCount): a // Let's reparse the returned SQL (not the most efficient way of doing things) $parser = new PHPSQLParser(); - $parsedSql = $parser->parse($selectProcessedSql); + $parsedSelectSql = $parser->parse($selectProcessedSql); - $parsedSqlList[] = $parsedSql; + $parsedSqlList[] = $parsedSelectSql; } // Let's rebuild the UNION query @@ -133,12 +135,31 @@ private function processParsedUnionQuery(array $parsedSql, ?string $sqlCount): a $generator = new PHPSQLCreator(); - $processedSql = $generator->create($query); + // Replaced the default generator by our own to add parenthesis around each SELECT + $processedSql = $this->buildUnion($query); $processedSqlCount = $generator->create($countQuery); + // Let's add the ORDER BY if any + if (isset($parsedSql['0']['ORDER'])) { + $orderByBuilder = new OrderByBuilder(); + $processedSql .= " " . $orderByBuilder->build($parsedSql['0']['ORDER']); + } + return [$processedSql, $sqlCount ?? $processedSqlCount, $columnDescriptors]; } + /** + * @param mixed[] $parsed + */ + private function buildUnion(array $parsed): string + { + $selectBuilder = new SelectStatementBuilder(); + + return implode(' UNION ', array_map(function ($clause) use ($selectBuilder) { + return '(' . $selectBuilder->build($clause) . ')'; + }, $parsed['UNION'])); + } + /** * @param mixed[] $parsedSql * @param null|string $sqlCount