From: Matthias Schmidt Date: Tue, 13 Apr 2021 14:21:54 +0000 (+0200) Subject: Properly handle foreign keys referencing tables created later on X-Git-Tag: 5.3.6~6^2 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=dc4b5734056ea938b79ef3a6d396749a04f2484e;p=GitHub%2FWoltLab%2FWCF.git Properly handle foreign keys referencing tables created later on If a foreign key of the first table references a table to be created later on, this foreign key can only be created once the referenced table was created. --- diff --git a/wcfsetup/install/files/lib/system/database/table/DatabaseTableChangeProcessor.class.php b/wcfsetup/install/files/lib/system/database/table/DatabaseTableChangeProcessor.class.php index 202065ff00..318d517c89 100644 --- a/wcfsetup/install/files/lib/system/database/table/DatabaseTableChangeProcessor.class.php +++ b/wcfsetup/install/files/lib/system/database/table/DatabaseTableChangeProcessor.class.php @@ -448,6 +448,12 @@ class DatabaseTableChangeProcessor { } } else if ($matchingExistingForeignKey === null) { + // If the referenced database table does not already exists, delay the + // foreign key creation until after the referenced table has been created. + if (!in_array($foreignKey->getReferencedTable(), $this->existingTableNames)) { + continue; + } + if (!isset($this->foreignKeysToAdd[$tableName])) { $this->foreignKeysToAdd[$tableName] = []; } @@ -648,10 +654,18 @@ class DatabaseTableChangeProcessor { $this->dbEditor->createTable($table->getName(), $columnData, $indexData); foreach ($table->getForeignKeys() as $foreignKey) { - $this->dbEditor->addForeignKey($table->getName(), $foreignKey->getName(), $foreignKey->getData()); - - // foreign keys need to be explicitly logged for proper uninstallation - $this->createForeignKeyLog($table->getName(), $foreignKey); + // Only try to create the foreign key if the referenced database table already exists. + // If it will be created later on, delay the foreign key creation until after the + // referenced table has been created. + if ( + in_array($foreignKey->getReferencedTable(), $this->existingTableNames) + || $foreignKey->getReferencedTable() === $table->getName() + ) { + $this->dbEditor->addForeignKey($table->getName(), $foreignKey->getName(), $foreignKey->getData()); + + // foreign keys need to be explicitly logged for proper uninstallation + $this->createForeignKeyLog($table->getName(), $foreignKey); + } } }