Skip to content

Commit 280c870

Browse files
authored
fix: fix partial index added diff (#5795)
[TML-2063](https://linear.app/prisma-company/issue/TML-2063/fix-another-partial-index-diffing-issue) Fixes prisma/prisma#29263 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Fixed migration diff detection for partial indexes so manual partial indexes are ignored when the preview feature is not enabled, preventing false positives when comparing schemas and migrations. * **Tests** * Added tests to validate that manual partial indexes without the preview feature do not produce migration differences. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent d684c19 commit 280c870

2 files changed

Lines changed: 86 additions & 20 deletions

File tree

  • schema-engine
    • connectors/sql-schema-connector/src/sql_schema_differ
    • sql-migration-tests/tests/migrations

schema-engine/connectors/sql-schema-connector/src/sql_schema_differ/table.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ impl<'schema> TableDiffer<'schema, '_> {
5757
!self
5858
.previous_indexes()
5959
.any(move |previous_index| indexes_match(previous_index, *next_index, self.db.flavour))
60+
&& !next_index.is_stripped_partial()
6061
})
6162
}
6263

schema-engine/sql-migration-tests/tests/migrations/diff.rs

Lines changed: 85 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -909,13 +909,13 @@ fn from_migrations_to_schema_datamodel_ignores_manual_partial_indexes_without_pr
909909
std::fs::write(
910910
migration_file,
911911
format!(
912-
"CREATE SCHEMA IF NOT EXISTS \"{schema_name}\";\n\
913-
CREATE TABLE \"{schema_name}\".\"User\" (\n\
914-
\"id\" INTEGER NOT NULL,\n\
915-
\"email\" TEXT NOT NULL,\n\
916-
CONSTRAINT \"User_pkey\" PRIMARY KEY (\"id\")\n\
917-
);\n\
918-
CREATE INDEX \"User_email_partial_idx\" ON \"{schema_name}\".\"User\" (\"email\") WHERE \"email\" IS NOT NULL;\n"
912+
r#"CREATE SCHEMA IF NOT EXISTS "{schema_name}";
913+
CREATE TABLE "{schema_name}"."User" (
914+
"id" INTEGER NOT NULL,
915+
"email" TEXT NOT NULL,
916+
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
917+
);
918+
CREATE INDEX "User_email_partial_idx" ON "{schema_name}"."User" ("email") WHERE "email" IS NOT NULL;"#
919919
),
920920
)
921921
.unwrap();
@@ -958,6 +958,71 @@ fn from_migrations_to_schema_datamodel_ignores_manual_partial_indexes_without_pr
958958
expected_diff.assert_eq(&diff);
959959
}
960960

