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

SQL Server: @unique should be allowed on @id #2117

Merged
merged 1 commit into from Aug 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -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
Expand Down
17 changes: 3 additions & 14 deletions libs/datamodel/core/src/transform/ast_to_dml/db/attributes.rs
Expand Up @@ -248,27 +248,16 @@ 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],
source_field: Some(field_id),
name: None,
db_name: None,
}))
});
});
});
}

Expand Down
22 changes: 0 additions & 22 deletions libs/datamodel/core/tests/attributes/id_negative.rs
Expand Up @@ -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),
));
}
14 changes: 14 additions & 0 deletions migration-engine/migration-engine-tests/tests/migrations/unique.rs
Expand Up @@ -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())
});
}