Skip to content

Commit

Permalink
fix(schema-engine): fix migrate diff on MySQL for foreign key index r…
Browse files Browse the repository at this point in the history
…emovals (#5020)
  • Loading branch information
jkomyno authored Nov 1, 2024
1 parent dc59d1c commit feda6ce
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
use sql_schema_describer::walkers::{IndexWalker, TableWalker};

pub(super) fn index_covers_fk(table: TableWalker<'_>, index: IndexWalker<'_>) -> bool {
// Only normal indexes can cover foreign keys.
if index.index_type() != sql_schema_describer::IndexType::Normal {
return false;
}

table.foreign_keys().any(|fk| {
let fk_cols = fk.constrained_columns().map(|col| col.name());
let index_cols = index.column_names();
Expand Down
89 changes: 89 additions & 0 deletions schema-engine/sql-migration-tests/tests/migrations/diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,95 @@ use schema_core::{
use sql_migration_tests::{test_api::*, utils::to_schema_containers};
use std::sync::Arc;

#[test_connector(tags(Sqlite, Mysql, Postgres, CockroachDb, Mssql))]
fn from_unique_index_to_without(mut api: TestApi) {
let tempdir = tempfile::tempdir().unwrap();
let host = Arc::new(TestConnectorHost::default());

api.connector.set_host(host.clone());

let from_schema = api.datamodel_with_provider(
r#"
model Post {
id Int @id
title String
author User? @relation(fields: [authorId], references: [id])
authorId Int? @unique
// ^^^^^^^ this will be removed later
}
model User {
id Int @id
name String?
posts Post[]
}
"#,
);

let to_schema = api.datamodel_with_provider(
r#"
model Post {
id Int @id
title String
author User? @relation(fields: [authorId], references: [id])
authorId Int?
}
model User {
id Int @id
name String?
posts Post[]
}
"#,
);

let from_file = write_file_to_tmp(&from_schema, &tempdir, "from");
let to_file = write_file_to_tmp(&to_schema, &tempdir, "to");

api.diff(DiffParams {
exit_code: None,
from: DiffTarget::SchemaDatamodel(SchemasContainer {
files: vec![SchemaContainer {
path: from_file.to_string_lossy().into_owned(),
content: from_schema.to_string(),
}],
}),
shadow_database_url: None,
to: DiffTarget::SchemaDatamodel(SchemasContainer {
files: vec![SchemaContainer {
path: to_file.to_string_lossy().into_owned(),
content: to_schema.to_string(),
}],
}),
script: true,
})
.unwrap();

let expected_printed_messages = if api.is_mysql() {
expect![[r#"
[
"-- DropIndex\nDROP INDEX `Post_authorId_key` ON `Post`;\n",
]
"#]]
} else if api.is_sqlite() || api.is_postgres() || api.is_cockroach() {
expect![[r#"
[
"-- DropIndex\nDROP INDEX \"Post_authorId_key\";\n",
]
"#]]
} else if api.is_mssql() {
expect![[r#"
[
"BEGIN TRY\n\nBEGIN TRAN;\n\n-- DropIndex\nDROP INDEX [Post_authorId_key] ON [dbo].[Post];\n\nCOMMIT TRAN;\n\nEND TRY\nBEGIN CATCH\n\nIF @@TRANCOUNT > 0\nBEGIN\n ROLLBACK TRAN;\nEND;\nTHROW\n\nEND CATCH\n",
]
"#]]
} else {
unreachable!()
};

expected_printed_messages.assert_debug_eq(&host.printed_messages.lock().unwrap());
}

#[test_connector(tags(Sqlite))]
fn diffing_postgres_schemas_when_initialized_on_sqlite(mut api: TestApi) {
// We should get a postgres diff.
Expand Down

0 comments on commit feda6ce

Please sign in to comment.