diff --git a/schema-engine/sql-introspection-tests/tests/re_introspection/sqlite.rs b/schema-engine/sql-introspection-tests/tests/re_introspection/sqlite.rs index 0909a46fda4..7284cfdf2c9 100644 --- a/schema-engine/sql-introspection-tests/tests/re_introspection/sqlite.rs +++ b/schema-engine/sql-introspection-tests/tests/re_introspection/sqlite.rs @@ -13,6 +13,10 @@ async fn multiple_changed_relation_names_due_to_mapped_models(api: &mut TestApi) t.add_column("id", types::primary()); t.add_column("user_id", types::integer().nullable(false).unique(true)); t.add_column("user_id2", types::integer().nullable(false).unique(true)); + t.add_column( + "createdAt", + types::custom("INTEGER NOT NULL DEFAULT (CAST(unixepoch('subsec') * 1000 AS INTEGER))"), + ); t.add_foreign_key(&["user_id"], "User", &["id"]); t.add_foreign_key(&["user_id2"], "User", &["id"]); @@ -29,6 +33,7 @@ async fn multiple_changed_relation_names_due_to_mapped_models(api: &mut TestApi) id Int @id @default(autoincrement()) user_id Int @unique user_id2 Int @unique + createdAt Int @default(dbgenerated("(CAST(unixepoch('subsec') * 1000 AS INTEGER))")) custom_User Custom_User @relation("CustomRelationName", fields: [user_id], references: [id], onDelete: NoAction, onUpdate: NoAction) custom_User2 Custom_User @relation("AnotherCustomRelationName", fields: [user_id2], references: [id], onDelete: NoAction, onUpdate: NoAction) } @@ -47,6 +52,7 @@ async fn multiple_changed_relation_names_due_to_mapped_models(api: &mut TestApi) id Int @id @default(autoincrement()) user_id Int @unique(map: "sqlite_autoindex_Post_1") user_id2 Int @unique(map: "sqlite_autoindex_Post_2") + createdAt Int @default(dbgenerated("(CAST(unixepoch('subsec') * 1000 AS INTEGER))")) custom_User2 Custom_User @relation("AnotherCustomRelationName", fields: [user_id2], references: [id], onDelete: NoAction, onUpdate: NoAction) custom_User Custom_User @relation("CustomRelationName", fields: [user_id], references: [id], onDelete: NoAction, onUpdate: NoAction) } diff --git a/schema-engine/sql-schema-describer/src/sqlite.rs b/schema-engine/sql-schema-describer/src/sqlite.rs index 26982a12bce..ca89ca0cc7c 100644 --- a/schema-engine/sql-schema-describer/src/sqlite.rs +++ b/schema-engine/sql-schema-describer/src/sqlite.rs @@ -270,6 +270,18 @@ impl<'a> SqlSchemaDescriber<'a> { } } +/// Wraps the given string in parentheses if it is not already. +/// The result of `PRAGMA table_info` removes parentheses from default values, +/// so we need to add parentheses when generating prisma schema. +/// See +fn wrap_in_parentheses(s: &str) -> Cow<'_, str> { + if !(s.starts_with('(') && s.ends_with(')')) { + format!("({})", s).into() + } else { + s.into() + } +} + async fn push_columns( table_name: &str, container_id: Either, @@ -306,26 +318,26 @@ async fn push_columns( Some(match &tpe.family { ColumnTypeFamily::Int => match SqlSchemaDescriber::parse_int(&default_string) { Some(int_value) => DefaultValue::value(int_value), - None => DefaultValue::db_generated(default_string), + None => DefaultValue::db_generated(wrap_in_parentheses(&default_string)), }, ColumnTypeFamily::BigInt => match SqlSchemaDescriber::parse_big_int(&default_string) { Some(int_value) => DefaultValue::value(int_value), - None => DefaultValue::db_generated(default_string), + None => DefaultValue::db_generated(wrap_in_parentheses(&default_string)), }, ColumnTypeFamily::Float => match SqlSchemaDescriber::parse_float(&default_string) { Some(float_value) => DefaultValue::value(float_value), - None => DefaultValue::db_generated(default_string), + None => DefaultValue::db_generated(wrap_in_parentheses(&default_string)), }, ColumnTypeFamily::Decimal => match SqlSchemaDescriber::parse_float(&default_string) { Some(float_value) => DefaultValue::value(float_value), - None => DefaultValue::db_generated(default_string), + None => DefaultValue::db_generated(wrap_in_parentheses(&default_string)), }, ColumnTypeFamily::Boolean => match SqlSchemaDescriber::parse_int(&default_string) { Some(PrismaValue::Int(1)) => DefaultValue::value(true), Some(PrismaValue::Int(0)) => DefaultValue::value(false), _ => match SqlSchemaDescriber::parse_bool(&default_string) { Some(bool_value) => DefaultValue::value(bool_value), - None => DefaultValue::db_generated(default_string), + None => DefaultValue::db_generated(wrap_in_parentheses(&default_string)), }, }, ColumnTypeFamily::String => { @@ -335,14 +347,14 @@ async fn push_columns( "current_timestamp" | "datetime(\'now\')" | "datetime(\'now\', \'localtime\')" => { DefaultValue::now() } - _ => DefaultValue::db_generated(default_string), + _ => DefaultValue::db_generated(wrap_in_parentheses(&default_string)), }, ColumnTypeFamily::Json => DefaultValue::value(default_string), - ColumnTypeFamily::Binary => DefaultValue::db_generated(default_string), - ColumnTypeFamily::Uuid => DefaultValue::db_generated(default_string), + ColumnTypeFamily::Binary => DefaultValue::db_generated(wrap_in_parentheses(&default_string)), + ColumnTypeFamily::Uuid => DefaultValue::db_generated(wrap_in_parentheses(&default_string)), ColumnTypeFamily::Enum(_) => DefaultValue::value(PrismaValue::Enum(default_string)), ColumnTypeFamily::Udt(_) | ColumnTypeFamily::Unsupported(_) => { - DefaultValue::db_generated(default_string) + DefaultValue::db_generated(wrap_in_parentheses(&default_string)) } }) }