6
6
7
7
use Doctrine \DBAL \Platforms \MySqlPlatform ;
8
8
use Doctrine \DBAL \Schema \Schema ;
9
+ use PHPSQLParser \builders \OrderByBuilder ;
10
+ use PHPSQLParser \builders \SelectStatementBuilder ;
9
11
use TheCodingMachine \TDBM \TDBMException ;
10
12
use TheCodingMachine \TDBM \TDBMService ;
11
13
use PHPSQLParser \PHPSQLCreator ;
@@ -106,7 +108,7 @@ private function compute(string $sql, ?string $sqlCount): array
106
108
* @param mixed[] $parsedSql
107
109
* @param null|string $sqlCount
108
110
* @return mixed[] An array of 3 elements: [$processedSql, $processedSqlCount, $columnDescriptors]
109
- * @throws \PHPSQLParser\exceptions\UnsupportedFeatureException
111
+ * @throws \PHPSQLParser\exceptions\UnsupportedFeatureException|\PHPSQLParser\exceptions\UnableToCreateSQLException
110
112
*/
111
113
private function processParsedUnionQuery (array $ parsedSql , ?string $ sqlCount ): array
112
114
{
@@ -120,9 +122,9 @@ private function processParsedUnionQuery(array $parsedSql, ?string $sqlCount): a
120
122
121
123
// Let's reparse the returned SQL (not the most efficient way of doing things)
122
124
$ parser = new PHPSQLParser ();
123
- $ parsedSql = $ parser ->parse ($ selectProcessedSql );
125
+ $ parsedSelectSql = $ parser ->parse ($ selectProcessedSql );
124
126
125
- $ parsedSqlList [] = $ parsedSql ;
127
+ $ parsedSqlList [] = $ parsedSelectSql ;
126
128
}
127
129
128
130
// Let's rebuild the UNION query
@@ -133,12 +135,31 @@ private function processParsedUnionQuery(array $parsedSql, ?string $sqlCount): a
133
135
134
136
$ generator = new PHPSQLCreator ();
135
137
136
- $ processedSql = $ generator ->create ($ query );
138
+ // Replaced the default generator by our own to add parenthesis around each SELECT
139
+ $ processedSql = $ this ->buildUnion ($ query );
137
140
$ processedSqlCount = $ generator ->create ($ countQuery );
138
141
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
+
139
148
return [$ processedSql , $ sqlCount ?? $ processedSqlCount , $ columnDescriptors ];
140
149
}
141
150
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
+
142
163
/**
143
164
* @param mixed[] $parsedSql
144
165
* @param null|string $sqlCount
0 commit comments