From 19ce66960747f1fa9985676ecf9e25d0262bd97c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20B=C3=BCrk?= <stefan@buerk.tech> Date: Mon, 10 Jun 2024 23:21:56 +0200 Subject: [PATCH] [BUGFIX] Use correct column and index name caseing for PostgresSQL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Doctrine DBAL uses lowercased array index names for table or index names, which has been used to make RENAME DDL statements. Due to the lack of having the old information correctly in place, this leads to invalid RENAME DDL statements for tables or indexes having upper case characters in the name. That is a edgecase for PostgreSQL and SQLite due to custom index name handling based on that array key. This change modifies the ConnectionMigrator to use correct casing for column and index naming in case table or column needs to be renamed. That allows, that following correct DDL statements are now created: ALTER INDEX "freeIndexUid_65098221" RENAME TO "customFreeIndexUid_6dedc8fa" ALTER TABLE "index_phash" RENAME COLUMN "freeIndexSetId" TO "zzz_deleted_freeIndexSetId" in case the `EXT:indexed_search/ext_tables.sql` is changed for table `index_phash` to drop the `freeIndexSetId` column by commenting it out or remove it and renaming `freeIndexUid` index to `customFreeIndexUid`. [1] [1] https://review.typo3.org/c/Packages/TYPO3.CMS/+/84576/3/typo3/sysext/indexed_search/ext_tables.sql Resolves: #93223 Releases: main, 12.4 Change-Id: I195ad021b8826be59a3ae78a926a396528ca0c66 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/84698 Reviewed-by: Stefan Bürk <stefan@buerk.tech> Tested-by: core-ci <typo3@b13.com> Tested-by: Stefan Bürk <stefan@buerk.tech> --- .../Database/Schema/ConnectionMigrator.php | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/typo3/sysext/core/Classes/Database/Schema/ConnectionMigrator.php b/typo3/sysext/core/Classes/Database/Schema/ConnectionMigrator.php index eb05f5069fb8..fed41979df77 100644 --- a/typo3/sysext/core/Classes/Database/Schema/ConnectionMigrator.php +++ b/typo3/sysext/core/Classes/Database/Schema/ConnectionMigrator.php @@ -522,11 +522,13 @@ class ConnectionMigrator // just for this index. foreach ($changedTable->renamedIndexes as $key => $renamedIndex) { $indexDiff = clone $tableDiff; - $indexDiff->renamedIndexes = [$key => $renamedIndex]; + $indexDiff->renamedIndexes = [ + $changedTable->getOldTable()->getIndex($key)->getQuotedName($databasePlatform) => $renamedIndex, + ]; $temporarySchemaDiff = new SchemaDiff( [], - [$indexDiff], + [$indexDiff->getOldTable()->getQuotedName($databasePlatform) => $indexDiff], [], $schemaDiff->fromSchema ); @@ -634,6 +636,7 @@ class ConnectionMigrator */ protected function getUnusedTableUpdateSuggestions(SchemaDiff $schemaDiff): array { + $databasePlatform = $this->connection->getDatabasePlatform(); $updateSuggestions = []; foreach ($schemaDiff->changedTables as $tableDiff) { // Skip tables that are not being renamed or where the new name isn't prefixed @@ -643,15 +646,10 @@ class ConnectionMigrator ) { continue; } - // Build a new schema diff that only contains this table - $changedFieldDiff = new SchemaDiff( - [], - [$tableDiff], - [], - $schemaDiff->fromSchema + $statements = $databasePlatform->getRenameTableSQL( + $tableDiff->getOldTable()->getQuotedName($databasePlatform), + $tableDiff->newName ); - - $statements = $changedFieldDiff->toSql($this->connection->getDatabasePlatform()); foreach ($statements as $statement) { $updateSuggestions['change_table'][md5($statement)] = $statement; } @@ -674,21 +672,21 @@ class ConnectionMigrator { $changedTables = []; + $databasePlatform = $this->connection->getDatabasePlatform(); foreach ($schemaDiff->changedTables as $index => $changedTable) { if (count($changedTable->changedColumns) === 0) { continue; } - $databasePlatform = $this->getDatabasePlatform($index); - // Treat each changed column with a new diff to get a dedicated suggestions // just for this single column. - foreach ($changedTable->changedColumns as $oldFieldName => $changedColumn) { + foreach ($changedTable->changedColumns as $index => $changedColumn) { // Field has not been renamed if ($changedColumn->getOldColumnName()->getName() === $changedColumn->column->getName()) { continue; } + $oldFieldName = $changedColumn->getOldColumn()->getQuotedName($databasePlatform); $renameColumnTableDiff = new TableDiff( $changedTable->name, [], @@ -699,12 +697,12 @@ class ConnectionMigrator [], $this->buildQuotedTable($schemaDiff->fromSchema->getTable($changedTable->name)) ); - if ($databasePlatform === 'postgresql') { + if ($databasePlatform instanceof \Doctrine\DBAL\Platforms\PostgreSQLPlatform) { $renameColumnTableDiff->renamedColumns[$oldFieldName] = $changedColumn->column; } $changedTables[$index . ':' . $changedColumn->column->getName()] = $renameColumnTableDiff; - if ($databasePlatform === 'sqlite') { + if ($databasePlatform instanceof SqlitePlatform) { break; } } -- GitLab