From 6e0111edbcbf12d1b704be70b13a1746d8021a42 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/+/84576
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Andreas Kienast <a.fernandez@scripting-base.de>
Tested-by: core-ci <typo3@b13.com>
Reviewed-by: Stefan Bürk <stefan@buerk.tech>
Reviewed-by: Andreas Kienast <a.fernandez@scripting-base.de>
Tested-by: Stefan Bürk <stefan@buerk.tech>
---
 .../Database/Schema/ConnectionMigrator.php     | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/typo3/sysext/core/Classes/Database/Schema/ConnectionMigrator.php b/typo3/sysext/core/Classes/Database/Schema/ConnectionMigrator.php
index 2591b2659b9e..774f46ba3b51 100644
--- a/typo3/sysext/core/Classes/Database/Schema/ConnectionMigrator.php
+++ b/typo3/sysext/core/Classes/Database/Schema/ConnectionMigrator.php
@@ -657,7 +657,9 @@ 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 Typo3SchemaDiff(
                         // createdSchemas
@@ -667,7 +669,7 @@ class ConnectionMigrator
                         // createdTables
                         [],
                         // alteredTables
-                        [$indexDiff->getOldTable()->getName() => $indexDiff],
+                        [$indexDiff->getOldTable()->getQuotedName($databasePlatform) => $indexDiff],
                         // droppedTables
                         [],
                         // createdSequences
@@ -862,6 +864,7 @@ class ConnectionMigrator
      */
     protected function getUnusedTableUpdateSuggestions(Typo3SchemaDiff $schemaDiff): array
     {
+        $databasePlatform = $this->connection->getDatabasePlatform();
         $updateSuggestions = [];
         foreach ($schemaDiff->alteredTables as $tableName => $tableDiff) {
             // Skip tables that are not being renamed or where the new name isn't prefixed
@@ -872,8 +875,8 @@ class ConnectionMigrator
                 continue;
             }
 
-            $statement = $this->connection->getDatabasePlatform()->getRenameTableSQL(
-                $tableDiff->getOldTable()->getName(),
+            $statement = $databasePlatform->getRenameTableSQL(
+                $tableDiff->getOldTable()->getQuotedName($databasePlatform),
                 $tableDiff->newName
             );
             $updateSuggestions['change_table'][md5($statement)] = $statement;
@@ -894,23 +897,22 @@ class ConnectionMigrator
      */
     protected function getUnusedFieldUpdateSuggestions(Typo3SchemaDiff $schemaDiff): array
     {
+        $databasePlatform = $this->connection->getDatabasePlatform();
         $changedTables = [];
-
         foreach ($schemaDiff->alteredTables as $tableName => $changedTable) {
             if (count($changedTable->modifiedColumns) === 0) {
                 continue;
             }
 
-            $databasePlatform = $this->getDatabasePlatformForTable($tableName);
-
             // Treat each changed column with a new diff to get a dedicated suggestions
             // just for this single column.
-            foreach ($changedTable->modifiedColumns as $oldFieldName => $changedColumn) {
+            foreach ($changedTable->modifiedColumns as $index => $changedColumn) {
                 // Field has not been renamed
                 if ($changedColumn->getOldColumn()->getName() === $changedColumn->getNewColumn()->getName()) {
                     continue;
                 }
 
+                $oldFieldName = $changedColumn->getOldColumn()->getQuotedName($databasePlatform);
                 $renameColumnTableDiff = new Typo3TableDiff(
                     // oldTable
                     $this->buildQuotedTable($changedTable->getOldTable()),
-- 
GitLab