961+
#[test_connector(tags(Postgres), exclude(CockroachDb))]
962+
fn from_schema_datamodel_to_migrations_ignores_manual_partial_indexes_without_preview_feature(api: TestApi) {
963+
let migrations_dir = tempfile::tempdir().unwrap();
964+
let migration_dir = migrations_dir.path().join("01init");
965+
let migration_file = migration_dir.join("migration.sql");
966+
let schema_name = api.schema_name();
967+
968+
std::fs::write(
969+
migrations_dir.path().join("migration_lock.toml"),
970+
format!("provider = \"{}\"", api.args().provider()),
971+
)
972+
.unwrap();
973+
std::fs::create_dir_all(&migration_dir).unwrap();
974+
std::fs::write(
975+
migration_file,
976+
format!(
977+
r#"CREATE SCHEMA IF NOT EXISTS "{schema_name}";
978+
CREATE TABLE "{schema_name}"."User" (
979+
"id" INTEGER NOT NULL,
980+
"email" TEXT NOT NULL,
981+
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
982+
);
983+
CREATE INDEX "User_email_partial_idx" ON "{schema_name}"."User" ("email") WHERE "email" IS NOT NULL;"#
984+
),
985+
)
986+
.unwrap();
987+
988+
let datamodel = api.datamodel_with_provider(
989+
r#"
990+
model User {
991+
id Int @id
992+
email String
993+
}
994+
"#,
995+
);
996+
let datamodel_dir = tempfile::tempdir().unwrap();
997+
let datamodel_path = write_file_to_tmp(&datamodel, &datamodel_dir, "schema.prisma");
998+
999+
let (result, diff) = diff_result(
1000+
DatasourceUrls {
1001+
url: Some(api.connection_string().to_owned()),
1002+
shadow_database_url: Some(api.connection_string().to_owned()),
1003+
},
1004+
DiffParams {
1005+
exit_code: Some(true),
1006+
from: DiffTarget::SchemaDatamodel(SchemasContainer {
1007+
files: vec![SchemaContainer {
1008+
path: datamodel_path.to_string_lossy().into_owned(),
1009+
content: datamodel,
1010+
}],
1011+
}),
1012+
to: DiffTarget::Migrations(list_migrations(migrations_dir.path()).unwrap()),
1013+
script: false,
1014+
shadow_database_url: Some(api.connection_string().to_owned()),
1015+
filters: SchemaFilter::default(),
1016+
},
1017+
);
1018+
1019+
let expected_diff = expect![[r#"
1020+
No difference detected.
1021+
"#]];
1022+
expected_diff.assert_eq(&diff);
1023+
assert_eq!(result.exit_code, 0);
1024+
}
1025+
9611026
#[test_connector(tags(Postgres), exclude(CockroachDb))]
9621027
fn from_migrations_to_url_ignores_manual_partial_indexes_with_engine_seeded_schema(api: TestApi) {
9631028
let migrations_dir = tempfile::tempdir().unwrap();
@@ -974,13 +1039,13 @@ fn from_migrations_to_url_ignores_manual_partial_indexes_with_engine_seeded_sche
9741039
std::fs::write(
9751040
migration_file,
9761041
format!(
977-
"CREATE SCHEMA IF NOT EXISTS \"{schema_name}\";\n\
978-
CREATE TABLE \"{schema_name}\".\"User\" (\n\
979-
\"id\" INTEGER NOT NULL,\n\
980-
\"email\" TEXT NOT NULL,\n\
981-
CONSTRAINT \"User_pkey\" PRIMARY KEY (\"id\")\n\
982-
);\n\
983-
CREATE INDEX \"User_email_partial_idx\" ON \"{schema_name}\".\"User\" (\"email\") WHERE \"email\" IS NOT NULL;\n"
1042+
r#"CREATE SCHEMA IF NOT EXISTS "{schema_name}";
1043+
CREATE TABLE "{schema_name}"."User" (
1044+
"id" INTEGER NOT NULL,
1045+
"email" TEXT NOT NULL,
1046+
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
1047+
);
1048+
CREATE INDEX "User_email_partial_idx" ON "{schema_name}"."User" ("email") WHERE "email" IS NOT NULL;"#
9841049
),
9851050
)
9861051
.unwrap();
@@ -998,12 +1063,12 @@ fn from_migrations_to_url_ignores_manual_partial_indexes_with_engine_seeded_sche
9981063

9991064
// Apply the migration to create the table + partial index
10001065
api.raw_cmd(&format!(
1001-
"CREATE TABLE \"{schema_name}\".\"User\" (\n\
1002-
\"id\" INTEGER NOT NULL,\n\
1003-
\"email\" TEXT NOT NULL,\n\
1004-
CONSTRAINT \"User_pkey\" PRIMARY KEY (\"id\")\n\
1005-
);\n\
1006-
CREATE INDEX \"User_email_partial_idx\" ON \"{schema_name}\".\"User\" (\"email\") WHERE \"email\" IS NOT NULL;\n"
1066+
r#"CREATE TABLE "{schema_name}"."User" (
1067+
"id" INTEGER NOT NULL,
1068+
"email" TEXT NOT NULL,
1069+
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
1070+
);
1071+
CREATE INDEX "User_email_partial_idx" ON "{schema_name}"."User" ("email") WHERE "email" IS NOT NULL;"#,
10071072
));
10081073

10091074
let (result, diff) = diff_result_with_initial_datamodel(

0 commit comments

Comments
 (0)