|
23 | 23 | use function str_contains;
|
24 | 24 | use function str_replace;
|
25 | 25 | use function strtolower;
|
26 |
| -use function trim; |
27 | 26 |
|
28 | 27 | use const CASE_LOWER;
|
29 | 28 |
|
@@ -162,44 +161,19 @@ protected function _getPortableTableDefinition(array $table): string
|
162 | 161 | */
|
163 | 162 | protected function _getPortableTableIndexesList(array $rows, string $tableName): array
|
164 | 163 | {
|
165 |
| - $buffer = []; |
166 |
| - foreach ($rows as $row) { |
167 |
| - $colNumbers = array_map('intval', explode(' ', $row['indkey'])); |
168 |
| - $columnNameSql = sprintf( |
169 |
| - <<<'SQL' |
170 |
| - SELECT attnum, |
171 |
| - quote_ident(attname) AS attname |
172 |
| - FROM pg_attribute |
173 |
| - WHERE attrelid = %d |
174 |
| - AND attnum IN (%s) |
175 |
| - ORDER BY attnum |
176 |
| - SQL, |
177 |
| - $row['indrelid'], |
178 |
| - implode(', ', $colNumbers), |
179 |
| - ); |
180 |
| - |
181 |
| - // @phpstan-ignore missingType.checkedException |
182 |
| - $indexColumns = $this->connection->fetchAllAssociative($columnNameSql); |
183 |
| - |
184 |
| - // required for getting the order of the columns right. |
185 |
| - foreach ($colNumbers as $colNum) { |
186 |
| - foreach ($indexColumns as $colRow) { |
187 |
| - if ($colNum !== $colRow['attnum']) { |
188 |
| - continue; |
189 |
| - } |
190 |
| - |
191 |
| - $buffer[] = [ |
192 |
| - 'key_name' => $row['relname'], |
193 |
| - 'column_name' => trim($colRow['attname']), |
194 |
| - 'non_unique' => ! $row['indisunique'], |
195 |
| - 'primary' => $row['indisprimary'], |
196 |
| - 'where' => $row['where'], |
197 |
| - ]; |
198 |
| - } |
199 |
| - } |
200 |
| - } |
201 |
| - |
202 |
| - return parent::_getPortableTableIndexesList($buffer, $tableName); |
| 164 | + return parent::_getPortableTableIndexesList(array_map( |
| 165 | + /** @param array<string, mixed> $row */ |
| 166 | + static function (array $row): array { |
| 167 | + return [ |
| 168 | + 'key_name' => $row['relname'], |
| 169 | + 'non_unique' => ! $row['indisunique'], |
| 170 | + 'primary' => $row['indisprimary'], |
| 171 | + 'where' => $row['where'], |
| 172 | + 'column_name' => $row['attname'], |
| 173 | + ]; |
| 174 | + }, |
| 175 | + $rows, |
| 176 | + ), $tableName); |
203 | 177 | }
|
204 | 178 |
|
205 | 179 | /**
|
@@ -496,24 +470,26 @@ protected function selectIndexColumns(string $databaseName, ?string $tableName =
|
496 | 470 | $sql = sprintf(
|
497 | 471 | <<<'SQL'
|
498 | 472 | SELECT
|
499 |
| - quote_ident(tn.nspname) AS schema_name, |
500 |
| - quote_ident(tc.relname) AS table_name, |
| 473 | + quote_ident(n.nspname) AS schema_name, |
| 474 | + quote_ident(c.relname) AS table_name, |
501 | 475 | quote_ident(ic.relname) AS relname,
|
502 | 476 | i.indisunique,
|
503 | 477 | i.indisprimary,
|
504 | 478 | i.indkey,
|
505 | 479 | i.indrelid,
|
506 |
| - pg_get_expr(indpred, indrelid) AS "where" |
| 480 | + pg_get_expr(indpred, indrelid) AS "where", |
| 481 | + quote_ident(attname) AS attname |
507 | 482 | FROM pg_index i
|
508 |
| - JOIN pg_class AS tc ON tc.oid = i.indrelid |
509 |
| - JOIN pg_namespace tn ON tn.oid = tc.relnamespace |
| 483 | + JOIN pg_class AS c ON c.oid = i.indrelid |
| 484 | + JOIN pg_namespace n ON n.oid = c.relnamespace |
510 | 485 | JOIN pg_class AS ic ON ic.oid = i.indexrelid
|
511 |
| - WHERE ic.oid IN ( |
512 |
| - SELECT indexrelid |
513 |
| - FROM pg_index i |
514 |
| - JOIN pg_class AS c ON c.oid = i.indrelid |
515 |
| - JOIN pg_namespace n ON n.oid = c.relnamespace |
516 |
| - WHERE %s) |
| 486 | + JOIN LATERAL UNNEST(i.indkey) WITH ORDINALITY AS keys(attnum, ord) |
| 487 | + ON TRUE |
| 488 | + JOIN pg_attribute a |
| 489 | + ON a.attrelid = c.oid |
| 490 | + AND a.attnum = keys.attnum |
| 491 | + WHERE %s |
| 492 | + ORDER BY 1, 2, keys.ord; |
517 | 493 | SQL,
|
518 | 494 | implode(' AND ', $this->buildQueryConditions($tableName, $params)),
|
519 | 495 | );
|
|
0 commit comments