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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
pub use *;
pub use *;
pub use *;
/// Builder states whose query is complete and can be executed.
///
/// Dialect crates implement this for their builder state markers to allow
/// execution, set operations, or prepared statements in those states.
/// The state of a query builder before any statement has been started.
;
// =============================================================================
// Capability marker traits for typestate method gating
// =============================================================================
// These allow a single generic impl block per method instead of duplicating
// across every state that supports it.
//
// Used directly by the inner `SelectBuilder` impls in driver crates.
// Wrapper builders (`DrizzleBuilder`, `TransactionBuilder`) use a declarative
// macro to stamp out per-state impls instead, because Rust's inherent impl
// overlap rules prevent trait-gated generics when other builder types
// (insert/update/delete) define methods with the same name.
/// Clause markers for [`ClauseAllowed`].
///
/// Each marker names a builder method (or a use of a whole query). A builder
/// state implements `ClauseAllowed<clause::X>` when that method may be called
/// next.
/// The builder state `Self` allows the clause `Clause` next.
///
/// SELECT builders track their progress in a state type parameter. Clause
/// methods require `State: ClauseAllowed<clause::X>`, so calling a clause
/// out of order (`.group_by(...)` after `.limit(...)`, `.having(...)`
/// without `.group_by(...)`) is a compile error:
///
/// ```text
/// error[E0277]: builder state `SelectLimitSet` does not allow `drizzle_core::builder::clause::GroupBy`
/// = note: SELECT clauses go in order: FROM, JOIN, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT, OFFSET
/// ```
///
/// The same check stops a statement that is not a SELECT (a
/// `DELETE ... RETURNING`, say) from being used as a subquery, set operand,
/// derived table, or `INSERT ... SELECT` source. Dialect crates implement
/// this for their states and may add their own clause markers for
/// dialect-only clauses. A few methods whose names clash with INSERT /
/// UPDATE / DELETE methods (`.r#where`, `.order_by`) use a dialect-local
/// trait with the same error message instead.
///
/// # Examples
///
/// ```
/// use drizzle_core::{ClauseAllowed, clause};
///
/// struct AfterFrom;
/// impl ClauseAllowed<clause::Where> for AfterFrom {}
///
/// fn where_<S: ClauseAllowed<clause::Where>>(_state: S) {}
///
/// where_(AfterFrom);
/// ```
///
/// ```compile_fail
/// # use drizzle_core::{ClauseAllowed, clause};
/// # struct AfterLimit;
/// fn where_<S: ClauseAllowed<clause::Where>>(_state: S) {}
///
/// // error: builder state `AfterLimit` does not allow `Where`
/// where_(AfterLimit);
/// ```