1 //! AST types representing various typed SQL expressions.
2 //!
3 //! Almost all types implement either [`Expression`](trait.Expression.html) or
4 //! [`AsExpression`](trait.AsExpression.html).
5 //!
6 //! The most common expression to work with is a
7 //! [`Column`](../query_source/trait.Column.html). There are various methods
8 //! that you can call on these, found in
9 //! [`expression_methods`](../expression_methods).
10 //!
11 //! You can also use numeric operators such as `+` on expressions of the
12 //! appropriate type.
13 //!
14 //! Any primitive which implements [`ToSql`](../serialize/trait.ToSql.html) will
15 //! also implement [`AsExpression`](trait.AsExpression.html), allowing it to be
16 //! used as an argument to any of the methods described here.
17 #[macro_use]
18 #[doc(hidden)]
19 pub mod ops;
20 #[doc(hidden)]
21 #[macro_use]
22 pub mod functions;
23 
24 #[doc(hidden)]
25 pub mod array_comparison;
26 #[doc(hidden)]
27 pub mod bound;
28 #[doc(hidden)]
29 pub mod coerce;
30 #[doc(hidden)]
31 pub mod count;
32 #[doc(hidden)]
33 pub mod exists;
34 #[doc(hidden)]
35 pub mod grouped;
36 #[doc(hidden)]
37 pub mod helper_types;
38 mod not;
39 #[doc(hidden)]
40 pub mod nullable;
41 #[doc(hidden)]
42 #[macro_use]
43 pub mod operators;
44 #[doc(hidden)]
45 pub mod sql_literal;
46 #[doc(hidden)]
47 pub mod subselect;
48 
49 #[doc(hidden)]
50 #[allow(non_camel_case_types)]
51 pub mod dsl {
52     use dsl::SqlTypeOf;
53 
54     #[doc(inline)]
55     pub use super::count::*;
56     #[doc(inline)]
57     pub use super::exists::exists;
58     #[doc(inline)]
59     pub use super::functions::aggregate_folding::*;
60     #[doc(inline)]
61     pub use super::functions::aggregate_ordering::*;
62     #[doc(inline)]
63     pub use super::functions::date_and_time::*;
64     #[doc(inline)]
65     pub use super::not::not;
66     #[doc(inline)]
67     pub use super::sql_literal::sql;
68 
69     #[cfg(feature = "postgres")]
70     pub use pg::expression::dsl::*;
71 
72     /// The return type of [`count(expr)`](../dsl/fn.count.html)
73     pub type count<Expr> = super::count::count::HelperType<SqlTypeOf<Expr>, Expr>;
74 
75     /// The return type of [`count_star)(`](../dsl/fn.count_star.html)
76     pub type count_star = super::count::CountStar;
77 
78     /// The return type of [`date(expr)`](../dsl/fn.date.html)
79     pub type date<Expr> = super::functions::date_and_time::date::HelperType<Expr>;
80 }
81 
82 #[doc(inline)]
83 pub use self::sql_literal::{SqlLiteral, UncheckedBind};
84 
85 use backend::Backend;
86 use dsl::AsExprOf;
87 
88 /// Represents a typed fragment of SQL.
89 ///
90 /// Apps should not need to implement this type directly, but it may be common
91 /// to use this in where clauses. Libraries should consider using
92 /// [`diesel_infix_operator!`](../macro.diesel_infix_operator.html) or
93 /// [`diesel_postfix_operator!`](../macro.diesel_postfix_operator.html) instead of
94 /// implementing this directly.
95 pub trait Expression {
96     /// The type that this expression represents in SQL
97     type SqlType;
98 }
99 
100 impl<T: Expression + ?Sized> Expression for Box<T> {
101     type SqlType = T::SqlType;
102 }
103 
104 impl<'a, T: Expression + ?Sized> Expression for &'a T {
105     type SqlType = T::SqlType;
106 }
107 
108 /// Converts a type to its representation for use in Diesel's query builder.
109 ///
110 /// This trait is used directly. Apps should typically use [`IntoSql`] instead.
111 ///
112 /// Implementations of this trait will generally do one of 3 things:
113 ///
114 /// - Return `self` for types which are already parts of Diesel's query builder
115 /// - Perform some implicit coercion (for example, allowing [`now`] to be used as
116 ///   both [`Timestamp`] and [`Timestamptz`].
117 /// - Indicate that the type has data which will be sent separately from the
118 ///   query. This is generally referred as a "bind parameter". Types which
119 ///   implement [`ToSql`] will generally implement `AsExpression` this way.
120 ///
121 ///   [`IntoSql`]: trait.IntoSql.html
122 ///   [`now`]: ../dsl/struct.now.html
123 ///   [`Timestamp`]: ../sql_types/struct.Timestamp.html
124 ///   [`Timestamptz`]: ../pg/types/sql_types/struct.Timestamptz.html
125 ///   [`ToSql`]: ../serialize/trait.ToSql.html
126 ///
127 /// ## Deriving
128 ///
129 /// This trait can be automatically derived for any type which implements `ToSql`.
130 /// The type must be annotated with `#[sql_type = "SomeType"]`.
131 /// If that annotation appears multiple times,
132 /// implementations will be generated for each one of them.
133 ///
134 /// This will generate the following impls:
135 ///
136 /// - `impl AsExpression<SqlType> for YourType`
137 /// - `impl AsExpression<Nullable<SqlType>> for YourType`
138 /// - `impl AsExpression<SqlType> for &'a YourType`
139 /// - `impl AsExpression<Nullable<SqlType>> for &'a YourType`
140 /// - `impl AsExpression<SqlType> for &'a &'b YourType`
141 /// - `impl AsExpression<Nullable<SqlType>> for &'a &'b YourType`
142 ///
143 /// If your type is unsized,
144 /// you can specify this by adding the annotation `#[diesel(not_sized)]`.
145 /// This will skip the impls for non-reference types.
146 pub trait AsExpression<T> {
147     /// The expression being returned
148     type Expression: Expression<SqlType = T>;
149 
150     /// Perform the conversion
as_expression(self) -> Self::Expression151     fn as_expression(self) -> Self::Expression;
152 }
153 
154 impl<T: Expression> AsExpression<T::SqlType> for T {
155     type Expression = Self;
156 
as_expression(self) -> Self157     fn as_expression(self) -> Self {
158         self
159     }
160 }
161 
162 /// Converts a type to its representation for use in Diesel's query builder.
163 ///
164 /// This trait only exists to make usage of `AsExpression` more ergonomic when
165 /// the `SqlType` cannot be inferred. It is generally used when you need to use
166 /// a Rust value as the left hand side of an expression, or when you want to
167 /// select a constant value.
168 ///
169 /// # Example
170 ///
171 /// ```rust
172 /// # #[macro_use] extern crate diesel;
173 /// # include!("../doctest_setup.rs");
174 /// # use schema::users;
175 /// #
176 /// # fn main() {
177 /// use diesel::sql_types::Text;
178 /// #   let conn = establish_connection();
179 /// let names = users::table
180 ///     .select("The Amazing ".into_sql::<Text>().concat(users::name))
181 ///     .load(&conn);
182 /// let expected_names = vec![
183 ///     "The Amazing Sean".to_string(),
184 ///     "The Amazing Tess".to_string(),
185 /// ];
186 /// assert_eq!(Ok(expected_names), names);
187 /// # }
188 /// ```
189 pub trait IntoSql {
190     /// Convert `self` to an expression for Diesel's query builder.
191     ///
192     /// There is no difference in behavior between `x.into_sql::<Y>()` and
193     /// `AsExpression::<Y>::as_expression(x)`.
into_sql<T>(self) -> AsExprOf<Self, T> where Self: AsExpression<T> + Sized,194     fn into_sql<T>(self) -> AsExprOf<Self, T>
195     where
196         Self: AsExpression<T> + Sized,
197     {
198         self.as_expression()
199     }
200 
201     /// Convert `&self` to an expression for Diesel's query builder.
202     ///
203     /// There is no difference in behavior between `x.as_sql::<Y>()` and
204     /// `AsExpression::<Y>::as_expression(&x)`.
as_sql<'a, T>(&'a self) -> AsExprOf<&'a Self, T> where &'a Self: AsExpression<T>,205     fn as_sql<'a, T>(&'a self) -> AsExprOf<&'a Self, T>
206     where
207         &'a Self: AsExpression<T>,
208     {
209         self.as_expression()
210     }
211 }
212 
213 impl<T> IntoSql for T {}
214 
215 /// Indicates that all elements of an expression are valid given a from clause.
216 ///
217 /// This is used to ensure that `users.filter(posts::id.eq(1))` fails to
218 /// compile. This constraint is only used in places where the nullability of a
219 /// SQL type doesn't matter (everything except `select` and `returning`). For
220 /// places where nullability is important, `SelectableExpression` is used
221 /// instead.
222 pub trait AppearsOnTable<QS: ?Sized>: Expression {}
223 
224 impl<T: ?Sized, QS> AppearsOnTable<QS> for Box<T>
225 where
226     T: AppearsOnTable<QS>,
227     Box<T>: Expression,
228 {
229 }
230 
231 impl<'a, T: ?Sized, QS> AppearsOnTable<QS> for &'a T
232 where
233     T: AppearsOnTable<QS>,
234     &'a T: Expression,
235 {
236 }
237 
238 /// Indicates that an expression can be selected from a source.
239 ///
240 /// Columns will implement this for their table. Certain special types, like
241 /// `CountStar` and `Bound` will implement this for all sources. Most compound
242 /// expressions will implement this if each of their parts implement it.
243 ///
244 /// Notably, columns will not implement this trait for the right side of a left
245 /// join. To select a column or expression using a column from the right side of
246 /// a left join, you must call `.nullable()` on it.
247 pub trait SelectableExpression<QS: ?Sized>: AppearsOnTable<QS> {}
248 
249 impl<T: ?Sized, QS> SelectableExpression<QS> for Box<T>
250 where
251     T: SelectableExpression<QS>,
252     Box<T>: AppearsOnTable<QS>,
253 {
254 }
255 
256 impl<'a, T: ?Sized, QS> SelectableExpression<QS> for &'a T
257 where
258     T: SelectableExpression<QS>,
259     &'a T: AppearsOnTable<QS>,
260 {
261 }
262 
263 /// Marker trait to indicate that an expression does not include any aggregate
264 /// functions.
265 ///
266 /// Used to ensure that aggregate expressions aren't mixed with
267 /// non-aggregate expressions in a select clause, and that they're never
268 /// included in a where clause.
269 pub trait NonAggregate {}
270 
271 impl<T: NonAggregate + ?Sized> NonAggregate for Box<T> {}
272 
273 impl<'a, T: NonAggregate + ?Sized> NonAggregate for &'a T {}
274 
275 use query_builder::{QueryFragment, QueryId};
276 
277 /// Helper trait used when boxing expressions.
278 ///
279 /// In Rust you cannot create a trait object with more than one trait.
280 /// This type has all of the additional traits you would want when using
281 /// `Box<Expression>` as a single trait object.
282 ///
283 /// This is typically used as the return type of a function.
284 /// For cases where you want to dynamically construct a query,
285 /// [boxing the query] is usually more ergonomic.
286 ///
287 /// [boxing the query]: ../query_dsl/trait.QueryDsl.html#method.into_boxed
288 ///
289 /// # Examples
290 ///
291 /// ```rust
292 /// # #[macro_use] extern crate diesel;
293 /// # include!("../doctest_setup.rs");
294 /// # use schema::users;
295 /// use diesel::sql_types::Bool;
296 ///
297 /// # fn main() {
298 /// #     run_test().unwrap();
299 /// # }
300 /// #
301 /// # fn run_test() -> QueryResult<()> {
302 /// #     let conn = establish_connection();
303 /// enum Search {
304 ///     Id(i32),
305 ///     Name(String),
306 /// }
307 ///
308 /// # /*
309 /// type DB = diesel::sqlite::Sqlite;
310 /// # */
311 ///
312 /// fn find_user(search: Search) -> Box<BoxableExpression<users::table, DB, SqlType = Bool>> {
313 ///     match search {
314 ///         Search::Id(id) => Box::new(users::id.eq(id)),
315 ///         Search::Name(name) => Box::new(users::name.eq(name)),
316 ///     }
317 /// }
318 ///
319 /// let user_one = users::table
320 ///     .filter(find_user(Search::Id(1)))
321 ///     .first(&conn)?;
322 /// assert_eq!((1, String::from("Sean")), user_one);
323 ///
324 /// let tess = users::table
325 ///     .filter(find_user(Search::Name("Tess".into())))
326 ///     .first(&conn)?;
327 /// assert_eq!((2, String::from("Tess")), tess);
328 /// #     Ok(())
329 /// # }
330 /// ```
331 pub trait BoxableExpression<QS, DB>
332 where
333     DB: Backend,
334     Self: Expression,
335     Self: SelectableExpression<QS>,
336     Self: NonAggregate,
337     Self: QueryFragment<DB>,
338 {
339 }
340 
341 impl<QS, T, DB> BoxableExpression<QS, DB> for T
342 where
343     DB: Backend,
344     T: Expression,
345     T: SelectableExpression<QS>,
346     T: NonAggregate,
347     T: QueryFragment<DB>,
348 {
349 }
350 
351 impl<'a, QS, ST, DB> QueryId for dyn BoxableExpression<QS, DB, SqlType = ST> + 'a {
352     type QueryId = ();
353 
354     const HAS_STATIC_QUERY_ID: bool = false;
355 }
356 
357 /// Converts a tuple of values into a tuple of Diesel expressions.
358 ///
359 /// This trait is similar to [`AsExpression`], but it operates on tuples.
360 /// The expressions must all be of the same SQL type.
361 ///
362 /// [`AsExpression`]: trait.AsExpression.html
363 pub trait AsExpressionList<ST> {
364     /// The final output expression
365     type Expression;
366 
367     /// Perform the conversion
as_expression_list(self) -> Self::Expression368     fn as_expression_list(self) -> Self::Expression;
369 }
370