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

Raw "SELECT ?" sql query results in a panic for the mysql backend #3754

Open
3 tasks done
weiznich opened this issue Aug 18, 2023 · 2 comments
Open
3 tasks done

Raw "SELECT ?" sql query results in a panic for the mysql backend #3754

weiznich opened this issue Aug 18, 2023 · 2 comments

Comments

@weiznich
Copy link
Member

Setup

Versions

  • Rust: 1.71
  • Diesel: 2.1.0
  • Database: mysql
  • Operating System: fedora

Feature Flags

  • diesel: mysql

Problem Description

Raw select queries with binds as select clause fail at runtime with the following error:

thread 'multiconnection::nullable_type_checks' panicked at 'internal error: entered unreachable code: We ensure at the call side that we do not hit this type here. If you ever see this error, something has gone very wrong. Please open an issue at the diesel github repo in this case', diesel/src/mysql/connection/bind.rs:685:50
stack backtrace:
   0: rust_begin_unwind
             at /rustc/2c8cc343237b8f7d5a3c3703e3a87f2eb2c54a74/library/std/src/panicking.rs:575:5
   1: core::panicking::panic_fmt
             at /rustc/2c8cc343237b8f7d5a3c3703e3a87f2eb2c54a74/library/core/src/panicking.rs:64:14
   2: diesel::mysql::connection::bind::<impl core::convert::From<(mysqlclient_sys::enum_field_types,diesel::mysql::connection::bind::Flags)> for diesel::mysql::backend::MysqlType>::from
             at /home/weiznich/Documents/rust/diesel/diesel/src/mysql/connection/bind.rs:685:50
   3: <T as core::convert::Into<U>>::into
             at /rustc/2c8cc343237b8f7d5a3c3703e3a87f2eb2c54a74/library/core/src/convert/mod.rs:726:9
   4: diesel::mysql::connection::bind::BindData::value
             at /home/weiznich/Documents/rust/diesel/diesel/src/mysql/connection/bind.rs:410:23
   5: <diesel::mysql::connection::stmt::iterator::MysqlField as diesel::row::Field<diesel::mysql::backend::Mysql>>::value
             at /home/weiznich/Documents/rust/diesel/diesel/src/mysql/connection/stmt/iterator.rs:223:72

What are you trying to accomplish?

let mut conn = MysqlConnection::establish("…").unwrap();

#[derive(QueryableByName)]
struct Res {
    #[diesel(sql_type = sql_types::Integer)]
    bar: i32
}

diesel::sql_query("SELECT ? as bar").bind::<sql_types::Integer, i32>(1).get_result::<Res>(&mut conn);

What is the expected output?

The query runs successful

What is the actual output?

The panic message from above

Are you seeing any additional errors?

Steps to reproduce

let mut conn = MysqlConnection::establish("…").unwrap();

#[derive(QueryableByName)]
struct Res {
    #[diesel(sql_type = sql_types::Integer)]
    bar: i32
}

diesel::sql_query("SELECT ? as bar").bind::<sql_types::Integer, i32>(1).get_result::<Res>(&mut conn);

Preliminary debugging

This seems to happen because mysql returns MYSQL_TYPE_NULL in such cases and we don't have any type information on our own there. I've tried to just ignore the missing type information but we need the type information for automatically converting to the right numeric type here:

pub(crate) fn numeric_value(&self) -> deserialize::Result<NumericRepresentation<'_>> {
Ok(match self.tpe {
MysqlType::UnsignedTiny | MysqlType::Tiny => {
NumericRepresentation::Tiny(self.raw[0] as i8)
}
MysqlType::UnsignedShort | MysqlType::Short => {
NumericRepresentation::Small(i16::from_ne_bytes((&self.raw[..2]).try_into()?))
}
MysqlType::UnsignedLong | MysqlType::Long => {
NumericRepresentation::Medium(i32::from_ne_bytes((&self.raw[..4]).try_into()?))
}
MysqlType::UnsignedLongLong | MysqlType::LongLong => {
NumericRepresentation::Big(i64::from_ne_bytes(self.raw.try_into()?))
}
MysqlType::Float => {
NumericRepresentation::Float(f32::from_ne_bytes(self.raw.try_into()?))
}
MysqlType::Double => {
NumericRepresentation::Double(f64::from_ne_bytes(self.raw.try_into()?))
}
MysqlType::Numeric => NumericRepresentation::Decimal(self.raw),
_ => return Err(self.invalid_type_code("number")),
})
}

Checklist

  • 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
@pxp9
Copy link

pxp9 commented Aug 23, 2023

it panic! because it hits this unreachable code

@weiznich
Copy link
Member Author

@pxp9 Thanks for that note. I'm well aware of that fact as I'm already done some debugging there + wrote the corresponding panic! call on my own. This issue mostly exists to document that issue for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants