From abe4eaba10a57c3e56c3225974a2634fc19d946c Mon Sep 17 00:00:00 2001 From: Julius de Bruijn Date: Wed, 18 Aug 2021 07:52:05 +0200 Subject: [PATCH] SQL Server: do not allow Bytes in @id (#2159) --- .../src/mssql_datamodel_connector.rs | 24 ++++++++++---- .../core/tests/attributes/id_negative.rs | 33 +++++++++++++++++++ 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/libs/datamodel/connectors/sql-datamodel-connector/src/mssql_datamodel_connector.rs b/libs/datamodel/connectors/sql-datamodel-connector/src/mssql_datamodel_connector.rs index 5b3067dd59ee..0d68f3f1a6ae 100644 --- a/libs/datamodel/connectors/sql-datamodel-connector/src/mssql_datamodel_connector.rs +++ b/libs/datamodel/connectors/sql-datamodel-connector/src/mssql_datamodel_connector.rs @@ -1,4 +1,4 @@ -use datamodel_connector::connector_error::ConnectorError; +use datamodel_connector::connector_error::{ConnectorError, ErrorKind}; use datamodel_connector::helper::{arg_vec_from_opt, args_vec_from_opt, parse_one_opt_u32, parse_two_opt_u32}; use datamodel_connector::{Connector, ConnectorCapability}; use dml::{ @@ -298,13 +298,23 @@ impl Connector for MsSqlDatamodelConnector { for id_field in pk.fields.iter() { let field = model.find_field(id_field).unwrap(); - if let FieldType::Scalar(_, _, Some(native_type)) = field.field_type() { - let r#type: MsSqlType = native_type.deserialize_native_type(); + if let FieldType::Scalar(scalar_type, _, native_type) = field.field_type() { + if let Some(native_type) = native_type { + let r#type: MsSqlType = native_type.deserialize_native_type(); - if heap_allocated_types().contains(&r#type) { - return self - .native_instance_error(native_type) - .new_incompatible_native_type_with_id(); + if heap_allocated_types().contains(&r#type) { + return self + .native_instance_error(native_type) + .new_incompatible_native_type_with_id(); + } + } + + if matches!(scalar_type, ScalarType::Bytes) { + let kind = ErrorKind::InvalidModelError { + message: String::from("Using Bytes type is not allowed in the model's id."), + }; + + return Err(ConnectorError { kind }); } } } diff --git a/libs/datamodel/core/tests/attributes/id_negative.rs b/libs/datamodel/core/tests/attributes/id_negative.rs index a41fadb66451..1bea82405e9a 100644 --- a/libs/datamodel/core/tests/attributes/id_negative.rs +++ b/libs/datamodel/core/tests/attributes/id_negative.rs @@ -1,6 +1,7 @@ use crate::attributes::with_named_constraints; use crate::common::*; use datamodel::{ast::Span, diagnostics::DatamodelError}; +use indoc::indoc; #[test] fn id_should_error_if_the_field_is_not_required() { @@ -329,3 +330,35 @@ fn name_on_field_level_id_should_error() { let errors = parse_error(&dml); errors.assert_is(DatamodelError::new_unused_argument_error("name", Span::new(277, 311))); } + +#[test] +fn bytes_should_not_be_allowed_as_id_on_sql_server() { + let dml = indoc! {r#" + datasource db { + provider = "sqlserver" + url = "sqlserver://" + } + + generator client { + provider = "prisma-client-js" + } + + model A { + id Bytes @id + } + "#}; + + let error = datamodel::parse_schema(dml).map(drop).unwrap_err(); + let expected = expect![[r#" + error: Invalid model: Using Bytes type is not allowed in the model's id.. + --> schema.prisma:10 +  |  +  9 |  + 10 | model A { + 11 |  id Bytes @id + 12 | } +  |  + "#]]; + + expected.assert_eq(&error); +}