|
9 | 9 | use TheCodingMachine\TDBM\TDBMService;
|
10 | 10 | use PHPSQLParser\PHPSQLCreator;
|
11 | 11 | use PHPSQLParser\PHPSQLParser;
|
| 12 | +use function array_merge; |
12 | 13 |
|
13 | 14 | /**
|
14 | 15 | * This class is in charge of formatting the SQL passed to findObjectsFromRawSql method.
|
@@ -224,7 +225,7 @@ private function formatSelect(array $baseSelect): array
|
224 | 225 | ],
|
225 | 226 | 'alias' => [
|
226 | 227 | 'as' => true,
|
227 |
| - 'name' => $alias, |
| 228 | + 'name' => $connection->quoteIdentifier($alias), |
228 | 229 | ]
|
229 | 230 | ];
|
230 | 231 | $formattedSelect[] = $astColumn;
|
@@ -352,20 +353,98 @@ private function generateGroupedSqlCount(array $parsedSql): array
|
352 | 353 | {
|
353 | 354 | $group = $parsedSql['GROUP'];
|
354 | 355 | unset($parsedSql['GROUP']);
|
355 |
| - $parsedSql['SELECT'] = [[ |
356 |
| - 'expr_type' => 'aggregate_function', |
357 |
| - 'alias' => [ |
358 |
| - 'as' => true, |
359 |
| - 'name' => 'cnt', |
360 |
| - ], |
361 |
| - 'base_expr' => 'COUNT', |
362 |
| - 'sub_tree' => array_merge([[ |
| 356 | + |
| 357 | + // Count(DISTINCT ...) on multiple columns is only valid in MySQL (unsupported on Pgsql or Oracle). For those, we need to do a subquery. |
| 358 | + if (count($group) === 1 || $this->tdbmService->getConnection()->getDatabasePlatform() instanceof MySqlPlatform) { |
| 359 | + $parsedSql['SELECT'] = [[ |
| 360 | + 'expr_type' => 'aggregate_function', |
| 361 | + 'alias' => [ |
| 362 | + 'as' => true, |
| 363 | + 'name' => 'cnt', |
| 364 | + ], |
| 365 | + 'base_expr' => 'COUNT', |
| 366 | + 'sub_tree' => array_merge([[ |
| 367 | + 'expr_type' => 'reserved', |
| 368 | + 'base_expr' => 'DISTINCT', |
| 369 | + 'delim' => ',' |
| 370 | + ]], $group), |
| 371 | + 'delim' => false, |
| 372 | + ]]; |
| 373 | + } else { |
| 374 | + $innerColumns = [[ |
363 | 375 | 'expr_type' => 'reserved',
|
364 | 376 | 'base_expr' => 'DISTINCT',
|
365 |
| - 'delim' => ',' |
366 |
| - ]], $group), |
367 |
| - 'delim' => false, |
368 |
| - ]]; |
| 377 | + 'delim' => ' ' |
| 378 | + ]]; |
| 379 | + foreach ($group as $item) { |
| 380 | + $item['delim'] = ','; |
| 381 | + $innerColumns[] = $item; |
| 382 | + } |
| 383 | + $innerColumns[count($innerColumns)-1]['delim'] = false; |
| 384 | + $parsedSql['SELECT'] = $innerColumns; |
| 385 | + |
| 386 | + $parsedSql = [ |
| 387 | + 'SELECT' => |
| 388 | + [ |
| 389 | + 0 => |
| 390 | + [ |
| 391 | + 'expr_type' => 'aggregate_function', |
| 392 | + 'alias' => |
| 393 | + [ |
| 394 | + 'as' => true, |
| 395 | + 'name' => 'cnt', |
| 396 | + 'base_expr' => 'AS cnt', |
| 397 | + 'no_quotes' => |
| 398 | + [ |
| 399 | + 'delim' => false, |
| 400 | + 'parts' => |
| 401 | + [ |
| 402 | + 0 => 'cnt', |
| 403 | + ], |
| 404 | + ], |
| 405 | + ], |
| 406 | + 'base_expr' => 'COUNT', |
| 407 | + 'sub_tree' => |
| 408 | + [ |
| 409 | + 0 => |
| 410 | + [ |
| 411 | + 'expr_type' => 'colref', |
| 412 | + 'base_expr' => '*', |
| 413 | + 'sub_tree' => false, |
| 414 | + ], |
| 415 | + ], |
| 416 | + 'delim' => false, |
| 417 | + ], |
| 418 | + ], |
| 419 | + 'FROM' => |
| 420 | + [ |
| 421 | + 0 => |
| 422 | + [ |
| 423 | + 'expr_type' => 'subquery', |
| 424 | + 'alias' => |
| 425 | + [ |
| 426 | + 'as' => false, |
| 427 | + 'name' => 'subquery', |
| 428 | + 'no_quotes' => |
| 429 | + [ |
| 430 | + 'delim' => false, |
| 431 | + 'parts' => |
| 432 | + [ |
| 433 | + 0 => 'subquery', |
| 434 | + ], |
| 435 | + ], |
| 436 | + 'base_expr' => 'subquery', |
| 437 | + ], |
| 438 | + 'hints' => false, |
| 439 | + 'join_type' => 'JOIN', |
| 440 | + 'ref_type' => false, |
| 441 | + 'ref_clause' => false, |
| 442 | + //'base_expr' => 'SELECT id FROM country', |
| 443 | + 'sub_tree' => $parsedSql |
| 444 | + ], |
| 445 | + ], |
| 446 | + ]; |
| 447 | + } |
369 | 448 | return $parsedSql;
|
370 | 449 | }
|
371 | 450 |
|
|
0 commit comments