From 02088c7d5674478490db6997e4de00ee35e6509b Mon Sep 17 00:00:00 2001 From: alu Date: Wed, 24 Jul 2024 16:17:35 +0900 Subject: [PATCH 1/5] Support for MySQL enums in `sqlx::Type` --- sqlx-mysql/src/type_info.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sqlx-mysql/src/type_info.rs b/sqlx-mysql/src/type_info.rs index 6b0bfff76c..49d1d2b37d 100644 --- a/sqlx-mysql/src/type_info.rs +++ b/sqlx-mysql/src/type_info.rs @@ -28,8 +28,8 @@ impl MySqlTypeInfo { #[doc(hidden)] pub const fn __enum() -> Self { Self { - r#type: ColumnType::Enum, - flags: ColumnFlags::BINARY, + r#type: ColumnType::String, + flags: ColumnFlags::union(ColumnFlags::BINARY, ColumnFlags::ENUM), max_size: None, } } From 393a816ff1b7572db45a615558cf8e5a157284f6 Mon Sep 17 00:00:00 2001 From: Austin Bonander Date: Thu, 25 Jul 2024 01:53:38 -0700 Subject: [PATCH 2/5] chore(mysql): add comprehensive test for enum derives --- Cargo.lock | 2 - Cargo.toml | 5 + sqlx-test/Cargo.toml | 2 - tests/mysql/derives.rs | 302 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 307 insertions(+), 4 deletions(-) create mode 100644 tests/mysql/derives.rs diff --git a/Cargo.lock b/Cargo.lock index f1aa1acd86..3b0feb4b4f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3565,11 +3565,9 @@ name = "sqlx-test" version = "0.1.0" dependencies = [ "anyhow", - "async-std", "dotenvy", "env_logger", "sqlx", - "tokio", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 0af662a46b..1a535afae2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -287,6 +287,11 @@ name = "mysql-describe" path = "tests/mysql/describe.rs" required-features = ["mysql"] +[[test]] +name = "mysql-derives" +path = "tests/mysql/derives.rs" +required-features = ["mysql", "derive"] + [[test]] name = "mysql-macros" path = "tests/mysql/macros.rs" diff --git a/sqlx-test/Cargo.toml b/sqlx-test/Cargo.toml index ddc94d216e..32708596e9 100644 --- a/sqlx-test/Cargo.toml +++ b/sqlx-test/Cargo.toml @@ -9,5 +9,3 @@ sqlx = { default-features = false, path = ".." } env_logger = "0.11" dotenvy = "0.15.0" anyhow = "1.0.26" -async-std = { version = "1.8.0", features = [ "attributes" ] } -tokio = { version = "1.0.1", features = [ "full" ] } diff --git a/tests/mysql/derives.rs b/tests/mysql/derives.rs new file mode 100644 index 0000000000..7a3f1210fa --- /dev/null +++ b/tests/mysql/derives.rs @@ -0,0 +1,302 @@ +use sqlx_mysql::MySql; +use sqlx_test::new; + +#[sqlx::test] +async fn test_derive_strong_enum() -> anyhow::Result<()> { + #[derive(sqlx::Type, PartialEq, Eq, Debug)] + #[sqlx(rename_all = "PascalCase")] + enum PascalCaseEnum { + FooFoo, + BarBar, + BazBaz + } + + #[derive(sqlx::Type, PartialEq, Eq, Debug)] + #[sqlx(rename_all = "camelCase")] + enum CamelCaseEnum { + FooFoo, + BarBar, + BazBaz + } + + #[derive(sqlx::Type, PartialEq, Eq, Debug)] + #[sqlx(rename_all = "snake_case")] + enum SnakeCaseEnum { + FooFoo, + BarBar, + BazBaz + } + + #[derive(sqlx::Type, PartialEq, Eq, Debug)] + #[sqlx(rename_all = "SCREAMING_SNAKE_CASE")] + enum ScreamingSnakeCaseEnum { + FooFoo, + BarBar, + BazBaz + } + + #[derive(sqlx::Type, PartialEq, Eq, Debug)] + #[sqlx(rename_all = "kebab-case")] + enum KebabCaseEnum { + FooFoo, + BarBar, + BazBaz + } + + #[derive(sqlx::Type, PartialEq, Eq, Debug)] + #[sqlx(rename_all = "lowercase")] + enum LowerCaseEnum { + FooFoo, + BarBar, + BazBaz + } + + #[derive(sqlx::Type, PartialEq, Eq, Debug)] + #[sqlx(rename_all = "UPPERCASE")] + enum UpperCaseEnum { + FooFoo, + BarBar, + BazBaz + } + + #[derive(sqlx::Type, PartialEq, Eq, Debug)] + enum DefaultCaseEnum { + FooFoo, + BarBar, + BazBaz + } + + #[derive(sqlx::FromRow, PartialEq, Eq, Debug)] + struct StrongEnumRow { + pascal_case: PascalCaseEnum, + camel_case: CamelCaseEnum, + snake_case: SnakeCaseEnum, + screaming_snake_case: ScreamingSnakeCaseEnum, + kebab_case: KebabCaseEnum, + lowercase: LowerCaseEnum, + uppercase: UpperCaseEnum, + default_case: DefaultCaseEnum + } + + let mut conn = new::().await?; + + sqlx::raw_sql( + r#" + CREATE TEMPORARY TABLE strong_enum ( + pascal_case ENUM('FooFoo', 'BarBar', 'BazBaz'), + camel_case ENUM('fooFoo', 'barBar', 'bazBaz'), + snake_case ENUM('foo_foo', 'bar_bar', 'baz_baz'), + screaming_snake_case ENUM('FOO_FOO', 'BAR_BAR', 'BAZ_BAZ'), + kebab_case ENUM('foo-foo', 'bar-bar', 'baz-baz'), + lowercase ENUM('foofoo', 'barbar', 'bazbaz'), + uppercase ENUM('FOOFOO', 'BARBAR', 'BAZBAZ'), + default_case ENUM('FooFoo', 'BarBar', 'BazBaz') + ); + "# + ) + .execute(&mut conn) + .await?; + + let input = StrongEnumRow { + pascal_case: PascalCaseEnum::FooFoo, + camel_case: CamelCaseEnum::BarBar, + snake_case: SnakeCaseEnum::BazBaz, + screaming_snake_case: ScreamingSnakeCaseEnum::FooFoo, + kebab_case: KebabCaseEnum::BarBar, + lowercase: LowerCaseEnum::BazBaz, + uppercase: UpperCaseEnum::FooFoo, + default_case: DefaultCaseEnum::BarBar + }; + + sqlx::query( + r#" + INSERT INTO strong_enum( + pascal_case, + camel_case, + snake_case, + screaming_snake_case, + kebab_case, + lowercase, + uppercase, + default_case + ) + VALUES (?, ?, ?, ?, ?, ?, ?, ?) + "# + ) + .bind(&input.pascal_case) + .bind(&input.camel_case) + .bind(&input.snake_case) + .bind(&input.screaming_snake_case) + .bind(&input.kebab_case) + .bind(&input.lowercase) + .bind(&input.uppercase) + .bind(&input.default_case) + .execute(&mut conn) + .await?; + + let output: StrongEnumRow = sqlx::query_as("SELECT * FROM strong_enum") + .fetch_one(&mut conn) + .await?; + + assert_eq!(input, output); + + Ok(()) +} + +#[sqlx::test] +async fn test_derive_weak_enum() -> anyhow::Result<()> { + #[derive(sqlx::Type, Debug, PartialEq, Eq)] + #[repr(i8)] + enum WeakEnumI8 { + Foo = i8::MIN, + Bar = 0, + Baz = i8::MAX + } + + #[derive(sqlx::Type, Debug, PartialEq, Eq)] + #[repr(i16)] + enum WeakEnumI16 { + Foo = i16::MIN, + Bar = 0, + Baz = i16::MAX + } + + #[derive(sqlx::Type, Debug, PartialEq, Eq)] + #[repr(i32)] + enum WeakEnumI32 { + Foo = i32::MIN, + Bar = 0, + Baz = i32::MAX, + } + + #[derive(sqlx::Type, Debug, PartialEq, Eq)] + #[repr(i64)] + enum WeakEnumI64 { + Foo = i64::MIN, + Bar = 0, + Baz = i64::MAX, + } + + #[derive(sqlx::Type, Debug, PartialEq, Eq)] + #[repr(u8)] + enum WeakEnumU8 { + Foo = 0, + Bar = 1, + Baz = u8::MAX + } + + #[derive(sqlx::Type, Debug, PartialEq, Eq)] + #[repr(u16)] + enum WeakEnumU16 { + Foo = 0, + Bar = 1, + Baz = u16::MAX + } + + #[derive(sqlx::Type, Debug, PartialEq, Eq)] + #[repr(u32)] + enum WeakEnumU32 { + Foo = 0, + Bar = 1, + Baz = u32::MAX, + } + + #[derive(sqlx::Type, Debug, PartialEq, Eq)] + #[repr(u64)] + enum WeakEnumU64 { + Foo = 0, + Bar = 1, + Baz = u64::MAX, + } + + #[derive(sqlx::FromRow, Debug, PartialEq, Eq)] + struct WeakEnumRow { + i8: WeakEnumI8, + i16: WeakEnumI16, + i32: WeakEnumI32, + i64: WeakEnumI64, + u8: WeakEnumU8, + u16: WeakEnumU16, + u32: WeakEnumU32, + u64: WeakEnumU64 + } + + let mut conn = new::().await?; + + sqlx::raw_sql( + r#" + CREATE TEMPORARY TABLE weak_enum ( + i8 TINYINT, + i16 SMALLINT, + i32 INT, + i64 BIGINT, + u8 TINYINT UNSIGNED, + u16 SMALLINT UNSIGNED, + u32 INT UNSIGNED, + u64 BIGINT UNSIGNED + ) + "# + ) + .execute(&mut conn) + .await?; + + let rows_in = vec![ + WeakEnumRow { + i8: WeakEnumI8::Foo, + i16: WeakEnumI16::Foo, + i32: WeakEnumI32::Foo, + i64: WeakEnumI64::Foo, + u8: WeakEnumU8::Foo, + u16: WeakEnumU16::Foo, + u32: WeakEnumU32::Foo, + u64: WeakEnumU64::Foo + }, + WeakEnumRow { + i8: WeakEnumI8::Bar, + i16: WeakEnumI16::Bar, + i32: WeakEnumI32::Bar, + i64: WeakEnumI64::Bar, + u8: WeakEnumU8::Bar, + u16: WeakEnumU16::Bar, + u32: WeakEnumU32::Bar, + u64: WeakEnumU64::Bar + }, + WeakEnumRow { + i8: WeakEnumI8::Baz, + i16: WeakEnumI16::Baz, + i32: WeakEnumI32::Baz, + i64: WeakEnumI64::Baz, + u8: WeakEnumU8::Baz, + u16: WeakEnumU16::Baz, + u32: WeakEnumU32::Baz, + u64: WeakEnumU64::Baz + }, + ]; + + for row in &rows_in { + sqlx::query( + r#" + INSERT INTO weak_enum(i8, i16, i32, i64, u8, u16, u32, u64) + VALUES (?, ?, ?, ?, ?, ?, ?, ?) + "# + ) + .bind(&row.i8) + .bind(&row.i16) + .bind(&row.i32) + .bind(&row.i64) + .bind(&row.u8) + .bind(&row.u16) + .bind(&row.u32) + .bind(&row.u64) + .execute(&mut conn) + .await?; + } + + let rows_out: Vec = sqlx::query_as("SELECT * FROM weak_enum") + .fetch_all(&mut conn) + .await?; + + assert_eq!(rows_in, rows_out); + + Ok(()) +} \ No newline at end of file From 95833d7bba20891b79ac00c4efe746340763f97f Mon Sep 17 00:00:00 2001 From: Austin Bonander Date: Thu, 25 Jul 2024 01:54:02 -0700 Subject: [PATCH 3/5] fix(mysql): use correct types for encoding/decoding enums --- sqlx-macros-core/src/derives/type.rs | 4 ++-- sqlx-mysql/src/type_info.rs | 11 ++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/sqlx-macros-core/src/derives/type.rs b/sqlx-macros-core/src/derives/type.rs index d035ec5aa7..18e763d2d6 100644 --- a/sqlx-macros-core/src/derives/type.rs +++ b/sqlx-macros-core/src/derives/type.rs @@ -181,11 +181,11 @@ fn expand_derive_has_sql_type_strong_enum( #[automatically_derived] impl ::sqlx::Type<::sqlx::MySql> for #ident { fn type_info() -> ::sqlx::mysql::MySqlTypeInfo { - ::sqlx::mysql::MySqlTypeInfo::__enum() + ::sqlx::mysql::MySqlTypeInfo::__enum_input() } fn compatible(ty: &::sqlx::mysql::MySqlTypeInfo) -> ::std::primitive::bool { - *ty == ::sqlx::mysql::MySqlTypeInfo::__enum() + ty.is_enum() } } )); diff --git a/sqlx-mysql/src/type_info.rs b/sqlx-mysql/src/type_info.rs index 49d1d2b37d..bb514dce90 100644 --- a/sqlx-mysql/src/type_info.rs +++ b/sqlx-mysql/src/type_info.rs @@ -17,6 +17,11 @@ pub struct MySqlTypeInfo { } impl MySqlTypeInfo { + pub fn is_enum(&self) -> bool { + // Can't do `== __enum_input()` because MySQL returns a nonzero `max_size` + self.flags.contains(ColumnFlags::ENUM) || self.r#type == ColumnType::Enum + } + pub(crate) const fn binary(ty: ColumnType) -> Self { Self { r#type: ty, @@ -26,7 +31,11 @@ impl MySqlTypeInfo { } #[doc(hidden)] - pub const fn __enum() -> Self { + pub const fn __enum_input() -> Self { + // Newer versions of MySQL seem to expect that a parameter binding of `MYSQL_TYPE_ENUM` + // means that the value is encoded as an integer. + // + // For "strong" enums inputted as strings, we need to specify this type instead. Self { r#type: ColumnType::String, flags: ColumnFlags::union(ColumnFlags::BINARY, ColumnFlags::ENUM), From b41ca95f4bdd1065b54583f17ead87f6043b486b Mon Sep 17 00:00:00 2001 From: Austin Bonander Date: Thu, 25 Jul 2024 01:55:24 -0700 Subject: [PATCH 4/5] chore: run `cargo fmt` --- tests/mysql/derives.rs | 98 +++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/tests/mysql/derives.rs b/tests/mysql/derives.rs index 7a3f1210fa..825c7b8e2c 100644 --- a/tests/mysql/derives.rs +++ b/tests/mysql/derives.rs @@ -8,7 +8,7 @@ async fn test_derive_strong_enum() -> anyhow::Result<()> { enum PascalCaseEnum { FooFoo, BarBar, - BazBaz + BazBaz, } #[derive(sqlx::Type, PartialEq, Eq, Debug)] @@ -16,7 +16,7 @@ async fn test_derive_strong_enum() -> anyhow::Result<()> { enum CamelCaseEnum { FooFoo, BarBar, - BazBaz + BazBaz, } #[derive(sqlx::Type, PartialEq, Eq, Debug)] @@ -24,7 +24,7 @@ async fn test_derive_strong_enum() -> anyhow::Result<()> { enum SnakeCaseEnum { FooFoo, BarBar, - BazBaz + BazBaz, } #[derive(sqlx::Type, PartialEq, Eq, Debug)] @@ -32,7 +32,7 @@ async fn test_derive_strong_enum() -> anyhow::Result<()> { enum ScreamingSnakeCaseEnum { FooFoo, BarBar, - BazBaz + BazBaz, } #[derive(sqlx::Type, PartialEq, Eq, Debug)] @@ -40,7 +40,7 @@ async fn test_derive_strong_enum() -> anyhow::Result<()> { enum KebabCaseEnum { FooFoo, BarBar, - BazBaz + BazBaz, } #[derive(sqlx::Type, PartialEq, Eq, Debug)] @@ -48,7 +48,7 @@ async fn test_derive_strong_enum() -> anyhow::Result<()> { enum LowerCaseEnum { FooFoo, BarBar, - BazBaz + BazBaz, } #[derive(sqlx::Type, PartialEq, Eq, Debug)] @@ -56,14 +56,14 @@ async fn test_derive_strong_enum() -> anyhow::Result<()> { enum UpperCaseEnum { FooFoo, BarBar, - BazBaz + BazBaz, } #[derive(sqlx::Type, PartialEq, Eq, Debug)] enum DefaultCaseEnum { FooFoo, BarBar, - BazBaz + BazBaz, } #[derive(sqlx::FromRow, PartialEq, Eq, Debug)] @@ -75,13 +75,13 @@ async fn test_derive_strong_enum() -> anyhow::Result<()> { kebab_case: KebabCaseEnum, lowercase: LowerCaseEnum, uppercase: UpperCaseEnum, - default_case: DefaultCaseEnum + default_case: DefaultCaseEnum, } let mut conn = new::().await?; sqlx::raw_sql( - r#" + r#" CREATE TEMPORARY TABLE strong_enum ( pascal_case ENUM('FooFoo', 'BarBar', 'BazBaz'), camel_case ENUM('fooFoo', 'barBar', 'bazBaz'), @@ -92,10 +92,10 @@ async fn test_derive_strong_enum() -> anyhow::Result<()> { uppercase ENUM('FOOFOO', 'BARBAR', 'BAZBAZ'), default_case ENUM('FooFoo', 'BarBar', 'BazBaz') ); - "# + "#, ) - .execute(&mut conn) - .await?; + .execute(&mut conn) + .await?; let input = StrongEnumRow { pascal_case: PascalCaseEnum::FooFoo, @@ -105,11 +105,11 @@ async fn test_derive_strong_enum() -> anyhow::Result<()> { kebab_case: KebabCaseEnum::BarBar, lowercase: LowerCaseEnum::BazBaz, uppercase: UpperCaseEnum::FooFoo, - default_case: DefaultCaseEnum::BarBar + default_case: DefaultCaseEnum::BarBar, }; sqlx::query( - r#" + r#" INSERT INTO strong_enum( pascal_case, camel_case, @@ -121,18 +121,18 @@ async fn test_derive_strong_enum() -> anyhow::Result<()> { default_case ) VALUES (?, ?, ?, ?, ?, ?, ?, ?) - "# + "#, ) - .bind(&input.pascal_case) - .bind(&input.camel_case) - .bind(&input.snake_case) - .bind(&input.screaming_snake_case) - .bind(&input.kebab_case) - .bind(&input.lowercase) - .bind(&input.uppercase) - .bind(&input.default_case) - .execute(&mut conn) - .await?; + .bind(&input.pascal_case) + .bind(&input.camel_case) + .bind(&input.snake_case) + .bind(&input.screaming_snake_case) + .bind(&input.kebab_case) + .bind(&input.lowercase) + .bind(&input.uppercase) + .bind(&input.default_case) + .execute(&mut conn) + .await?; let output: StrongEnumRow = sqlx::query_as("SELECT * FROM strong_enum") .fetch_one(&mut conn) @@ -150,7 +150,7 @@ async fn test_derive_weak_enum() -> anyhow::Result<()> { enum WeakEnumI8 { Foo = i8::MIN, Bar = 0, - Baz = i8::MAX + Baz = i8::MAX, } #[derive(sqlx::Type, Debug, PartialEq, Eq)] @@ -158,7 +158,7 @@ async fn test_derive_weak_enum() -> anyhow::Result<()> { enum WeakEnumI16 { Foo = i16::MIN, Bar = 0, - Baz = i16::MAX + Baz = i16::MAX, } #[derive(sqlx::Type, Debug, PartialEq, Eq)] @@ -182,7 +182,7 @@ async fn test_derive_weak_enum() -> anyhow::Result<()> { enum WeakEnumU8 { Foo = 0, Bar = 1, - Baz = u8::MAX + Baz = u8::MAX, } #[derive(sqlx::Type, Debug, PartialEq, Eq)] @@ -190,7 +190,7 @@ async fn test_derive_weak_enum() -> anyhow::Result<()> { enum WeakEnumU16 { Foo = 0, Bar = 1, - Baz = u16::MAX + Baz = u16::MAX, } #[derive(sqlx::Type, Debug, PartialEq, Eq)] @@ -218,7 +218,7 @@ async fn test_derive_weak_enum() -> anyhow::Result<()> { u8: WeakEnumU8, u16: WeakEnumU16, u32: WeakEnumU32, - u64: WeakEnumU64 + u64: WeakEnumU64, } let mut conn = new::().await?; @@ -235,10 +235,10 @@ async fn test_derive_weak_enum() -> anyhow::Result<()> { u32 INT UNSIGNED, u64 BIGINT UNSIGNED ) - "# + "#, ) - .execute(&mut conn) - .await?; + .execute(&mut conn) + .await?; let rows_in = vec![ WeakEnumRow { @@ -249,7 +249,7 @@ async fn test_derive_weak_enum() -> anyhow::Result<()> { u8: WeakEnumU8::Foo, u16: WeakEnumU16::Foo, u32: WeakEnumU32::Foo, - u64: WeakEnumU64::Foo + u64: WeakEnumU64::Foo, }, WeakEnumRow { i8: WeakEnumI8::Bar, @@ -259,7 +259,7 @@ async fn test_derive_weak_enum() -> anyhow::Result<()> { u8: WeakEnumU8::Bar, u16: WeakEnumU16::Bar, u32: WeakEnumU32::Bar, - u64: WeakEnumU64::Bar + u64: WeakEnumU64::Bar, }, WeakEnumRow { i8: WeakEnumI8::Baz, @@ -269,7 +269,7 @@ async fn test_derive_weak_enum() -> anyhow::Result<()> { u8: WeakEnumU8::Baz, u16: WeakEnumU16::Baz, u32: WeakEnumU32::Baz, - u64: WeakEnumU64::Baz + u64: WeakEnumU64::Baz, }, ]; @@ -278,18 +278,18 @@ async fn test_derive_weak_enum() -> anyhow::Result<()> { r#" INSERT INTO weak_enum(i8, i16, i32, i64, u8, u16, u32, u64) VALUES (?, ?, ?, ?, ?, ?, ?, ?) - "# + "#, ) - .bind(&row.i8) - .bind(&row.i16) - .bind(&row.i32) - .bind(&row.i64) - .bind(&row.u8) - .bind(&row.u16) - .bind(&row.u32) - .bind(&row.u64) - .execute(&mut conn) - .await?; + .bind(&row.i8) + .bind(&row.i16) + .bind(&row.i32) + .bind(&row.i64) + .bind(&row.u8) + .bind(&row.u16) + .bind(&row.u32) + .bind(&row.u64) + .execute(&mut conn) + .await?; } let rows_out: Vec = sqlx::query_as("SELECT * FROM weak_enum") @@ -299,4 +299,4 @@ async fn test_derive_weak_enum() -> anyhow::Result<()> { assert_eq!(rows_in, rows_out); Ok(()) -} \ No newline at end of file +} From 062824e063d6bd916b352ca81ceda20f612f3358 Mon Sep 17 00:00:00 2001 From: Austin Bonander Date: Thu, 25 Jul 2024 02:34:59 -0700 Subject: [PATCH 5/5] chore(mysql): simplify changes to enum handling --- sqlx-macros-core/src/derives/type.rs | 6 +----- sqlx-mysql/src/type_info.rs | 15 +++++++-------- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/sqlx-macros-core/src/derives/type.rs b/sqlx-macros-core/src/derives/type.rs index 18e763d2d6..66579e5b6c 100644 --- a/sqlx-macros-core/src/derives/type.rs +++ b/sqlx-macros-core/src/derives/type.rs @@ -181,11 +181,7 @@ fn expand_derive_has_sql_type_strong_enum( #[automatically_derived] impl ::sqlx::Type<::sqlx::MySql> for #ident { fn type_info() -> ::sqlx::mysql::MySqlTypeInfo { - ::sqlx::mysql::MySqlTypeInfo::__enum_input() - } - - fn compatible(ty: &::sqlx::mysql::MySqlTypeInfo) -> ::std::primitive::bool { - ty.is_enum() + ::sqlx::mysql::MySqlTypeInfo::__enum() } } )); diff --git a/sqlx-mysql/src/type_info.rs b/sqlx-mysql/src/type_info.rs index bb514dce90..a80b233fc9 100644 --- a/sqlx-mysql/src/type_info.rs +++ b/sqlx-mysql/src/type_info.rs @@ -17,11 +17,6 @@ pub struct MySqlTypeInfo { } impl MySqlTypeInfo { - pub fn is_enum(&self) -> bool { - // Can't do `== __enum_input()` because MySQL returns a nonzero `max_size` - self.flags.contains(ColumnFlags::ENUM) || self.r#type == ColumnType::Enum - } - pub(crate) const fn binary(ty: ColumnType) -> Self { Self { r#type: ty, @@ -31,14 +26,18 @@ impl MySqlTypeInfo { } #[doc(hidden)] - pub const fn __enum_input() -> Self { + pub const fn __enum() -> Self { // Newer versions of MySQL seem to expect that a parameter binding of `MYSQL_TYPE_ENUM` // means that the value is encoded as an integer. // - // For "strong" enums inputted as strings, we need to specify this type instead. + // For "strong" enums inputted as strings, we need to specify this type instead + // for wider compatibility. This works on all covered versions of MySQL and MariaDB. + // + // Annoyingly, MySQL's developer documentation doesn't really explain this anywhere; + // this had to be determined experimentally. Self { r#type: ColumnType::String, - flags: ColumnFlags::union(ColumnFlags::BINARY, ColumnFlags::ENUM), + flags: ColumnFlags::ENUM, max_size: None, } }