Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(database): drop fk before dropping index #20113

Merged
merged 10 commits into from May 2, 2024
34 changes: 24 additions & 10 deletions packages/core/database/src/schema/builder.ts
Expand Up @@ -248,16 +248,7 @@ const createHelpers = (db: Database) => {
await schemaBuilder.alterTable(table.name, (tableBuilder) => {
// Delete indexes / fks / columns

for (const removedIndex of table.indexes.removed) {
debug(`Dropping index ${removedIndex.name} on ${table.name}`);
dropIndex(tableBuilder, removedIndex);
}

for (const updateddIndex of table.indexes.updated) {
debug(`Dropping updated index ${updateddIndex.name} on ${table.name}`);
dropIndex(tableBuilder, updateddIndex.object);
}

// Drop foreign keys first to avoid foreign key errors in the following steps
for (const removedForeignKey of table.foreignKeys.removed) {
debug(`Dropping foreign key ${removedForeignKey.name} on ${table.name}`);
dropForeignKey(tableBuilder, removedForeignKey);
Expand All @@ -273,6 +264,29 @@ const createHelpers = (db: Database) => {
dropColumn(tableBuilder, removedColumn);
}

// for mysql only, dropForeignKey also removes the index, so don't drop it twice
const isMySQL = db.config.connection.client === 'mysql';
const ignoreForeignKeyNames = isMySQL
? [
...table.foreignKeys.removed.map((fk) => fk.name),
alexandrebodin marked this conversation as resolved.
Show resolved Hide resolved
...table.foreignKeys.updated.map((fk) => fk.name),
]
: [];

for (const removedIndex of table.indexes.removed) {
if (!ignoreForeignKeyNames.includes(removedIndex.name)) {
debug(`Dropping index ${removedIndex.name} on ${table.name}`);
dropIndex(tableBuilder, removedIndex);
}
}

for (const updatedIndex of table.indexes.updated) {
if (!ignoreForeignKeyNames.includes(updatedIndex.name)) {
debug(`Dropping updated index ${updatedIndex.name} on ${table.name}`);
dropIndex(tableBuilder, updatedIndex.object);
}
}

// Update existing columns / foreign keys / indexes
for (const updatedColumn of table.columns.updated) {
debug(`Updating column ${updatedColumn.name} on ${table.name}`);
Expand Down