weiznich/diesel_async

Incorrect casting of MySQL `tinyint`

Closed this issue · 3 comments

Setup

Versions

  • Rust: rustc 1.70.0 (90c541806 2023-05-31)
  • Diesel: 2.1.0
  • Diesel_async: 0.3.1
  • Database: mysql 8.0

Feature Flags

  • diesel: ["mysql_backend", "serde_json", "uuid"]
  • diesel_async: ["mysql", "mobc"]

Problem Description

having such a table:

diesel::table! {
    use diesel::sql_types::*;
    use super::sql_types::StateMapping;

    accounts (address, workchain) {
        workchain -> Tinyint,
        #[max_length = 32]
        address -> Varbinary,
        ...
    }
}

this query

#[derive(Queryable, Selectable)]
#[diesel(check_for_backend(Mysql))]
#[diesel(table_name = crate::schema::accounts)]
pub struct AccountWithCreatorInfo {
   ...
}

 let query = accounts_dsl::accounts
            .filter(accounts_dsl::workchain.eq(-1))
            .select(AccountWithCreatorInfo::as_select());

produces query like this:

"SELECT  ... FROM `accounts` WHERE (`accounts`.`workchain` = ?)",
    binds: [
        -1,
    ],

But here we receive values as Vec<u8>,
take the first element and cast them as i64. Casting u8::MAX as i64 returns 255 instead of original -1 bind.

I suggest changing this line to

            MysqlType::Tiny => Value::Int((bind[0] as i8) as i64),

Checklist

  • I have already looked over the issue tracker for similar possible closed issues.
  • This issue can be reproduced on Rust's stable channel. (Your issue will be
    closed if this is not the case)
  • This issue can be reproduced without requiring a third party crate

Thanks for reporting. Mind submitting a PR with a fix and a test?

@weiznich sure, I wrote a pr, but but cargo test wasn't compiling. It should be cargo test - - all-features, right?

It's currently only possible to test one backend at the time. So cargo test --features "mysql" or cargo test --features "postgres". As this is a mysql backend specific issue it should be fine to run the mysql tests afterwards, especially as the CI runs all the tests anyway.