diff --git a/sqlx-mysql/src/types/mod.rs b/sqlx-mysql/src/types/mod.rs index ba0ddb40..889c4d51 100644 --- a/sqlx-mysql/src/types/mod.rs +++ b/sqlx-mysql/src/types/mod.rs @@ -4,7 +4,7 @@ //! //! | Rust type | MySQL type(s) | //! |---------------------------------------|------------------------------------------------------| -//! | `bool` | TINYINT(1), BOOLEAN | +//! | `bool` | TINYINT(1), BOOLEAN, BOOL (see below) | //! | `i8` | TINYINT | //! | `i16` | SMALLINT | //! | `i32` | INT | @@ -18,6 +18,23 @@ //! | `&str`, [`String`] | VARCHAR, CHAR, TEXT | //! | `&[u8]`, `Vec` | VARBINARY, BINARY, BLOB | //! +//! ##### Note: `BOOLEAN`/`BOOL` Type +//! MySQL and MariaDB treat `BOOLEAN` as an alias of the `TINYINT` type: +//! +//! * [Using Data Types from Other Database Engines (MySQL)](https://dev.mysql.com/doc/refman/8.0/en/other-vendor-data-types.html) +//! * [BOOLEAN (MariaDB)](https://mariadb.com/kb/en/boolean/) +//! +//! For the most part, you can simply use the Rust type `bool` when encoding or decoding a value +//! using the dynamic query interface, or passing a boolean as a parameter to the query macros +//! (`query!()` _et al._). +//! +//! However, because the MySQL wire protocol does not distinguish between `TINYINT` and `BOOLEAN`, +//! the query macros cannot know that a `TINYINT` column is semantically a boolean. +//! By default, they will map a `TINYINT` column as `i8` instead, as that is the safer assumption. +//! +//! Thus, you must use the type override syntax in the query to tell the macros you are expecting +//! a `bool` column. See the docs for `query!()` and `query_as!()` for details on this syntax. +//! //! ### [`chrono`](https://crates.io/crates/chrono) //! //! Requires the `chrono` Cargo feature flag. diff --git a/src/macros/mod.rs b/src/macros/mod.rs index 48ac63e8..1d4931fd 100644 --- a/src/macros/mod.rs +++ b/src/macros/mod.rs @@ -28,7 +28,17 @@ /// # fn main() {} /// ``` /// -/// **The method you want to call depends on how many rows you're expecting.** +/// The output columns will be mapped to their corresponding Rust types. +/// See the documentation for your database for details: +/// +/// * Postgres: [crate::postgres::types] +/// * MySQL: [crate::mysql::types] +/// * Note: due to wire protocol limitations, the query macros do not know when +/// a column should be decoded as `bool`. It will be inferred to be `i8` instead. +/// See the link above for details. +/// * SQLite: [crate::sqlite::types] +/// +/// **The method you want to call on the result depends on how many rows you're expecting.** /// /// | Number of Rows | Method to Call* | Returns | Notes | /// |----------------| ----------------------------|-----------------------------------------------------|-------| @@ -38,7 +48,7 @@ /// | At Least One | `.fetch(...)` | `impl Stream>` | Call `.try_next().await` to get each row result. | /// | Multiple | `.fetch_all(...)` | `sqlx::Result>` | | /// -/// \* All methods accept one of `&mut {connection type}`, `&mut Transaction` or `&Pool`. +/// \* All methods accept one of `&mut {connection type}`, `&mut Transaction` or `&Pool`. /// † Only callable if the query returns no columns; otherwise it's assumed the query *may* return at least one row. /// ## Requirements /// * The `DATABASE_URL` environment variable must be set at build-time to point to a database @@ -60,7 +70,7 @@ /// determine the database type. /// /// 1 The `dotenv` crate itself appears abandoned as of [December 2021](https://github.com/dotenv-rs/dotenv/issues/74) -/// so we now use the [`dotenvy`] crate instead. The file format is the same. +/// so we now use the [dotenvy] crate instead. The file format is the same. /// /// [dotenv]: https://crates.io/crates/dotenv /// [dotenvy]: https://crates.io/crates/dotenvy @@ -421,8 +431,10 @@ macro_rules! query_file_unchecked ( /// module for your database for mappings: /// * Postgres: [crate::postgres::types] /// * MySQL: [crate::mysql::types] +/// * Note: due to wire protocol limitations, the query macros do not know when +/// a column should be decoded as `bool`. It will be inferred to be `i8` instead. +/// See the link above for details. /// * SQLite: [crate::sqlite::types] -/// * MSSQL: [crate::mssql::types] /// * If a column may be `NULL`, the corresponding field's type must be wrapped in `Option<_>`. /// * Neither the query nor the struct may have unused fields. ///