Make renaming columns with PHP DB API idempotent (#4367)
authorMatthias Schmidt <gravatronics@live.com>
Mon, 5 Jul 2021 09:15:20 +0000 (11:15 +0200)
committerGitHub <noreply@github.com>
Mon, 5 Jul 2021 09:15:20 +0000 (11:15 +0200)
An error message should only be shown if the neither a column with the old name, nor with the name name exists so that after the rename, a second rename is a no-op.

Close #4362
See #3765

wcfsetup/install/files/lib/system/database/table/DatabaseTableChangeProcessor.class.php

index 01f535b16495b7c565fcad67a075bed9a7317ddc..6ee6fa60850c528d7a9e313ec8fcdcd4a958e334 100644 (file)
@@ -417,10 +417,14 @@ class DatabaseTableChangeProcessor
                             $this->deleteColumnLog($tableName, $column);
                         }
                     } elseif (!isset($existingColumns[$column->getName()])) {
-                        if (!isset($this->columnsToAdd[$tableName])) {
-                            $this->columnsToAdd[$tableName] = [];
+                        // It was already checked in `validate()` that for renames, the column either
+                        // exists with the old or new name.
+                        if (!$column->getNewName()) {
+                            if (!isset($this->columnsToAdd[$tableName])) {
+                                $this->columnsToAdd[$tableName] = [];
+                            }
+                            $this->columnsToAdd[$tableName][] = $column;
                         }
-                        $this->columnsToAdd[$tableName][] = $column;
                     } elseif ($this->diffColumns($existingColumns[$column->getName()], $column)) {
                         if (!isset($this->columnsToAlter[$tableName])) {
                             $this->columnsToAlter[$tableName] = [];
@@ -1182,7 +1186,9 @@ class DatabaseTableChangeProcessor
                                         'type' => 'foreignColumnChange',
                                     ];
                                 }
-                            } elseif ($column->getNewName()) {
+                            } elseif ($column->getNewName() && !isset($existingColumns[$column->getNewName()])) {
+                                // Only show error message for a column rename if no column with the
+                                // old or new name exists.
                                 $errors[] = [
                                     'columnName' => $column->getName(),
                                     'tableName' => $table->getName(),