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