#7481·dbal

A foreign key's implicit index breaks dropping its column after introspection

Author: morozovCreated Jul 26, 2026Updated Aug 26, 2026
LabelsSchema DefinitionForeign KeysIndexes
Q A
Version 4.4.x

Table fabricates an implicit index to back a foreign key and records its name in $implicitIndexNames. On a constructed table the index is implicit, so dropping the foreign key drops it too. A round-trip through the database breaks that in two steps:

  1. Create-and-introspect loses the index's implicitness. The database has no notion of an implicit index, so introspection brings it back as an explicit one.
  2. Dropping the foreign key does not automatically drop the no longer implicit index. Dropping its column then leaves an index over a column that doesn't exist, so the table is invalid.

Given child(id PK, parent_id) with a foreign key child_parent on parent_id referencing parent(id), where the invalid table is caught depends on how it's edited:

  • The mutable Table API has no build-time check, so the invalid table reaches the database on drop-and-create:

    php
    $child = $schemaManager->introspectTableByUnquotedName('child');
    $child->removeForeignKey('child_parent');
    $child->dropColumn('parent_id');
    $schemaManager->dropTable('child');
    $schemaManager->createTable($child);
    // DriverException: SQLSTATE[HY000]: General error: 1 no such column: parent_id
  • The editor rejects it earlier, when create() builds the object:

    php
    $child = $schemaManager->introspectTableByUnquotedName('child');
    $child->edit()
        ->dropColumnByUnquotedName('parent_id')
        ->dropForeignKeyConstraintByUnquotedName('child_parent')
        ->create();
    // ColumnDoesNotExist: There is no column with name "parent_id" on table child.