mirror of
https://github.com/launchbadge/sqlx.git
synced 2025-10-04 00:05:27 +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.
|
/// 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:
|
/// if the query has output columns, or `()` (unit) otherwise:
|
||||||
///
|
///
|
||||||
/// ```rust,ignore
|
/// ```rust,ignore
|
||||||
@ -111,9 +111,78 @@
|
|||||||
/// `NULL` which then depends on the semantics of what functions are used. Consult the MySQL
|
/// `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`.
|
/// 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,
|
/// The macros can be configured to not require a live database connection for compilation,
|
||||||
/// but it requires a couple extra steps:
|
/// but it requires a couple extra steps:
|
||||||
///
|
///
|
||||||
@ -313,6 +382,36 @@ macro_rules! query_file_unchecked (
|
|||||||
/// ## Nullability
|
/// ## Nullability
|
||||||
/// Use `Option` for columns which may be `NULL` in order to avoid a runtime error being returned
|
/// Use `Option` for columns which may be `NULL` in order to avoid a runtime error being returned
|
||||||
/// from `.fetch_*()`.
|
/// 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]
|
#[macro_export]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
|
||||||
macro_rules! query_as (
|
macro_rules! query_as (
|
||||||
|
Loading…
x
Reference in New Issue
Block a user