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

Deriving sqlx::Type on an enum fails to decode a MySql enum #3750

Open
cdhowie opened this issue Feb 19, 2025 · 0 comments
Open

Deriving sqlx::Type on an enum fails to decode a MySql enum #3750

cdhowie opened this issue Feb 19, 2025 · 0 comments
Labels

Comments

@cdhowie
Copy link

cdhowie commented Feb 19, 2025

I have found these related issues/pull requests

This is reminiscent of #1241 but the underlying cause seems to be different.

Description

When testing if two enum types are compatible, sqlx checks if the flags are equal:

return self.flags == other.flags;

This causes problems when the flags on the database column do not exactly match what the builtin __enum() typeinfo has on its flags:

flags: ColumnFlags::ENUM,

For example, we have a column whose flags are NOT_NULL | ENUM | NO_DEFAULT_VALUE and we cannot therefore decode a #[derive(sqlx::Type)] enum from this column. It appears that if a column is marked "not null" or does not have a default value that decoding will therefore unnecessarily fail.

It seems to me that not all flags need to match in the enum case. Certain flags could be ignored, like NO_DEFAULT_VALUE and NOT_NULL.

In particular, this error gets raised:

error occurred while decoding column "Output": mismatched types; Rust type `db::Output` (as SQL type `ENUM`) is not compatible with SQL type `ENUM`

Reproduction steps

Derive sqlx::Type on an enum and attempt to decode it from a MySQL column that is marked either NOT NULL or does not have a default value.

Workaround

As much of MySqlTypeInfo is not public, the workaround is a bit kludgy, but it seems to work in our tests. Instead of deriving sqlx::Type we derive sqlx::Encode and sqlx::Decode, and implement sqlx::Type by hand, like so:

impl sqlx::Type<sqlx::MySql> for Output {
    fn type_info() -> <sqlx::MySql as sqlx::Database>::TypeInfo {
        sqlx::mysql::MySqlTypeInfo::__enum()
    }

    fn compatible(ty: &<sqlx::MySql as sqlx::Database>::TypeInfo) -> bool {
        sqlx::TypeInfo::name(ty) == "ENUM"
    }
}

SQLx version

0.8.3

Enabled SQLx features

chrono, mysql, runtime-tokio

Database server and version

MariaDB 10.11.8

Operating system

Linux (Ubuntu client, Debian server)

Rust version

1.84.1

@cdhowie cdhowie added the bug label Feb 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant