Skip to content

Commit b03d75f

Browse files
authored
fix: fix unsupported type diff false positives (#5633)
[TML-1493](https://linear.app/prisma-company/issue/TML-1493/fix-unsupported-data-type-issue) The extension type changes accidentally caused unsupported types to produce diffs because they weren't considered equal to `PostgresType::Unknown`, which is what the introspection infers for unknown columns now. `None` (no native type defined in schema) and `Some(PostgresType::Unknown(_))` (unknown type found in introspection) should be compared using the type name. The existing type name check is broken though because it compares `columns.previous` to `columns.previous`. I left that behavior unchanged intentionally, because the diffs it produces are somewhat broken. They generate `ALTER TYPE` statements from `full_data_type`, which isn't always valid, for example when the column type is `vector(3)`, the `full_data_type` is `vector` so the statement ends up being invalid: `SET DATA TYPE vector`. This functionality works fine for types without modifiers though like plain `geometry`. As of this PR though, the diffs should never occur. Fixes: prisma/prisma#28237
1 parent ba26271 commit b03d75f

2 files changed

Lines changed: 74 additions & 5 deletions

File tree

schema-engine/connectors/sql-schema-connector/src/flavour/postgres/schema_differ.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -382,10 +382,10 @@ fn postgres_column_type_change(columns: MigrationPair<TableColumnWalker<'_>>) ->
382382
Some(RiskyCast)
383383
}
384384
}
385-
// Unsupported types will have None as Native type
386-
(None, Some(_)) => Some(RiskyCast),
387-
(Some(_), None) => Some(RiskyCast),
388-
(None, None)
385+
// Unsupported types will have None as Native type when defined in the Prisma schema.
386+
// When introspected, we get an Unknown type with name and args.
387+
(None | Some(PostgresType::Unknown(_, _)), None | Some(PostgresType::Unknown(_, _)))
388+
// TODO: this diffs columns.previous with columns.previous, which is incorrect
389389
if columns.previous.column_type().full_data_type == columns.previous.column_type().full_data_type =>
390390
{
391391
None

schema-engine/sql-migration-tests/tests/migrations/postgres/extensions.rs

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use indoc::indoc;
2-
use psl::SourceFile;
2+
use psl::{SourceFile, parser_database::NoExtensionTypes};
33
use schema_core::{ExtensionType, ExtensionTypeConfig, schema_connector::DiffTarget};
44
use sql_migration_tests::test_api::*;
55

@@ -581,3 +581,72 @@ fn diff_extension_type_unchanged_db_type_modifiers(api: TestApi) {
581581
-- This is an empty migration."#]]
582582
.assert_eq(&diff);
583583
}
584+
585+
#[test_connector(tags(Postgres), exclude(CockroachDb))]
586+
fn diff_unchanged_unsupported_type(api: TestApi) {
587+
let dm = indoc! {r#"
588+
generator client {
589+
provider = "prisma-client"
590+
}
591+
592+
datasource db {
593+
provider = "postgresql"
594+
url = "env(TEST_DATABASE_URL)"
595+
}
596+
597+
model A {
598+
id Int @id @default(autoincrement())
599+
data Unsupported("vector")?
600+
}
601+
"#};
602+
603+
let extensions = NoExtensionTypes;
604+
605+
api.raw_cmd("CREATE EXTENSION IF NOT EXISTS vector");
606+
api.raw_cmd("CREATE TABLE \"A\" (\"id\" SERIAL PRIMARY KEY, \"data\" vector(3))");
607+
608+
let diff = api.connector_diff(
609+
DiffTarget::Database,
610+
DiffTarget::Datamodel(vec![("schema.prisma".into(), SourceFile::new_static(dm))], &extensions),
611+
None,
612+
);
613+
614+
expect![[r#"
615+
-- This is an empty migration."#]]
616+
.assert_eq(&diff);
617+
}
618+
619+
#[test_connector(tags(Postgres), exclude(CockroachDb))]
620+
fn diff_changed_unsupported_type(api: TestApi) {
621+
let dm = indoc! {r#"
622+
generator client {
623+
provider = "prisma-client"
624+
}
625+
626+
datasource db {
627+
provider = "postgresql"
628+
url = "env(TEST_DATABASE_URL)"
629+
}
630+
631+
model A {
632+
id Int @id @default(autoincrement())
633+
data Unsupported("vector")?
634+
}
635+
"#};
636+
637+
let extensions = NoExtensionTypes;
638+
639+
api.raw_cmd("CREATE EXTENSION IF NOT EXISTS vector");
640+
api.raw_cmd("CREATE EXTENSION IF NOT EXISTS postgis");
641+
api.raw_cmd("CREATE TABLE \"A\" (\"id\" SERIAL PRIMARY KEY, \"data\" geometry)");
642+
643+
let diff = api.connector_diff(
644+
DiffTarget::Database,
645+
DiffTarget::Datamodel(vec![("schema.prisma".into(), SourceFile::new_static(dm))], &extensions),
646+
None,
647+
);
648+
649+
// TODO: this should produce 'ALTER TABLE "A" ALTER COLUMN "data" SET DATA TYPE geometry;',
650+
// but unsupported column diffing is currently broken.
651+
expect!["-- This is an empty migration."].assert_eq(&diff);
652+
}

0 commit comments

Comments
 (0)