Skip to content

Commit 246b2d7

Browse files
mhtghnhomersimpsons
authored andcommitted
Adding ORDER support for UNION queries
1 parent 9854491 commit 246b2d7

File tree

1 file changed

+25
-4
lines changed

1 file changed

+25
-4
lines changed

src/QueryFactory/FindObjectsFromRawSqlQueryFactory.php

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
use Doctrine\DBAL\Platforms\MySqlPlatform;
88
use Doctrine\DBAL\Schema\Schema;
9+
use PHPSQLParser\builders\OrderByBuilder;
10+
use PHPSQLParser\builders\SelectStatementBuilder;
911
use TheCodingMachine\TDBM\TDBMException;
1012
use TheCodingMachine\TDBM\TDBMService;
1113
use PHPSQLParser\PHPSQLCreator;
@@ -106,7 +108,7 @@ private function compute(string $sql, ?string $sqlCount): array
106108
* @param mixed[] $parsedSql
107109
* @param null|string $sqlCount
108110
* @return mixed[] An array of 3 elements: [$processedSql, $processedSqlCount, $columnDescriptors]
109-
* @throws \PHPSQLParser\exceptions\UnsupportedFeatureException
111+
* @throws \PHPSQLParser\exceptions\UnsupportedFeatureException|\PHPSQLParser\exceptions\UnableToCreateSQLException
110112
*/
111113
private function processParsedUnionQuery(array $parsedSql, ?string $sqlCount): array
112114
{
@@ -120,9 +122,9 @@ private function processParsedUnionQuery(array $parsedSql, ?string $sqlCount): a
120122

121123
// Let's reparse the returned SQL (not the most efficient way of doing things)
122124
$parser = new PHPSQLParser();
123-
$parsedSql = $parser->parse($selectProcessedSql);
125+
$parsedSelectSql = $parser->parse($selectProcessedSql);
124126

125-
$parsedSqlList[] = $parsedSql;
127+
$parsedSqlList[] = $parsedSelectSql;
126128
}
127129

128130
// Let's rebuild the UNION query
@@ -133,12 +135,31 @@ private function processParsedUnionQuery(array $parsedSql, ?string $sqlCount): a
133135

134136
$generator = new PHPSQLCreator();
135137

136-
$processedSql = $generator->create($query);
138+
// Replaced the default generator by our own to add parenthesis around each SELECT
139+
$processedSql = $this->buildUnion($query);
137140
$processedSqlCount = $generator->create($countQuery);
138141

142+
// Let's add the ORDER BY if any
143+
if (isset($parsedSql['0']['ORDER'])) {
144+
$orderByBuilder = new OrderByBuilder();
145+
$processedSql .= " " . $orderByBuilder->build($parsedSql['0']['ORDER']);
146+
}
147+
139148
return [$processedSql, $sqlCount ?? $processedSqlCount, $columnDescriptors];
140149
}
141150

151+
/**
152+
* @param mixed[] $parsed
153+
*/
154+
private function buildUnion(array $parsed): string
155+
{
156+
$selectBuilder = new SelectStatementBuilder();
157+
158+
return implode(' UNION ', array_map(function ($clause) use ($selectBuilder) {
159+
return '(' . $selectBuilder->build($clause) . ')';
160+
}, $parsed['UNION']));
161+
}
162+
142163
/**
143164
* @param mixed[] $parsedSql
144165
* @param null|string $sqlCount

0 commit comments

Comments
 (0)