mirror of
https://github.com/launchbadge/sqlx.git
synced 2025-10-02 07:21:08 +00:00
doc(macros): document type override feature for macros
This commit is contained in:
parent
7b37ebde0f
commit
897c8f429a
105
src/macros.rs
105
src/macros.rs
@ -1,6 +1,6 @@
|
||||
/// Statically checked SQL query with `println!()` style syntax.
|
||||
///
|
||||
/// This expands to an instance of [QueryAs] that outputs an ad-hoc anonymous struct type,
|
||||
/// This expands to an instance of [QueryAs][crate::QueryAs] that outputs an ad-hoc anonymous struct type,
|
||||
/// if the query has output columns, or `()` (unit) otherwise:
|
||||
///
|
||||
/// ```rust,ignore
|
||||
@ -111,9 +111,78 @@
|
||||
/// `NULL` which then depends on the semantics of what functions are used. Consult the MySQL
|
||||
/// manual for the functions you are using to find the cases in which they return `NULL`.
|
||||
///
|
||||
/// To override the nullability of an output column, use [query_as!].
|
||||
/// To override the nullability of an output column, use [query_as!], or see below.
|
||||
///
|
||||
/// ### Offline Mode (requires the `offline` feature)
|
||||
/// ## Type Overrides: Bind Parameters (Postgres only)
|
||||
/// For typechecking of bind parameters, casts using `as` are treated as overrides for the inferred
|
||||
/// types of bind parameters and no typechecking is emitted:
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// #[derive(sqlx::Type)]
|
||||
/// #[sqlx(transparent)]
|
||||
/// struct MyInt4(i32);
|
||||
///
|
||||
/// let my_int = MyInt4(1);
|
||||
///
|
||||
/// sqlx::query!("select $1::int4 as id", my_int as MyInt4)
|
||||
/// ```
|
||||
///
|
||||
/// In Rust 1.45 we can eliminate this redundancy by allowing casts using `as _` or type ascription
|
||||
/// syntax, i.e. `my_int: _` (which is unstable but can be stripped), but this requires modifying
|
||||
/// the expression which is not possible as the macros are currently implemented. Casts to `_` are
|
||||
/// forbidden for now as they produce rather nasty type errors.
|
||||
///
|
||||
/// ## Type Overrides: Output Columns
|
||||
/// Type overrides are also available for output columns, utilizing the SQL standard's support
|
||||
/// for arbitrary text in column names:
|
||||
///
|
||||
/// * selecting a column `foo as "foo!"` (Postgres / SQLite) or `` foo as `foo!` `` overrides
|
||||
/// inferred nullability and forces the column to be treated as `NOT NULL`; this is useful e.g. for
|
||||
/// selecting expressions in Postgres where we cannot infer nullability:
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// # async fn main() {
|
||||
/// # let mut conn = panic!();
|
||||
/// // Postgres: using a raw query string lets us use unescaped double-quotes
|
||||
/// // Note that this query wouldn't work in SQLite as we still don't know the exact type of `id`
|
||||
/// let record = sqlx::query!(r#"select 1 as "id!""#) // MySQL: use "select 1 as `id!`" instead
|
||||
/// .fetch_one(&mut conn)
|
||||
/// .await?;
|
||||
///
|
||||
/// // For Postgres this would have been inferred to be Option<i32> instead
|
||||
/// assert_eq!(record.id, 1i32);
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// * selecting a column `foo as "foo: T"` (Postgres / SQLite) or `` foo as `foo: T` `` (MySQL)
|
||||
/// overrides the inferred type which is useful when selecting user-defined custom types
|
||||
/// (dynamic type checking is still done so if the types are incompatible this will be an error
|
||||
/// at runtime instead of compile-time):
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// # async fn main() {
|
||||
/// # let mut conn = panic!();
|
||||
/// #[derive(sqlx::Type)]
|
||||
/// #[sqlx(transparent)
|
||||
/// struct MyInt4(i32);
|
||||
///
|
||||
/// let my_int = MyInt4(1);
|
||||
///
|
||||
/// // Postgres/SQLite
|
||||
/// sqlx::query!(r#"select 1 as "id: MyInt4""#) // MySQL: use "select 1 as `id: MyInt4`" instead
|
||||
/// .fetch_one(&mut conn)
|
||||
/// .await?;
|
||||
///
|
||||
/// // For Postgres this would have been inferred to be `Option<i32>`, MySQL `i32`
|
||||
/// // and SQLite it wouldn't have worked at all because we couldn't know the type.
|
||||
/// assert_eq!(record.id, MyInt4(1));
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// As mentioned, this allows specifying the type of a pure expression column which is normally
|
||||
/// forbidden for SQLite as there's no way we can ask SQLite what type the column is expected to be.
|
||||
///
|
||||
/// ## Offline Mode (requires the `offline` feature)
|
||||
/// The macros can be configured to not require a live database connection for compilation,
|
||||
/// but it requires a couple extra steps:
|
||||
///
|
||||
@ -313,6 +382,36 @@ macro_rules! query_file_unchecked (
|
||||
/// ## Nullability
|
||||
/// Use `Option` for columns which may be `NULL` in order to avoid a runtime error being returned
|
||||
/// from `.fetch_*()`.
|
||||
///
|
||||
/// ### Additional Column Type Override Option
|
||||
/// In addition to the column type overrides supported by [query!], `query_as!()` supports an
|
||||
/// additional override option:
|
||||
///
|
||||
/// If you select a column `foo as "foo: _"` (Postgres/SQLite) or `` foo as `foo: _` `` (MySQL)
|
||||
/// it causes that column to be inferred based on the type of the corresponding field in the given
|
||||
/// record struct. Runtime type-checking is still done so an error will be emitted if the types
|
||||
/// are not compatible.
|
||||
///
|
||||
/// This allows you to override the inferred type of a column to instead use a custom-defined type:
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// #[derive(sqlx::Type)]
|
||||
/// #[sqlx(transparent)
|
||||
/// struct MyInt4(i32);
|
||||
///
|
||||
/// struct Record {
|
||||
/// id: MyInt4,
|
||||
/// }
|
||||
///
|
||||
/// let my_int = MyInt4(1);
|
||||
///
|
||||
/// // Postgres/SQLite
|
||||
/// sqlx::query!(r#"select 1 as "id: _""#) // MySQL: use "select 1 as `id: _`" instead
|
||||
/// .fetch_one(&mut conn)
|
||||
/// .await?;
|
||||
///
|
||||
/// assert_eq!(record.id, MyInt4(1));
|
||||
/// ```
|
||||
#[macro_export]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
|
||||
macro_rules! query_as (
|
||||
|
Loading…
x
Reference in New Issue
Block a user