sqlx/macros/
mod.rs

1/// Statically checked SQL query with `println!()` style syntax.
2///
3/// This expands to an instance of [`query::Map`][crate::query::Map] that outputs an ad-hoc anonymous
4/// struct type, if the query has at least one output column that is not `Void`, or `()` (unit) otherwise:
5///
6/// ```rust,ignore
7/// # use sqlx::Connect;
8/// # #[cfg(all(feature = "mysql", feature = "_rt-async-std"))]
9/// # #[async_std::main]
10/// # async fn main() -> sqlx::Result<()>{
11/// # let db_url = dotenvy::var("DATABASE_URL").expect("DATABASE_URL must be set");
12/// #
13/// # if !(db_url.starts_with("mysql") || db_url.starts_with("mariadb")) { return Ok(()) }
14/// # let mut conn = sqlx::MySqlConnection::connect(db_url).await?;
15/// // let mut conn = <impl sqlx::Executor>;
16/// let account = sqlx::query!("select (1) as id, 'Herp Derpinson' as name")
17///     .fetch_one(&mut conn)
18///     .await?;
19///
20/// // anonymous struct has `#[derive(Debug)]` for convenience
21/// println!("{account:?}");
22/// println!("{}: {}", account.id, account.name);
23///
24/// # Ok(())
25/// # }
26/// #
27/// # #[cfg(any(not(feature = "mysql"), not(feature = "_rt-async-std")))]
28/// # fn main() {}
29/// ```
30///
31/// The output columns will be mapped to their corresponding Rust types.
32/// See the documentation for your database for details:
33///
34/// * Postgres: [crate::postgres::types]
35/// * MySQL: [crate::mysql::types]
36///     * Note: due to wire protocol limitations, the query macros do not know when
37///       a column should be decoded as `bool`. It will be inferred to be `i8` instead.
38///       See the link above for details.
39/// * SQLite: [crate::sqlite::types]
40///
41/// **The method you want to call on the result depends on how many rows you're expecting.**
42///
43/// | Number of Rows | Method to Call*             | Returns                                             | Notes |
44/// |----------------| ----------------------------|-----------------------------------------------------|-------|
45/// | None†          | `.execute(...).await`       | `sqlx::Result<DB::QueryResult>`                     | For `INSERT`/`UPDATE`/`DELETE` without `RETURNING`. |
46/// | Zero or One    | `.fetch_optional(...).await`| `sqlx::Result<Option<{adhoc struct}>>`              | Extra rows are ignored. |
47/// | Exactly One    | `.fetch_one(...).await`     | `sqlx::Result<{adhoc struct}>`                      | Errors if no rows were returned. Extra rows are ignored. Aggregate queries, use this. |
48/// | At Least One   | `.fetch(...)`               | `impl Stream<Item = sqlx::Result<{adhoc struct}>>`  | Call `.try_next().await` to get each row result. |
49/// | Multiple   | `.fetch_all(...)`               | `sqlx::Result<Vec<{adhoc struct}>>`  | |
50///
51/// \* All methods accept one of `&mut {connection type}`, `&mut Transaction` or `&Pool`.  
52/// † Only callable if the query returns no columns; otherwise it's assumed the query *may* return at least one row.
53/// ## Requirements
54/// * The `DATABASE_URL` environment variable must be set at build-time to point to a database
55///   server with the schema that the query string will be checked against.
56///   All variants of `query!()` use [dotenv]<sup>1</sup> so this can be in a `.env` file instead.
57///
58///     * Or, `.sqlx` must exist at the workspace root. See [Offline Mode](#offline-mode-requires-the-offline-feature)
59///       below.
60///
61/// * The query must be a string literal, or concatenation of string literals using `+` (useful
62///   for queries generated by macro), or else it cannot be introspected (and thus cannot be dynamic
63///   or the result of another macro).
64///
65/// * The `QueryAs` instance will be bound to the same database type as `query!()` was compiled
66///   against (e.g. you cannot build against a Postgres database and then run the query against
67///   a MySQL database).
68///
69///     * The schema of the database URL (e.g. `postgres://` or `mysql://`) will be used to
70///       determine the database type.
71///
72/// <sup>1</sup> The `dotenv` crate itself appears abandoned as of [December 2021](https://github.com/dotenv-rs/dotenv/issues/74)
73/// so we now use the [dotenvy] crate instead. The file format is the same.
74///
75/// [dotenv]: https://crates.io/crates/dotenv
76/// [dotenvy]: https://crates.io/crates/dotenvy
77///
78/// ## Configuration with `sqlx.toml`
79/// Multiple crate-wide configuration options are now available, including:
80///
81/// * change the name of the `DATABASE_URL` variable for using multiple databases in the same workspace
82///     * In the initial implementation, a separate crate must be created for each database.
83///       Using multiple databases in the same crate may become possible in the future.
84/// * global type overrides (useful for custom types!)
85/// * per-column type overrides
86/// * force use of a specific crate (e.g. `chrono` when both it and `time` are enabled)
87///
88/// See the [configuration guide] and [reference `sqlx.toml`] for details.
89///
90/// See also `examples/postgres/multi-database` and `examples/postgres/preferred-crates`
91/// for example usage.
92///
93/// [configuration guide]: crate::_config::macros::Config
94/// [reference `sqlx.toml`]: crate::_config::_reference
95///
96/// ## Query Arguments
97/// Like `println!()` and the other formatting macros, you can add bind parameters to your SQL
98/// and this macro will typecheck passed arguments and error on missing ones:
99///
100/// ```rust,ignore
101/// # use sqlx::Connect;
102/// # #[cfg(all(feature = "mysql", feature = "_rt-async-std"))]
103/// # #[async_std::main]
104/// # async fn main() -> sqlx::Result<()>{
105/// # let db_url = dotenvy::var("DATABASE_URL").expect("DATABASE_URL must be set");
106/// #
107/// # if !(db_url.starts_with("mysql") || db_url.starts_with("mariadb")) { return Ok(()) }
108/// # let mut conn = sqlx::mysql::MySqlConnection::connect(db_url).await?;
109/// // let mut conn = <impl sqlx::Executor>;
110/// let account = sqlx::query!(
111///         // just pretend "accounts" is a real table
112///         "select * from (select (1) as id, 'Herp Derpinson' as name) accounts where id = ?",
113///         1i32
114///     )
115///     .fetch_one(&mut conn)
116///     .await?;
117///
118/// println!("{account:?}");
119/// println!("{}: {}", account.id, account.name);
120/// # Ok(())
121/// # }
122/// #
123/// # #[cfg(any(not(feature = "mysql"), not(feature = "_rt-async-std")))]
124/// # fn main() {}
125/// ```
126///
127/// Bind parameters in the SQL string are specific to the database backend:
128///
129/// * Postgres: `$N` where `N` is the 1-based positional argument index
130/// * MySQL/SQLite: `?` which matches arguments in order that it appears in the query
131///
132/// ## Nullability: Bind Parameters
133/// For a given expected type `T`, both `T` and `Option<T>` are allowed (as well as either
134/// behind references). `Option::None` will be bound as `NULL`, so if binding a type behind `Option`
135/// be sure your query can support it.
136///
137/// Note, however, if binding in a `where` clause, that equality comparisons with `NULL` may not
138/// work as expected; instead you must use `IS NOT NULL` or `IS NULL` to check if a column is not
139/// null or is null, respectively.
140///
141/// In Postgres and MySQL you may also use `IS [NOT] DISTINCT FROM` to compare with a possibly
142/// `NULL` value. In MySQL `IS NOT DISTINCT FROM` can be shortened to `<=>`.
143/// In SQLite you can use `IS` or `IS NOT`. Note that operator precedence may be different.
144///
145/// ## Nullability: Output Columns
146/// In most cases, the database engine can tell us whether or not a column may be `NULL`, and
147/// the `query!()` macro adjusts the field types of the returned struct accordingly.
148///
149/// For Postgres, this only works for columns which come directly from actual tables,
150/// as the implementation will need to query the table metadata to find if a given column
151/// has a `NOT NULL` constraint. Columns that do not have a `NOT NULL` constraint or are the result
152/// of an expression are assumed to be nullable and so `Option<T>` is used instead of `T`.
153///
154/// For MySQL, the implementation looks at [the `NOT_NULL` flag](https://dev.mysql.com/doc/dev/mysql-server/8.0.12/group__group__cs__column__definition__flags.html#ga50377f5ca5b3e92f3931a81fe7b44043)
155/// of [the `ColumnDefinition` structure in `COM_QUERY_OK`](https://dev.mysql.com/doc/internals/en/com-query-response.html#column-definition):
156/// if it is set, `T` is used; if it is not set, `Option<T>` is used.
157///
158/// MySQL appears to be capable of determining the nullability of a result column even if it
159/// is the result of an expression, depending on if the expression may in any case result in
160/// `NULL` which then depends on the semantics of what functions are used. Consult the MySQL
161/// manual for the functions you are using to find the cases in which they return `NULL`.
162///
163/// For SQLite we perform a similar check to Postgres, looking for `NOT NULL` constraints
164/// on columns that come from tables. However, for SQLite we also can step through the output
165/// of `EXPLAIN` to identify columns that may or may not be `NULL`.
166///
167/// To override the nullability of an output column, [see below](#type-overrides-output-columns).
168///
169/// ## Type Overrides: Bind Parameters (Postgres only)
170/// For typechecking of bind parameters, casts using `as` are treated as overrides for the inferred
171/// types of bind parameters and no typechecking is emitted:
172///
173/// ```rust,ignore
174/// #[derive(sqlx::Type)]
175/// #[sqlx(transparent)]
176/// struct MyInt4(i32);
177///
178/// let my_int = MyInt4(1);
179///
180/// sqlx::query!("select $1::int4 as id", my_int as MyInt4)
181/// ```
182///
183/// Using `expr as _` simply signals to the macro to not type-check that bind expression,
184/// and then that syntax is stripped from the expression so as to not trigger type errors.
185///
186/// ## Type Overrides: Output Columns
187/// Type overrides are also available for output columns, utilizing the SQL standard's support
188/// for arbitrary text in column names:
189///
190/// ##### Force Not-Null
191/// Selecting a column `foo as "foo!"` (Postgres / SQLite) or `` foo as `foo!` `` (MySQL) overrides
192/// inferred nullability and forces the column to be treated as `NOT NULL`; this is useful e.g. for
193/// selecting expressions in Postgres where we cannot infer nullability:
194///
195/// ```rust,ignore
196/// # async fn main() {
197/// # let mut conn = panic!();
198/// // Postgres: using a raw query string lets us use unescaped double-quotes
199/// // Note that this query wouldn't work in SQLite as we still don't know the exact type of `id`
200/// let record = sqlx::query!(r#"select 1 as "id!""#) // MySQL: use "select 1 as `id!`" instead
201///     .fetch_one(&mut conn)
202///     .await?;
203///
204/// // For Postgres this would have been inferred to be Option<i32> instead
205/// assert_eq!(record.id, 1i32);
206/// # }
207///
208/// ```
209///
210/// ##### Force Nullable
211/// Selecting a column `foo as "foo?"` (Postgres / SQLite) or `` foo as `foo?` `` (MySQL) overrides
212/// inferred nullability and forces the column to be treated as nullable; this is provided mainly
213/// for symmetry with `!`.
214///
215/// ```rust,ignore
216/// # async fn main() {
217/// # let mut conn = panic!();
218/// // Postgres/SQLite:
219/// let record = sqlx::query!(r#"select 1 as "id?""#) // MySQL: use "select 1 as `id?`" instead
220///     .fetch_one(&mut conn)
221///     .await?;
222///
223/// // For Postgres this would have been inferred to be Option<i32> anyway
224/// // but this is just a basic example
225/// assert_eq!(record.id, Some(1i32));
226/// # }
227/// ```
228///
229/// MySQL should be accurate with regards to nullability as it directly tells us when a column is
230/// expected to never be `NULL`. Any mistakes should be considered a bug in MySQL.
231///
232/// However, inference in SQLite and Postgres is more fragile as it depends primarily on observing
233/// `NOT NULL` constraints on columns. If a `NOT NULL` column is brought in by a `LEFT JOIN` then
234/// that column may be `NULL` if its row does not satisfy the join condition. Similarly, a
235/// `FULL JOIN` or `RIGHT JOIN` may generate rows from the primary table that are all `NULL`.
236///
237/// Unfortunately, the result of mistakes in inference is a `UnexpectedNull` error at runtime.
238///
239/// In Postgres, we patch up this inference by analyzing `EXPLAIN VERBOSE` output (which is not
240/// well documented, is highly dependent on the query plan that Postgres generates, and may differ
241/// between releases) to find columns that are the result of left/right/full outer joins. This
242/// analysis errs on the side of producing false positives (marking columns nullable that are not
243/// in practice) but there are likely edge cases that it does not cover yet.
244///
245/// Using `?` as an override we can fix this for columns we know to be nullable in practice:
246///
247/// ```rust,ignore
248/// # async fn main() {
249/// # let mut conn = panic!();
250/// // Ironically this is the exact column we primarily look at to determine nullability in Postgres
251/// let record = sqlx::query!(
252///     r#"select attnotnull as "attnotnull?" from (values (1)) ids left join pg_attribute on false"#
253/// )
254/// .fetch_one(&mut conn)
255/// .await?;
256///
257/// // Although we do our best, under Postgres this might have been inferred to be `bool`
258/// // In that case, we would have gotten an error
259/// assert_eq!(record.attnotnull, None);
260/// # }
261/// ```
262///
263/// If you find that you need to use this override, please open an issue with a query we can use
264/// to reproduce the problem. For Postgres users, especially helpful would be the output of
265/// `EXPLAIN (VERBOSE, FORMAT JSON) <your query>` with bind parameters substituted in the query
266/// (as the exact value of bind parameters can change the query plan)
267/// and the definitions of any relevant tables (or sufficiently anonymized equivalents).
268///
269/// ##### Force a Different/Custom Type
270/// Selecting a column `foo as "foo: T"` (Postgres / SQLite) or `` foo as `foo: T` `` (MySQL)
271/// overrides the inferred type which is useful when selecting user-defined [custom types][crate::Type#compile-time-verification]
272/// (dynamic type checking is still done so if the types are incompatible this will be an error
273/// at runtime instead of compile-time). Note that this syntax alone doesn't override inferred nullability,
274/// but it is compatible with the forced not-null and forced nullable annotations:
275///
276/// ```rust,ignore
277/// # async fn main() {
278/// # let mut conn = panic!();
279/// #[derive(sqlx::Type)]
280/// #[sqlx(transparent)]
281/// struct MyInt4(i32);
282///
283/// let my_int = MyInt4(1);
284///
285/// // Postgres/SQLite
286/// sqlx::query!(r#"select 1 as "id!: MyInt4""#) // MySQL: use "select 1 as `id: MyInt4`" instead
287///     .fetch_one(&mut conn)
288///     .await?;
289///
290/// // For Postgres this would have been inferred to be `Option<i32>`, MySQL/SQLite `i32`
291/// // Note that while using `id: MyInt4` (without the `!`) would work the same for MySQL/SQLite,
292/// // Postgres would expect `Some(MyInt4(1))` and the code wouldn't compile
293/// assert_eq!(record.id, MyInt4(1));
294/// # }
295/// ```
296///
297/// ##### Overrides cheatsheet
298///
299/// | Syntax    | Nullability     | Type       |
300/// | --------- | --------------- | ---------- |
301/// | `foo!`    | Forced not-null | Inferred   |
302/// | `foo?`    | Forced nullable | Inferred   |
303/// | `foo: T`  | Inferred        | Overridden |
304/// | `foo!: T` | Forced not-null | Overridden |
305/// | `foo?: T` | Forced nullable | Overridden |
306///
307/// ## Offline Mode
308/// The macros can be configured to not require a live database connection for compilation,
309/// but it requires a couple extra steps:
310///
311/// * Run `cargo install sqlx-cli`.
312/// * In your project with `DATABASE_URL` set (or in a `.env` file) and the database server running,
313///   run `cargo sqlx prepare`.
314/// * Check the generated `.sqlx` directory into version control.
315/// * Don't have `DATABASE_URL` set during compilation.
316///
317/// Your project can now be built without a database connection (you must omit `DATABASE_URL` or
318/// else it will still try to connect). To update the generated file simply run `cargo sqlx prepare`
319/// again.
320///
321/// To ensure that your `.sqlx` directory is kept up-to-date, both with the queries in your
322/// project and your database schema itself, run
323/// `cargo install sqlx-cli && cargo sqlx prepare --check` in your Continuous Integration script.
324///
325/// See [the README for `sqlx-cli`](https://crates.io/crates/sqlx-cli) for more information.
326///
327/// ## See Also
328/// * [`query_as!`][`crate::query_as!`] if you want to use a struct you can name,
329/// * [`query_file!`][`crate::query_file!`] if you want to define the SQL query out-of-line,
330/// * [`query_file_as!`][`crate::query_file_as!`] if you want both of the above.
331#[macro_export]
332#[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
333macro_rules! query (
334    // in Rust 1.45 we can now invoke proc macros in expression position
335    ($query:expr) => ({
336        $crate::sqlx_macros::expand_query!(source = $query)
337    });
338    // RFC: this semantically should be `$($args:expr),*` (with `$(,)?` to allow trailing comma)
339    // but that doesn't work in 1.45 because `expr` fragments get wrapped in a way that changes
340    // their hygiene, which is fixed in 1.46 so this is technically just a temp. workaround.
341    // My question is: do we care?
342    // I was hoping using the `expr` fragment might aid code completion but it doesn't in my
343    // experience, at least not with IntelliJ-Rust at the time of writing (version 0.3.126.3220-201)
344    // so really the only benefit is making the macros _slightly_ self-documenting, but it's
345    // not like it makes them magically understandable at-a-glance.
346    ($query:expr, $($args:tt)*) => ({
347        $crate::sqlx_macros::expand_query!(source = $query, args = [$($args)*])
348    })
349);
350
351/// A variant of [`query!`][`crate::query!`] which does not check the input or output types. This still does parse
352/// the query to ensure it's syntactically and semantically valid for the current database.
353#[macro_export]
354#[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
355macro_rules! query_unchecked (
356    ($query:expr) => ({
357        $crate::sqlx_macros::expand_query!(source = $query, checked = false)
358    });
359    ($query:expr, $($args:tt)*) => ({
360        $crate::sqlx_macros::expand_query!(source = $query, args = [$($args)*], checked = false)
361    })
362);
363
364/// A variant of [`query!`][`crate::query!`] where the SQL query is stored in a separate file.
365///
366/// Useful for large queries and potentially cleaner than multiline strings.
367///
368/// The syntax and requirements (see [`query!`][`crate::query!`]) are the same except the SQL
369/// string is replaced by a file path.
370///
371/// The file must be relative to the project root (the directory containing `Cargo.toml`),
372/// unlike `include_str!()` which uses compiler internals to get the path of the file where it
373/// was invoked.
374///
375/// -----
376///
377/// `examples/queries/account-by-id.sql`:
378/// ```text
379/// select * from (select (1) as id, 'Herp Derpinson' as name) accounts
380/// where id = ?
381/// ```
382///
383/// `src/my_query.rs`:
384/// ```rust,ignore
385/// # use sqlx::Connect;
386/// # #[cfg(all(feature = "mysql", feature = "_rt-async-std"))]
387/// # #[async_std::main]
388/// # async fn main() -> sqlx::Result<()>{
389/// # let db_url = dotenvy::var("DATABASE_URL").expect("DATABASE_URL must be set");
390/// #
391/// # if !(db_url.starts_with("mysql") || db_url.starts_with("mariadb")) { return Ok(()) }
392/// # let mut conn = sqlx::MySqlConnection::connect(db_url).await?;
393/// let account = sqlx::query_file!("tests/test-query-account-by-id.sql", 1i32)
394///     .fetch_one(&mut conn)
395///     .await?;
396///
397/// println!("{account:?}");
398/// println!("{}: {}", account.id, account.name);
399///
400/// # Ok(())
401/// # }
402/// #
403/// # #[cfg(any(not(feature = "mysql"), not(feature = "_rt-async-std")))]
404/// # fn main() {}
405/// ```
406#[macro_export]
407#[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
408macro_rules! query_file (
409    ($path:literal) => ({
410        $crate::sqlx_macros::expand_query!(source_file = $path)
411    });
412    ($path:literal, $($args:tt)*) => ({
413        $crate::sqlx_macros::expand_query!(source_file = $path, args = [$($args)*])
414    })
415);
416
417/// A variant of [`query_file!`][`crate::query_file!`] which does not check the input or output
418/// types. This still does parse the query to ensure it's syntactically and semantically valid
419/// for the current database.
420#[macro_export]
421#[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
422macro_rules! query_file_unchecked (
423    ($path:literal) => ({
424        $crate::sqlx_macros::expand_query!(source_file = $path, checked = false)
425    });
426    ($path:literal, $($args:tt)*) => ({
427        $crate::sqlx_macros::expand_query!(source_file = $path, args = [$($args)*], checked = false)
428    })
429);
430
431/// A variant of [`query!`][`crate::query!`] which takes a path to an explicitly defined struct
432/// as the output type.
433///
434/// This lets you return the struct from a function or add your own trait implementations.
435///
436/// **This macro does not use [`FromRow`][crate::FromRow]**; in fact, no trait implementations are
437/// required at all, though this may change in future versions.
438///
439/// The macro maps rows using a struct literal where the names of columns in the query are expected
440/// to be the same as the fields of the struct (but the order does not need to be the same).
441/// The types of the columns are based on the query and not the corresponding fields of the struct,
442/// so this is type-safe as well.
443///
444/// This enforces a few things:
445/// * The query must output at least one column.
446/// * The column names of the query must match the field names of the struct.
447/// * The field types must be the Rust equivalent of their SQL counterparts; see the corresponding
448///   module for your database for mappings:
449///     * Postgres: [crate::postgres::types]
450///     * MySQL: [crate::mysql::types]
451///         * Note: due to wire protocol limitations, the query macros do not know when
452///           a column should be decoded as `bool`. It will be inferred to be `i8` instead.
453///           See the link above for details.
454///     * SQLite: [crate::sqlite::types]
455/// * If a column may be `NULL`, the corresponding field's type must be wrapped in `Option<_>`.
456/// * Neither the query nor the struct may have unused fields.
457///
458/// The only modification to the `query!()` syntax is that the struct name is given before the SQL
459/// string:
460/// ```rust,ignore
461/// # use sqlx::Connect;
462/// # #[cfg(all(feature = "mysql", feature = "_rt-async-std"))]
463/// # #[async_std::main]
464/// # async fn main() -> sqlx::Result<()>{
465/// # let db_url = dotenvy::var("DATABASE_URL").expect("DATABASE_URL must be set");
466/// #
467/// # if !(db_url.starts_with("mysql") || db_url.starts_with("mariadb")) { return Ok(()) }
468/// # let mut conn = sqlx::MySqlConnection::connect(db_url).await?;
469/// #[derive(Debug)]
470/// struct Account {
471///     id: i32,
472///     name: String
473/// }
474///
475/// // let mut conn = <impl sqlx::Executor>;
476/// let account = sqlx::query_as!(
477///         Account,
478///         "select * from (select (1) as id, 'Herp Derpinson' as name) accounts where id = ?",
479///         1i32
480///     )
481///     .fetch_one(&mut conn)
482///     .await?;
483///
484/// println!("{account:?}");
485/// println!("{}: {}", account.id, account.name);
486///
487/// # Ok(())
488/// # }
489/// #
490/// # #[cfg(any(not(feature = "mysql"), not(feature = "_rt-async-std")))]
491/// # fn main() {}
492/// ```
493///
494/// **The method you want to call depends on how many rows you're expecting.**
495///
496/// | Number of Rows | Method to Call*             | Returns (`T` being the given struct)   | Notes |
497/// |----------------| ----------------------------|----------------------------------------|-------|
498/// | Zero or One    | `.fetch_optional(...).await`| `sqlx::Result<Option<T>>`              | Extra rows are ignored. |
499/// | Exactly One    | `.fetch_one(...).await`     | `sqlx::Result<T>`                      | Errors if no rows were returned. Extra rows are ignored. Aggregate queries, use this. |
500/// | At Least One   | `.fetch(...)`               | `impl Stream<Item = sqlx::Result<T>>`  | Call `.try_next().await` to get each row result. |
501/// | Multiple       | `.fetch_all(...)`           | `sqlx::Result<Vec<T>>`  | |
502///
503/// \* All methods accept one of `&mut {connection type}`, `&mut Transaction` or `&Pool`.
504/// (`.execute()` is omitted as this macro requires at least one column to be returned.)
505///
506/// ### Column Type Override: Infer from Struct Field
507/// In addition to the column type overrides supported by [`query!`][`crate::query!`],
508/// [`query_as!()`][`crate::query_as!`] supports an
509/// additional override option:
510///
511/// If you select a column `foo as "foo: _"` (Postgres/SQLite) or `` foo as `foo: _` `` (MySQL)
512/// it causes that column to be inferred based on the type of the corresponding field in the given
513/// record struct. Runtime type-checking is still done so an error will be emitted if the types
514/// are not compatible.
515///
516/// This allows you to override the inferred type of a column to instead use a custom-defined type:
517///
518/// ```rust,ignore
519/// #[derive(sqlx::Type)]
520/// #[sqlx(transparent)]
521/// struct MyInt4(i32);
522///
523/// struct Record {
524///     id: MyInt4,
525/// }
526///
527/// let my_int = MyInt4(1);
528///
529/// // Postgres/SQLite
530/// sqlx::query_as!(Record, r#"select 1 as "id: _""#) // MySQL: use "select 1 as `id: _`" instead
531///     .fetch_one(&mut conn)
532///     .await?;
533///
534/// assert_eq!(record.id, MyInt4(1));
535/// ```
536///
537/// ### Troubleshooting: "error: mismatched types"
538/// If you get a "mismatched types" error from an invocation of this macro and the error
539/// isn't pointing specifically at a parameter.
540///
541/// For example, code like this (using a Postgres database):
542///
543/// ```rust,ignore
544/// struct Account {
545///     id: i32,
546///     name: Option<String>,
547/// }
548///
549/// let account = sqlx::query_as!(
550///     Account,
551///     r#"SELECT id, name from (VALUES (1, 'Herp Derpinson')) accounts(id, name)"#,
552/// )
553///     .fetch_one(&mut conn)
554///     .await?;
555/// ```
556///
557/// Might produce an error like this:
558/// ```text,ignore
559/// error[E0308]: mismatched types
560///    --> tests/postgres/macros.rs:126:19
561///     |
562/// 126 |       let account = sqlx::query_as!(
563///     |  ___________________^
564/// 127 | |         Account,
565/// 128 | |         r#"SELECT id, name from (VALUES (1, 'Herp Derpinson')) accounts(id, name)"#,
566/// 129 | |     )
567///     | |_____^ expected `i32`, found enum `std::option::Option`
568///     |
569///     = note: expected type `i32`
570///                found enum `std::option::Option<i32>`
571/// ```
572///
573/// This means that you need to check that any field of the "expected" type (here, `i32`) matches
574/// the Rust type mapping for its corresponding SQL column (see the `types` module of your database,
575/// listed above, for mappings). The "found" type is the SQL->Rust mapping that the macro chose.
576///
577/// In the above example, the returned column is inferred to be nullable because it's being
578/// returned from a `VALUES` statement in Postgres, so the macro inferred the field to be nullable
579/// and so used `Option<i32>` instead of `i32`. **In this specific case** we could use
580/// `select id as "id!"` to override the inferred nullability because we know in practice
581/// that column will never be `NULL` and it will fix the error.
582///
583/// Nullability inference and type overrides are discussed in detail in the docs for
584/// [`query!`][`crate::query!`].
585///
586/// It unfortunately doesn't appear to be possible right now to make the error specifically mention
587/// the field; this probably requires the `const-panic` feature (still unstable as of Rust 1.45).
588#[macro_export]
589#[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
590macro_rules! query_as (
591    ($out_struct:path, $query:expr) => ( {
592        $crate::sqlx_macros::expand_query!(record = $out_struct, source = $query)
593    });
594    ($out_struct:path, $query:expr, $($args:tt)*) => ( {
595        $crate::sqlx_macros::expand_query!(record = $out_struct, source = $query, args = [$($args)*])
596    })
597);
598
599/// Combines the syntaxes of [`query_as!`][`crate::query_as!`] and [`query_file!`][`crate::query_file!`].
600///
601/// Enforces requirements of both macros; see them for details.
602///
603/// ```rust,ignore
604/// # use sqlx::Connect;
605/// # #[cfg(all(feature = "mysql", feature = "_rt-async-std"))]
606/// # #[async_std::main]
607/// # async fn main() -> sqlx::Result<()>{
608/// # let db_url = dotenvy::var("DATABASE_URL").expect("DATABASE_URL must be set");
609/// #
610/// # if !(db_url.starts_with("mysql") || db_url.starts_with("mariadb")) { return Ok(()) }
611/// # let mut conn = sqlx::MySqlConnection::connect(db_url).await?;
612/// #[derive(Debug)]
613/// struct Account {
614///     id: i32,
615///     name: String
616/// }
617///
618/// // let mut conn = <impl sqlx::Executor>;
619/// let account = sqlx::query_file_as!(Account, "tests/test-query-account-by-id.sql", 1i32)
620///     .fetch_one(&mut conn)
621///     .await?;
622///
623/// println!("{account:?}");
624/// println!("{}: {}", account.id, account.name);
625///
626/// # Ok(())
627/// # }
628/// #
629/// # #[cfg(any(not(feature = "mysql"), not(feature = "_rt-async-std")))]
630/// # fn main() {}
631/// ```
632#[macro_export]
633#[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
634macro_rules! query_file_as (
635    ($out_struct:path, $path:literal) => ( {
636        $crate::sqlx_macros::expand_query!(record = $out_struct, source_file = $path)
637    });
638    ($out_struct:path, $path:literal, $($args:tt)*) => ( {
639        $crate::sqlx_macros::expand_query!(record = $out_struct, source_file = $path, args = [$($args)*])
640    })
641);
642
643/// A variant of [`query_as!`][`crate::query_as!`] which does not check the input or output types. This still does parse
644/// the query to ensure it's syntactically and semantically valid for the current database.
645#[macro_export]
646#[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
647macro_rules! query_as_unchecked (
648    ($out_struct:path, $query:expr) => ( {
649        $crate::sqlx_macros::expand_query!(record = $out_struct, source = $query, checked = false)
650    });
651
652    ($out_struct:path, $query:expr, $($args:tt)*) => ( {
653        $crate::sqlx_macros::expand_query!(record = $out_struct, source = $query, args = [$($args)*], checked = false)
654    })
655);
656
657/// A variant of [`query_file_as!`][`crate::query_file_as!`] which does not check the input or output types. This
658/// still does parse the query to ensure it's syntactically and semantically valid
659/// for the current database.
660#[macro_export]
661#[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
662macro_rules! query_file_as_unchecked (
663    ($out_struct:path, $path:literal) => ( {
664        $crate::sqlx_macros::expand_query!(record = $out_struct, source_file = $path, checked = false)
665    });
666
667    ($out_struct:path, $path:literal, $($args:tt)*) => ( {
668        $crate::sqlx_macros::expand_query!(record = $out_struct, source_file = $path, args = [$($args)*], checked = false)
669    })
670);
671
672/// A variant of [`query!`][`crate::query!`] which expects a single column from the query and evaluates to an
673/// instance of [QueryScalar][crate::query::QueryScalar].
674///
675/// The name of the column is not required to be a valid Rust identifier, however you can still
676/// use the column type override syntax in which case the column name _does_ have to be a valid
677/// Rust identifier for the override to parse properly. If the override parse fails the error
678/// is silently ignored (we just don't have a reliable way to tell the difference). **If you're
679/// getting a different type than expected, please check to see if your override syntax is correct
680/// before opening an issue.**
681///
682/// Wildcard overrides like in [`query_as!`][`crate::query_as!`] are also allowed, in which case the output type
683/// is left up to inference.
684///
685/// See [`query!`][`crate::query!`] for more information.
686#[macro_export]
687#[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
688macro_rules! query_scalar (
689    ($query:expr) => (
690        $crate::sqlx_macros::expand_query!(scalar = _, source = $query)
691    );
692    ($query:expr, $($args:tt)*) => (
693        $crate::sqlx_macros::expand_query!(scalar = _, source = $query, args = [$($args)*])
694    )
695);
696
697/// A variant of [`query_scalar!`][`crate::query_scalar!`] which takes a file path like
698/// [`query_file!`][`crate::query_file!`].
699#[macro_export]
700#[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
701macro_rules! query_file_scalar (
702    ($path:literal) => (
703        $crate::sqlx_macros::expand_query!(scalar = _, source_file = $path)
704    );
705    ($path:literal, $($args:tt)*) => (
706        $crate::sqlx_macros::expand_query!(scalar = _, source_file = $path, args = [$($args)*])
707    )
708);
709
710/// A variant of [`query_scalar!`][`crate::query_scalar!`] which does not typecheck bind parameters
711/// and leaves the output type to inference.
712/// The query itself is still checked that it is syntactically and semantically
713/// valid for the database, that it only produces one column and that the number of bind parameters
714/// is correct.
715///
716/// For this macro variant the name of the column is irrelevant.
717#[macro_export]
718#[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
719macro_rules! query_scalar_unchecked (
720    ($query:expr) => (
721        $crate::sqlx_macros::expand_query!(scalar = _, source = $query, checked = false)
722    );
723    ($query:expr, $($args:tt)*) => (
724        $crate::sqlx_macros::expand_query!(scalar = _, source = $query, args = [$($args)*], checked = false)
725    )
726);
727
728/// A variant of [`query_file_scalar!`][`crate::query_file_scalar!`] which does not typecheck bind
729/// parameters and leaves the output type to inference.
730/// The query itself is still checked that it is syntactically and
731/// semantically valid for the database, that it only produces one column and that the number of
732/// bind parameters is correct.
733///
734/// For this macro variant the name of the column is irrelevant.
735#[macro_export]
736#[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
737macro_rules! query_file_scalar_unchecked (
738    ($path:literal) => (
739        $crate::sqlx_macros::expand_query!(scalar = _, source_file = $path, checked = false)
740    );
741    ($path:literal, $($args:tt)*) => (
742        $crate::sqlx_macros::expand_query!(scalar = _, source_file = $path, args = [$($args)*], checked = false)
743    )
744);
745
746#[allow(clippy::needless_doctest_main)]
747/// Embeds migrations into the binary by expanding to a static instance of [Migrator][crate::migrate::Migrator].
748///
749/// ```rust,ignore
750/// // Consider instead setting
751/// sqlx::migrate!("db/migrations")
752///     .run(&pool)
753///     .await?;
754/// ```
755///
756/// ```rust,ignore
757/// use sqlx::migrate::Migrator;
758///
759/// static MIGRATOR: Migrator = sqlx::migrate!(); // defaults to "./migrations"
760/// ```
761///
762/// The directory must be relative to the project root (the directory containing `Cargo.toml`),
763/// unlike `include_str!()` which uses compiler internals to get the path of the file where it
764/// was invoked.
765///
766/// See [MigrationSource][crate::migrate::MigrationSource] for details on structure of the ./migrations directory.
767///
768/// ## Note: Platform-specific Line Endings
769/// Different platforms use different bytes for line endings by default:
770/// * Linux and MacOS use Line Feeds (LF:`\n`)
771/// * Windows uses Carriage Returns _and_ Line Feeds (CRLF:'\r\n')
772///
773/// This may result in un-reproducible hashes across platforms unless taken into account.
774///
775/// One solution is to use a [`.gitattributes` file](https://git-scm.com/docs/gitattributes)
776/// and force `.sql` files to be checked out with Line Feeds:
777///
778/// ```gitattributes
779/// *.sql text eol=lf
780/// ```
781///
782/// Another option is to configure migrations to ignore whitespace.
783/// See the next section for details.
784///
785/// ## Configuration with `sqlx.toml`
786/// Multiple crate-wide configuration options are now available, including:
787///
788/// * creating schemas on database setup
789/// * renaming the `_sqlx_migrations` table or placing it into a new schema
790/// * relocating the migrations directory
791/// * ignoring characters for hashing (such as whitespace and newlines)
792///
793/// See the [configuration guide] and [reference `sqlx.toml`] for details.
794///
795/// `sqlx-cli` can also read these options and use them when setting up or migrating databases.
796///
797/// [configuration guide]: crate::_config::migrate::Config
798/// [reference `sqlx.toml`]: crate::_config::_reference
799///
800/// ## Triggering Recompilation on Migration Changes
801/// In some cases when making changes to embedded migrations, such as adding a new migration without
802/// changing any Rust source files, you might find that `cargo build` doesn't actually do anything,
803/// or when you do `cargo run` your application isn't applying new migrations on startup.
804///
805/// This is because our ability to tell the compiler to watch external files for changes
806/// from a proc-macro is very limited. The compiler by default only re-runs proc macros when
807/// one or more source files have changed, because normally it shouldn't have to otherwise. SQLx is
808/// just weird in that external factors can change the output of proc macros, much to the chagrin of
809/// the compiler team and IDE plugin authors.
810///
811/// As of 0.5.6, we emit `include_str!()` with an absolute path for each migration, but that
812/// only works to get the compiler to watch _existing_ migration files for changes.
813///
814/// Our only options for telling it to watch the whole `migrations/` directory are either via the
815/// user creating a Cargo build script in their project, or using an unstable API on nightly
816/// governed by a `cfg`-flag.
817///
818/// ##### Stable Rust: Cargo Build Script
819/// The only solution on stable Rust right now is to create a Cargo build script in your project
820/// and have it print `cargo:rerun-if-changed=migrations`:
821///
822/// `build.rs`
823/// ```no_run
824/// fn main() {
825///     println!("cargo:rerun-if-changed=migrations");
826/// }
827/// ```
828///
829/// You can run `sqlx migrate build-script` to generate this file automatically.
830///
831/// See: [The Cargo Book: 3.8 Build Scripts; Outputs of the Build Script](https://doc.rust-lang.org/stable/cargo/reference/build-scripts.html#outputs-of-the-build-script)
832///
833/// #### Nightly Rust: `cfg` Flag
834/// The `migrate!()` macro also listens to `--cfg sqlx_macros_unstable`, which will enable
835/// the `track_path` feature to directly tell the compiler to watch the `migrations/` directory:
836///
837/// ```sh,ignore
838/// $ env RUSTFLAGS='--cfg sqlx_macros_unstable' cargo build
839/// ```
840///
841/// Note that this unfortunately will trigger a fully recompile of your dependency tree, at least
842/// for the first time you use it. It also, of course, requires using a nightly compiler.
843///
844/// You can also set it in `build.rustflags` in `.cargo/config.toml`:
845/// ```toml,ignore
846/// [build]
847/// rustflags = ["--cfg=sqlx_macros_unstable"]
848/// ```
849///
850/// And then continue building and running your project normally.
851///
852/// If you're building on nightly anyways, it would be extremely helpful to help us test
853/// this feature and find any bugs in it.
854///
855/// Subscribe to [the `track_path` tracking issue](https://github.com/rust-lang/rust/issues/73921)
856/// for discussion and the future stabilization of this feature.
857///
858/// For brevity and because it involves the same commitment to unstable features in `proc_macro`,
859/// if you're using `--cfg procmacro2_semver_exempt` it will also enable this feature
860/// (see [`proc-macro2` docs / Unstable Features](https://docs.rs/proc-macro2/1.0.27/proc_macro2/#unstable-features)).
861#[cfg(feature = "migrate")]
862#[macro_export]
863macro_rules! migrate {
864    ($dir:literal) => {{
865        $crate::sqlx_macros::migrate!($dir)
866    }};
867
868    () => {{
869        $crate::sqlx_macros::migrate!()
870    }};
871}