Incorrect casting of MySQL `tinyint`
Closed this issue · 3 comments
0xdeafbeef commented
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
weiznich commented
Thanks for reporting. Mind submitting a PR with a fix and a test?
0xdeafbeef commented
@weiznich sure, I wrote a pr, but but cargo test wasn't compiling. It should be cargo test - - all-features
, right?
weiznich commented
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.