From c7ffea6a760f85c5c782f0d1735e6ce23847b9e3 Mon Sep 17 00:00:00 2001 From: Julius de Bruijn Date: Mon, 2 Aug 2021 17:41:40 +0200 Subject: [PATCH] SQL Server: @unique should be allowed on @id --- .../tests/tables/mod.rs | 28 +++++++++++++++++++ .../src/transform/ast_to_dml/db/attributes.rs | 17 ++--------- .../core/tests/attributes/id_negative.rs | 22 --------------- .../tests/migrations/unique.rs | 14 ++++++++++ 4 files changed, 45 insertions(+), 36 deletions(-) diff --git a/introspection-engine/introspection-engine-tests/tests/tables/mod.rs b/introspection-engine/introspection-engine-tests/tests/tables/mod.rs index a68340ef1c49..640a89cfe050 100644 --- a/introspection-engine/introspection-engine-tests/tests/tables/mod.rs +++ b/introspection-engine/introspection-engine-tests/tests/tables/mod.rs @@ -815,6 +815,34 @@ async fn unique_and_index_on_same_field_works_sqlite(api: &TestApi) -> TestResul Ok(()) } +#[test_connector(tags(Mssql))] +async fn unique_and_id_on_same_field_works_mssql(api: &TestApi) -> TestResult { + let schema = api.schema_name(); + + api.barrel() + .execute(|migration| { + migration.inject_custom(format!( + "create table {}.users ( + id int identity primary key, + constraint unique_and_index_same unique(id) + );", + schema + )) + }) + .await?; + + let dm = indoc! {r##" + model users { + id Int @id @unique @default(autoincrement()) + } + "##}; + + let result = &api.introspect().await?; + api.assert_eq_datamodels(dm, result); + + Ok(()) +} + #[test_connector(tags(Postgres))] // If multiple constraints are created in the create table statement Postgres seems to collapse them // into the first named one. So on the db level there will be one named really_must_be_different that diff --git a/libs/datamodel/core/src/transform/ast_to_dml/db/attributes.rs b/libs/datamodel/core/src/transform/ast_to_dml/db/attributes.rs index 597e41e9df29..f31765f86801 100644 --- a/libs/datamodel/core/src/transform/ast_to_dml/db/attributes.rs +++ b/libs/datamodel/core/src/transform/ast_to_dml/db/attributes.rs @@ -248,19 +248,8 @@ fn visit_scalar_field_attributes<'ast>( }); } - // @unique - attributes.visit_optional_single("unique", ctx, |args, ctx| { - if let Some(source) = &ctx.db.datasource{ - if source.active_provider == "sqlserver" { - if let Some(pk) = &model_data.primary_key{ - if pk.source_field == Some(field_id) { - ctx.push_error(args.new_attribute_validation_error( - "SQLServer only allows either a unique or a primary key constraint on a column.", )) - } - } - } - } - + // @unique + attributes.visit_optional_single("unique", ctx, |args, _ctx| { model_data.indexes.push((args.attribute(), IndexData { is_unique: true, fields: vec![field_id], @@ -268,7 +257,7 @@ fn visit_scalar_field_attributes<'ast>( name: None, db_name: None, })) - }); + }); }); } diff --git a/libs/datamodel/core/tests/attributes/id_negative.rs b/libs/datamodel/core/tests/attributes/id_negative.rs index bb807e0cadfd..eb413843ce03 100644 --- a/libs/datamodel/core/tests/attributes/id_negative.rs +++ b/libs/datamodel/core/tests/attributes/id_negative.rs @@ -158,25 +158,3 @@ fn relation_field_as_id_must_error() { Span::new(84, 86), )); } - -#[test] -fn unique_should_error_if_unique_and_id_are_specified_on_sqlserver() { - let dml = r#" - datasource test { - provider = "sqlserver" - url = "sqlserver://...." - } - - model Model { - id Int @id @unique - } - "#; - - let errors = parse_error(dml); - - errors.assert_is(DatamodelError::new_attribute_validation_error( - "SQLServer only allows either a unique or a primary key constraint on a column.", - "unique", - Span::new(140, 146), - )); -} diff --git a/migration-engine/migration-engine-tests/tests/migrations/unique.rs b/migration-engine/migration-engine-tests/tests/migrations/unique.rs index af035722073e..3c7f1d1ade12 100644 --- a/migration-engine/migration-engine-tests/tests/migrations/unique.rs +++ b/migration-engine/migration-engine-tests/tests/migrations/unique.rs @@ -157,3 +157,17 @@ fn removing_unique_from_an_existing_field_must_work(api: TestApi) { api.schema_push(dm2).send().assert_green_bang(); api.assert_schema().assert_table("A", |t| t.assert_indexes_count(0)); } + +#[test_connector] +fn unique_is_allowed_on_an_id_field(api: TestApi) { + let dm1 = r#" + model A { + id Int @id @unique + } + "#; + + api.schema_push(dm1).send().assert_green_bang(); + api.assert_schema().assert_table("A", |t| { + t.assert_index_on_columns(&["id"], |idx| idx.assert_is_unique()) + }); +}