1use std::marker::PhantomData;
2
3use crate::value::{IntoSqlValue, Value};
4
5mod comparison {
6 pub trait Sealed<Rhs> {}
7
8 impl<T> Sealed<T> for T {}
9 impl<T> Sealed<Option<T>> for T {}
10 impl<T> Sealed<T> for Option<T> {}
11}
12
13pub trait SqlComparable<Rhs>: comparison::Sealed<Rhs> {}
16
17impl<T> SqlComparable<T> for T {}
18impl<T> SqlComparable<Option<T>> for T {}
19impl<T> SqlComparable<T> for Option<T> {}
20
21#[derive(Clone, Debug)]
22pub struct SelectSubquery(pub(crate) Box<crate::ast::SelectNode>);
23
24#[derive(Clone, Debug)]
25pub enum Expression {
26 Column {
27 table: &'static str,
28 name: &'static str,
29 },
30 Value(Value),
31 Subquery(SelectSubquery),
32 Function {
33 name: &'static str,
34 arguments: Vec<Expression>,
35 },
36 Coalesce(Vec<Expression>),
37 Least(Vec<Expression>),
38 Cast {
39 expression: Box<Expression>,
40 sql_type: &'static str,
41 },
42 Alias {
43 expression: Box<Expression>,
44 alias: &'static str,
45 },
46 Wildcard,
47 Window {
48 expression: Box<Expression>,
49 partition_by: Vec<Expression>,
50 order_by: Vec<(Expression, OrderDirection)>,
51 frame: Option<WindowFrame>,
52 },
53 Binary {
54 left: Box<Expression>,
55 operator: BinaryOperator,
56 right: Box<Expression>,
57 },
58 Unary {
59 operator: UnaryOperator,
60 expression: Box<Expression>,
61 },
62 And(Vec<Expression>),
63 Or(Vec<Expression>),
64}
65
66impl Expression {
67 pub fn and(self, other: Expression) -> Self {
68 match self {
69 Self::And(mut expressions) => {
70 expressions.push(other);
71 Self::And(expressions)
72 }
73 expression => Self::And(vec![expression, other]),
74 }
75 }
76
77 pub fn or(self, other: Expression) -> Self {
78 match self {
79 Self::Or(mut expressions) => {
80 expressions.push(other);
81 Self::Or(expressions)
82 }
83 expression => Self::Or(vec![expression, other]),
84 }
85 }
86}
87
88pub fn not(expression: Expression) -> Expression {
90 Expression::Unary {
91 operator: UnaryOperator::Not,
92 expression: Box::new(expression),
93 }
94}
95
96#[derive(Clone, Copy, Debug)]
97pub enum BinaryOperator {
98 Eq,
99 NotEq,
100 GreaterThan,
101 GreaterThanOrEq,
102 LessThan,
103 LessThanOrEq,
104 Like,
105 In,
106 Is,
107 IsNot,
108}
109
110#[derive(Clone, Copy, Debug)]
111pub enum UnaryOperator {
112 IsNull,
113 IsNotNull,
114 Not,
115 Exists,
116}
117
118#[derive(Clone, Copy, Debug, PartialEq, Eq)]
119pub enum OrderDirection {
120 Asc,
121 Desc,
122}
123
124#[derive(Clone, Copy, Debug, PartialEq, Eq)]
125pub enum WindowFrameUnits {
126 Rows,
127 Range,
128 Groups,
129}
130
131#[derive(Clone, Copy, Debug, PartialEq, Eq)]
132pub enum WindowBoundary {
133 UnboundedPreceding,
134 Preceding(u64),
135 CurrentRow,
136 Following(u64),
137 UnboundedFollowing,
138}
139
140#[derive(Clone, Copy, Debug, PartialEq, Eq)]
141pub struct WindowFrame {
142 pub units: WindowFrameUnits,
143 pub start: WindowBoundary,
144 pub end: WindowBoundary,
145}
146
147#[derive(Debug)]
148pub struct Column<T, V> {
149 table: &'static str,
150 name: &'static str,
151 marker: PhantomData<fn() -> (T, V)>,
152}
153
154impl<T, V> Clone for Column<T, V> {
155 fn clone(&self) -> Self {
156 *self
157 }
158}
159
160impl<T, V> Copy for Column<T, V> {}
161
162impl<T, V> Column<T, V> {
163 pub const fn new(table: &'static str, name: &'static str) -> Self {
164 Self {
165 table,
166 name,
167 marker: PhantomData,
168 }
169 }
170
171 pub const fn table_name(self) -> &'static str {
172 self.table
173 }
174
175 pub const fn name(self) -> &'static str {
176 self.name
177 }
178
179 pub fn expression(self) -> Expression {
180 Expression::Column {
181 table: self.table,
182 name: self.name,
183 }
184 }
185
186 pub fn eq(self, value: impl IntoSqlValue<V>) -> Expression {
187 self.compare(
188 BinaryOperator::Eq,
189 Expression::Value(value.into_sql_value()),
190 )
191 }
192
193 pub fn ne(self, value: impl IntoSqlValue<V>) -> Expression {
194 self.compare(
195 BinaryOperator::NotEq,
196 Expression::Value(value.into_sql_value()),
197 )
198 }
199
200 pub fn gt(self, value: impl IntoSqlValue<V>) -> Expression {
201 self.compare(
202 BinaryOperator::GreaterThan,
203 Expression::Value(value.into_sql_value()),
204 )
205 }
206
207 pub fn gte(self, value: impl IntoSqlValue<V>) -> Expression {
208 self.compare(
209 BinaryOperator::GreaterThanOrEq,
210 Expression::Value(value.into_sql_value()),
211 )
212 }
213
214 pub fn lt(self, value: impl IntoSqlValue<V>) -> Expression {
215 self.compare(
216 BinaryOperator::LessThan,
217 Expression::Value(value.into_sql_value()),
218 )
219 }
220
221 pub fn lte(self, value: impl IntoSqlValue<V>) -> Expression {
222 self.compare(
223 BinaryOperator::LessThanOrEq,
224 Expression::Value(value.into_sql_value()),
225 )
226 }
227
228 pub fn like(self, value: impl IntoSqlValue<V>) -> Expression {
229 self.compare(
230 BinaryOperator::Like,
231 Expression::Value(value.into_sql_value()),
232 )
233 }
234
235 pub fn eq_column<OtherTable, OtherValue>(
236 self,
237 other: Column<OtherTable, OtherValue>,
238 ) -> Expression
239 where
240 V: SqlComparable<OtherValue>,
241 {
242 self.compare(BinaryOperator::Eq, other.expression())
243 }
244
245 pub fn ne_column<OtherTable, OtherValue>(
246 self,
247 other: Column<OtherTable, OtherValue>,
248 ) -> Expression
249 where
250 V: SqlComparable<OtherValue>,
251 {
252 self.compare(BinaryOperator::NotEq, other.expression())
253 }
254
255 pub fn gt_column<OtherTable, OtherValue>(
256 self,
257 other: Column<OtherTable, OtherValue>,
258 ) -> Expression
259 where
260 V: SqlComparable<OtherValue>,
261 {
262 self.compare(BinaryOperator::GreaterThan, other.expression())
263 }
264
265 pub fn gte_column<OtherTable, OtherValue>(
266 self,
267 other: Column<OtherTable, OtherValue>,
268 ) -> Expression
269 where
270 V: SqlComparable<OtherValue>,
271 {
272 self.compare(BinaryOperator::GreaterThanOrEq, other.expression())
273 }
274
275 pub fn lt_column<OtherTable, OtherValue>(
276 self,
277 other: Column<OtherTable, OtherValue>,
278 ) -> Expression
279 where
280 V: SqlComparable<OtherValue>,
281 {
282 self.compare(BinaryOperator::LessThan, other.expression())
283 }
284
285 pub fn lte_column<OtherTable, OtherValue>(
286 self,
287 other: Column<OtherTable, OtherValue>,
288 ) -> Expression
289 where
290 V: SqlComparable<OtherValue>,
291 {
292 self.compare(BinaryOperator::LessThanOrEq, other.expression())
293 }
294
295 pub fn eq_subquery<Source: crate::Table>(
296 self,
297 query: crate::query::SelectQuery<Source, V>,
298 ) -> Expression {
299 self.compare(
300 BinaryOperator::Eq,
301 Expression::Subquery(SelectSubquery(Box::new(query.into_node()))),
302 )
303 }
304
305 pub fn in_subquery<Source: crate::Table>(
306 self,
307 query: crate::query::SelectQuery<Source, V>,
308 ) -> Expression {
309 self.compare(
310 BinaryOperator::In,
311 Expression::Subquery(SelectSubquery(Box::new(query.into_node()))),
312 )
313 }
314
315 pub fn is_null(self) -> Expression {
316 Expression::Unary {
317 operator: UnaryOperator::IsNull,
318 expression: Box::new(self.expression()),
319 }
320 }
321
322 pub fn is_not_null(self) -> Expression {
323 Expression::Unary {
324 operator: UnaryOperator::IsNotNull,
325 expression: Box::new(self.expression()),
326 }
327 }
328
329 fn compare(self, operator: BinaryOperator, right: Expression) -> Expression {
330 Expression::Binary {
331 left: Box::new(self.expression()),
332 operator,
333 right: Box::new(right),
334 }
335 }
336}
337
338pub fn exists<Source: crate::Table, Output>(
339 query: crate::query::SelectQuery<Source, Output>,
340) -> Expression {
341 Expression::Unary {
342 operator: UnaryOperator::Exists,
343 expression: Box::new(Expression::Subquery(SelectSubquery(Box::new(
344 query.into_node(),
345 )))),
346 }
347}
348
349pub trait Selection {
350 type Output;
351 fn expressions(self) -> Vec<Expression>;
352}
353
354pub struct AliasedSelection<S> {
355 selection: S,
356 alias: &'static str,
357}
358
359pub trait SelectionExt: Selection + Sized {
360 fn alias(self, alias: &'static str) -> AliasedSelection<Self> {
361 AliasedSelection {
362 selection: self,
363 alias,
364 }
365 }
366}
367
368impl<T, V> SelectionExt for Column<T, V> {}
369
370impl<S: Selection> Selection for AliasedSelection<S> {
371 type Output = S::Output;
372
373 fn expressions(self) -> Vec<Expression> {
374 self.selection
375 .expressions()
376 .into_iter()
377 .map(|expression| Expression::Alias {
378 expression: Box::new(expression),
379 alias: self.alias,
380 })
381 .collect()
382 }
383}
384
385impl<T, V> Selection for Column<T, V> {
386 type Output = V;
387
388 fn expressions(self) -> Vec<Expression> {
389 vec![self.expression()]
390 }
391}
392
393macro_rules! tuple_selection {
394 ($($name:ident),+ $(,)?) => {
395 impl<$($name),+> Selection for ($($name,)+)
396 where
397 $($name: Selection,)+
398 {
399 type Output = ($($name::Output,)+);
400
401 #[allow(non_snake_case)]
402 fn expressions(self) -> Vec<Expression> {
403 let ($($name,)+) = self;
404 let mut expressions = Vec::new();
405 $(expressions.extend($name.expressions());)+
406 expressions
407 }
408 }
409 };
410}
411
412tuple_selection!(A, B);
413tuple_selection!(A, B, C);
414tuple_selection!(A, B, C, D);
415tuple_selection!(A, B, C, D, E);
416tuple_selection!(A, B, C, D, E, F);
417tuple_selection!(A, B, C, D, E, F, G);
418tuple_selection!(A, B, C, D, E, F, G, H);