1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
//! The `sql!{}` escape hatch: a pressure valve for SQL constructs the typed
//! builder doesn't cover yet.
//!
//! A `?` slot takes a value, which binds as a parameter, or an expression
//! (a column, an aggregate, another fragment), which the renderer writes out
//! itself. A column slot is quoted by the same code that quotes it anywhere
//! else and carries its table into the fragment's `Req`, so
//! `sql!(Numeric, "sum(?)", invoices::amount)` is checked against the
//! query's scope like any other expression. Only the text between the slots
//! is unchecked.
//!
//! One fragment reused across clauses of one statement (selected, grouped
//! by, ordered by) renders as one expression, which is what Postgres's
//! syntactic `GROUP BY` matching asks for. Under Postgres its binds are
//! named again rather than bound again, since `$N` names a parameter. Under
//! MySQL and SQLite `?` *is* the next parameter, so the occurrences read
//! alike and each rebinds, and the statement carries one parameter per
//! occurrence.
//!
//! `sql!` binds that text to a `const` first, so text assembled at runtime
//! cannot reach SQL through this macro. The primitive it expands to,
//! `expr::raw_expr`, takes a bare `&'static str` and has no such guard, so
//! `String::leak` reaches it. It is `#[doc(hidden)]` because `sql!` is the
//! door; a caller who walks around it is writing the unchecked SQL
//! themselves. Every `?` in the text is a slot; a literal `?` belongs in a
//! slot's value, since MySQL and SQLite spell their own bind parameters the
//! same way.
/// `sql!(Bool, "lower(?) = ?", users::email, "dan")` -> a `Declared`
/// expression over whatever tables its slots name. It is keyed as
/// `row::Anon`, so it is selectable but not readable by name until
/// `.label(..)`. Slots are filled positionally, left to right.
///
/// Every `?` in the text is a slot: there is no escape for a literal one,
/// because two of the three dialects write their own bind parameters as `?`
/// and a `?` left in the text would be read as one. A string containing a
/// `?` goes in a slot, where it binds as a value; Postgres's `jsonb`
/// operators are reached through their function spellings
/// (`jsonb_exists(?, 'key')`).