| Q |
A |
| Version |
3.10.4, 4.4.3 |
Summary
The comparator detects renamed columns and renamed indexes, but not renamed foreign keys.
A foreign key that differs from the database only by its name produces no diff, so
schema:update reports the schema as in sync and the old constraint name is never reconciled.
Cause: in Comparator the FK matching loop discards any structurally-equal pair regardless of
name (if (diffForeignKey(...) === false) unset(...)), and diffForeignKey() never compares the
name. There is no detectRenamedForeignKeys() / TableDiff::$renamedForeignKeys (unlike indexes).
Reproduce
use Doctrine\DBAL\Schema\Comparator;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Platforms\MySQLPlatform;
function makeTable(string $fkName): Table {
$t = new Table('widget');
$t->addColumn('id', 'integer');
$t->addColumn('reviewed_by', 'integer', ['notnull' => false]);
$t->setPrimaryKey(['id']);
$t->addForeignKeyConstraint('account', ['reviewed_by'], ['id'], [], $fkName); // only the NAME differs
return $t;
}
$platform = new MySQLPlatform();
$diff = (new Comparator($platform))->compareTables(
makeTable('widget__account_legacy'), // in the database
makeTable('FK_85F91ED085D7FB47'), // generated by the mapping
);
var_dump($diff->isEmpty()); // true — no diff produced
Expected vs actual
- Expected: a name-only change is emitted as
DROP FOREIGN KEY <old> + ADD CONSTRAINT <new>
(no platform supports atomic FK rename), as indexes are handled today.
- Actual:
isEmpty() === true, no SQL. Changing onDelete instead does surface the FK,
confirming the gap is name-specific.
Related: #6390, #6445, #7356
Summary
The comparator detects renamed columns and renamed indexes, but not renamed foreign keys.
A foreign key that differs from the database only by its name produces no diff, so
schema:updatereports the schema as in sync and the old constraint name is never reconciled.Cause: in
Comparatorthe FK matching loop discards any structurally-equal pair regardless ofname (
if (diffForeignKey(...) === false) unset(...)), anddiffForeignKey()never compares thename. There is no
detectRenamedForeignKeys()/TableDiff::$renamedForeignKeys(unlike indexes).Reproduce
Expected vs actual
DROP FOREIGN KEY <old>+ADD CONSTRAINT <new>(no platform supports atomic FK rename), as indexes are handled today.
isEmpty() === true, no SQL. ChangingonDeleteinstead does surface the FK,confirming the gap is name-specific.
Related: #6390, #6445, #7356