dbal
dbal copied to clipboard
Comparator::toSql() creates duplicate DROP commands for foreign keys (MySql)
Bug Report
Q | A |
---|---|
BC Break | no |
Version | all |
Summary
Cannot migrate tables with renamed foreign keys when renaming index at the same time with MySqlPlatform.
How to reproduce
Schema 1 contains e.g. one table
- fk_foo (foreign_id)
- index_foo (foreign_id)
Schema 2 for same table
- fk_bar (foreign_id)
- index_bar (foreign_id)
The Comparator:.compare works fine, it detects:
- drop fk_foo
- add fk_bar
- rename index index_foo to index_bar
But toSql() produces:
- sql drop fk_foo
- sql drop fk_foo (it crashes here because index does not exist)
- sql add fk_bar (with namespace)
- sql drop index_foo
- sql add index_bar
- sql add fk_foo (recreates the dropped(!) fk here, but without namespace)
MysqlPlatform::getPreAlterTableIndexForeignKeySQL() generates the DROP query twice.
I guess $this->getRemainingForeignKeyConstraintsRequiringRenamedIndexes($diff) in getPreAlterTableRenameIndexForeignKeySQL is not working as expected.
Expected behaviour
Drop Command should not be duplicated.
EDIT: I reported the index is dropped twice, but it is the foreign key itself caused by the index.
Hi again,
unfortunately this bug still exists, but we made a workaround by replacing rename with add+drop instructions:
/** @var SchemaDiff $schemaDiff */
// ....
if ($platform instanceof MySQLPlatform) {
foreach ($schemaDiff->changedTables as $tableDiff) {
if ($tableDiff->renamedIndexes) {
foreach ($tableDiff->renamedIndexes as $oldName => $index) {
$tableDiff->addedIndexes[$index->getName()] = $index;
$removedIndex = new Index($oldName, $index->getColumns(), $index->isUnique(), $index->isPrimary(), $index->getFlags(), $index->getOptions());
$tableDiff->removedIndexes[$oldName] = $removedIndex;
}
$tableDiff->renamedIndexes = [];
}
}
}
But now we updated to 3.7.2, and are dealing with lots of deprecation here. Problem there are only getters, but no setters to fix it.
It looks like not many people run into that issue, I'm afraid. I'm happy to review any PR that fixes the issue for you. If you don't fix the bug, chances are that nobody else will. 😕