diesel/expression_methods/
global_expression_methods.rs

1use expression::array_comparison::{AsInExpression, In, NotIn};
2use expression::operators::*;
3use expression::{nullable, AsExpression, Expression};
4use sql_types::SingleValue;
5
6/// Methods present on all expressions, except tuples
7pub trait ExpressionMethods: Expression + Sized {
8    /// Creates a SQL `=` expression.
9    ///
10    /// # Example
11    ///
12    /// ```rust
13    /// # #[macro_use] extern crate diesel;
14    /// # include!("../doctest_setup.rs");
15    /// #
16    /// # fn main() {
17    /// #     use schema::users::dsl::*;
18    /// #     let connection = establish_connection();
19    /// let data = users.select(id).filter(name.eq("Sean"));
20    /// assert_eq!(Ok(1), data.first(&connection));
21    /// # }
22    /// ```
23    fn eq<T: AsExpression<Self::SqlType>>(self, other: T) -> Eq<Self, T::Expression> {
24        Eq::new(self, other.as_expression())
25    }
26
27    /// Creates a SQL `!=` expression.
28    ///
29    /// # Example
30    ///
31    /// ```rust
32    /// # #[macro_use] extern crate diesel;
33    /// # include!("../doctest_setup.rs");
34    /// #
35    /// # fn main() {
36    /// #     use schema::users::dsl::*;
37    /// #     let connection = establish_connection();
38    /// let data = users.select(id).filter(name.ne("Sean"));
39    /// assert_eq!(Ok(2), data.first(&connection));
40    /// # }
41    /// ```
42    fn ne<T: AsExpression<Self::SqlType>>(self, other: T) -> NotEq<Self, T::Expression> {
43        NotEq::new(self, other.as_expression())
44    }
45
46    /// Creates a SQL `IN` statement.
47    ///
48    /// Queries using this method will not be
49    /// placed in the prepared statement cache. On PostgreSQL, you should use
50    /// `eq(any())` instead. This method may change in the future to
51    /// automatically perform `= ANY` on PostgreSQL.
52    ///
53    /// # Example
54    ///
55    /// ```rust
56    /// # #[macro_use] extern crate diesel;
57    /// # include!("../doctest_setup.rs");
58    /// #
59    /// # fn main() {
60    /// #     use schema::users::dsl::*;
61    /// #     let connection = establish_connection();
62    /// #     connection.execute("INSERT INTO users (name) VALUES
63    /// #         ('Jim')").unwrap();
64    /// let data = users.select(id).filter(name.eq_any(vec!["Sean", "Jim"]));
65    /// assert_eq!(Ok(vec![1, 3]), data.load(&connection));
66    ///
67    /// // Calling `eq_any` with an empty array is the same as doing `WHERE 1=0`
68    /// let data = users.select(id).filter(name.eq_any(Vec::<String>::new()));
69    /// assert_eq!(Ok(vec![]), data.load::<i32>(&connection));
70    /// # }
71    /// ```
72    fn eq_any<T>(self, values: T) -> In<Self, T::InExpression>
73    where
74        T: AsInExpression<Self::SqlType>,
75    {
76        In::new(self, values.as_in_expression())
77    }
78
79    /// Deprecated alias for `ne_all`
80    ///
81    /// ```rust
82    /// # #[macro_use] extern crate diesel;
83    /// # include!("../doctest_setup.rs");
84    /// #
85    /// # fn main() {
86    /// #     use schema::users::dsl::*;
87    /// #     let connection = establish_connection();
88    /// #     connection.execute("INSERT INTO users (name) VALUES
89    /// #         ('Jim')").unwrap();
90    /// let data = users.select(id).filter(name.ne_any(vec!["Sean", "Jim"]));
91    /// assert_eq!(Ok(vec![2]), data.load(&connection));
92    ///
93    /// let data = users.select(id).filter(name.ne_any(vec!["Tess"]));
94    /// assert_eq!(Ok(vec![1, 3]), data.load(&connection));
95    ///
96    /// // Calling `ne_any` with an empty array is the same as doing `WHERE 1=1`
97    /// let data = users.select(id).filter(name.ne_any(Vec::<String>::new()));
98    /// assert_eq!(Ok(vec![1, 2, 3]), data.load(&connection));
99    /// # }
100    /// ```
101    #[cfg(feature = "with-deprecated")]
102    #[deprecated(since = "1.2.0", note = "use `ne_all` instead")]
103    fn ne_any<T>(self, values: T) -> NotIn<Self, T::InExpression>
104    where
105        T: AsInExpression<Self::SqlType>,
106    {
107        NotIn::new(self, values.as_in_expression())
108    }
109
110    /// Creates a SQL `NOT IN` statement.
111    ///
112    /// Queries using this method will not be
113    /// placed in the prepared statement cache. On PostgreSQL, you should use
114    /// `ne(all())` instead. This method may change in the future to
115    /// automatically perform `!= ALL` on PostgreSQL.
116    ///
117    /// # Example
118    ///
119    /// ```rust
120    /// # #[macro_use] extern crate diesel;
121    /// # include!("../doctest_setup.rs");
122    /// #
123    /// # fn main() {
124    /// #     use schema::users::dsl::*;
125    /// #     let connection = establish_connection();
126    /// #     connection.execute("INSERT INTO users (name) VALUES
127    /// #         ('Jim')").unwrap();
128    /// let data = users.select(id).filter(name.ne_all(vec!["Sean", "Jim"]));
129    /// assert_eq!(Ok(vec![2]), data.load(&connection));
130    ///
131    /// let data = users.select(id).filter(name.ne_all(vec!["Tess"]));
132    /// assert_eq!(Ok(vec![1, 3]), data.load(&connection));
133    ///
134    /// // Calling `ne_any` with an empty array is the same as doing `WHERE 1=1`
135    /// let data = users.select(id).filter(name.ne_all(Vec::<String>::new()));
136    /// assert_eq!(Ok(vec![1, 2, 3]), data.load(&connection));
137    /// # }
138    /// ```
139    fn ne_all<T>(self, values: T) -> NotIn<Self, T::InExpression>
140    where
141        T: AsInExpression<Self::SqlType>,
142    {
143        NotIn::new(self, values.as_in_expression())
144    }
145
146    /// Creates a SQL `IS NULL` expression.
147    ///
148    /// # Example
149    ///
150    /// ```rust
151    /// # #[macro_use] extern crate diesel;
152    /// # include!("../doctest_setup.rs");
153    /// #
154    /// # fn main() {
155    /// #     run_test().unwrap();
156    /// # }
157    /// #
158    /// # fn run_test() -> QueryResult<()> {
159    /// #     use schema::animals::dsl::*;
160    /// #     let connection = establish_connection();
161    /// #
162    /// let data = animals
163    ///     .select(species)
164    ///     .filter(name.is_null())
165    ///     .first::<String>(&connection)?;
166    /// assert_eq!("spider", data);
167    /// #     Ok(())
168    /// # }
169    fn is_null(self) -> IsNull<Self> {
170        IsNull::new(self)
171    }
172
173    /// Creates a SQL `IS NOT NULL` expression.
174    ///
175    /// # Example
176    ///
177    /// ```rust
178    /// # #[macro_use] extern crate diesel;
179    /// # include!("../doctest_setup.rs");
180    /// #
181    /// # fn main() {
182    /// #     run_test().unwrap();
183    /// # }
184    /// #
185    /// # fn run_test() -> QueryResult<()> {
186    /// #     use schema::animals::dsl::*;
187    /// #     let connection = establish_connection();
188    /// #
189    /// let data = animals
190    ///     .select(species)
191    ///     .filter(name.is_not_null())
192    ///     .first::<String>(&connection)?;
193    /// assert_eq!("dog", data);
194    /// #     Ok(())
195    /// # }
196    fn is_not_null(self) -> IsNotNull<Self> {
197        IsNotNull::new(self)
198    }
199
200    /// Creates a SQL `>` expression.
201    ///
202    /// # Example
203    ///
204    /// ```rust
205    /// # #[macro_use] extern crate diesel;
206    /// # include!("../doctest_setup.rs");
207    /// #
208    /// # fn main() {
209    /// #     run_test().unwrap();
210    /// # }
211    /// #
212    /// # fn run_test() -> QueryResult<()> {
213    /// #     use schema::users::dsl::*;
214    /// #     let connection = establish_connection();
215    /// let data = users
216    ///     .select(name)
217    ///     .filter(id.gt(1))
218    ///     .first::<String>(&connection)?;
219    /// assert_eq!("Tess", data);
220    /// #     Ok(())
221    /// # }
222    /// ```
223    fn gt<T: AsExpression<Self::SqlType>>(self, other: T) -> Gt<Self, T::Expression> {
224        Gt::new(self, other.as_expression())
225    }
226
227    /// Creates a SQL `>=` expression.
228    ///
229    /// # Example
230    ///
231    /// ```rust
232    /// # #[macro_use] extern crate diesel;
233    /// # include!("../doctest_setup.rs");
234    /// #
235    /// # fn main() {
236    /// #     run_test().unwrap();
237    /// # }
238    /// #
239    /// # fn run_test() -> QueryResult<()> {
240    /// #     use schema::users::dsl::*;
241    /// #     let connection = establish_connection();
242    /// let data = users
243    ///     .select(name)
244    ///     .filter(id.ge(2))
245    ///     .first::<String>(&connection)?;
246    /// assert_eq!("Tess", data);
247    /// #     Ok(())
248    /// # }
249    /// ```
250    fn ge<T: AsExpression<Self::SqlType>>(self, other: T) -> GtEq<Self, T::Expression> {
251        GtEq::new(self, other.as_expression())
252    }
253
254    /// Creates a SQL `<` expression.
255    ///
256    /// # Example
257    ///
258    /// ```rust
259    /// # #[macro_use] extern crate diesel;
260    /// # include!("../doctest_setup.rs");
261    /// #
262    /// # fn main() {
263    /// #     run_test().unwrap();
264    /// # }
265    /// #
266    /// # fn run_test() -> QueryResult<()> {
267    /// #     use schema::users::dsl::*;
268    /// #     let connection = establish_connection();
269    /// let data = users
270    ///     .select(name)
271    ///     .filter(id.lt(2))
272    ///     .first::<String>(&connection)?;
273    /// assert_eq!("Sean", data);
274    /// #     Ok(())
275    /// # }
276    /// ```
277    fn lt<T: AsExpression<Self::SqlType>>(self, other: T) -> Lt<Self, T::Expression> {
278        Lt::new(self, other.as_expression())
279    }
280
281    /// Creates a SQL `<=` expression.
282    ///
283    /// # Example
284    ///
285    /// ```rust
286    /// # #[macro_use] extern crate diesel;
287    /// # include!("../doctest_setup.rs");
288    /// #
289    /// # fn main() {
290    /// #     run_test().unwrap();
291    /// # }
292    /// #
293    /// # fn run_test() -> QueryResult<()> {
294    /// #     use schema::users::dsl::*;
295    /// #     let connection = establish_connection();
296    /// let data = users
297    ///     .select(name)
298    ///     .filter(id.le(2))
299    ///     .first::<String>(&connection)?;
300    /// assert_eq!("Sean", data);
301    /// #     Ok(())
302    /// # }
303    fn le<T: AsExpression<Self::SqlType>>(self, other: T) -> LtEq<Self, T::Expression> {
304        LtEq::new(self, other.as_expression())
305    }
306
307    /// Creates a SQL `BETWEEN` expression using the given lower and upper
308    /// bounds.
309    ///
310    /// # Example
311    ///
312    /// ```rust
313    /// # #[macro_use] extern crate diesel;
314    /// # include!("../doctest_setup.rs");
315    /// #
316    /// # fn main() {
317    /// #     use schema::animals::dsl::*;
318    /// #     let connection = establish_connection();
319    /// #
320    /// let data = animals
321    ///     .select(species)
322    ///     .filter(legs.between(2, 6))
323    ///     .first(&connection);
324    /// #
325    /// assert_eq!(Ok("dog".to_string()), data);
326    /// # }
327    /// ```
328    fn between<T, U>(self, lower: T, upper: U) -> Between<Self, And<T::Expression, U::Expression>>
329    where
330        T: AsExpression<Self::SqlType>,
331        U: AsExpression<Self::SqlType>,
332    {
333        Between::new(self, And::new(lower.as_expression(), upper.as_expression()))
334    }
335
336    /// Creates a SQL `NOT BETWEEN` expression using the given lower and upper
337    /// bounds.
338    ///
339    /// # Example
340    ///
341    /// ```rust
342    /// # #[macro_use] extern crate diesel;
343    /// # include!("../doctest_setup.rs");
344    /// #
345    /// # fn main() {
346    /// #     run_test().unwrap();
347    /// # }
348    /// #
349    /// # fn run_test() -> QueryResult<()> {
350    /// #     use schema::animals::dsl::*;
351    /// #     let connection = establish_connection();
352    /// #
353    /// let data = animals
354    ///     .select(species)
355    ///     .filter(legs.not_between(2, 6))
356    ///     .first::<String>(&connection)?;
357    /// assert_eq!("spider", data);
358    /// #     Ok(())
359    /// # }
360    fn not_between<T, U>(
361        self,
362        lower: T,
363        upper: U,
364    ) -> NotBetween<Self, And<T::Expression, U::Expression>>
365    where
366        T: AsExpression<Self::SqlType>,
367        U: AsExpression<Self::SqlType>,
368    {
369        NotBetween::new(self, And::new(lower.as_expression(), upper.as_expression()))
370    }
371
372    /// Creates a SQL `DESC` expression, representing this expression in
373    /// descending order.
374    ///
375    /// # Example
376    ///
377    /// ```rust
378    /// # #[macro_use] extern crate diesel;
379    /// # include!("../doctest_setup.rs");
380    /// #
381    /// # fn main() {
382    /// #     run_test().unwrap();
383    /// # }
384    /// #
385    /// # fn run_test() -> QueryResult<()> {
386    /// #     use schema::users::dsl::*;
387    /// #     let connection = establish_connection();
388    /// #
389    /// let names = users
390    ///     .select(name)
391    ///     .order(name.desc())
392    ///     .load::<String>(&connection)?;
393    /// assert_eq!(vec!["Tess", "Sean"], names);
394    /// #     Ok(())
395    /// # }
396    /// ```
397    fn desc(self) -> Desc<Self> {
398        Desc::new(self)
399    }
400
401    /// Creates a SQL `ASC` expression, representing this expression in
402    /// ascending order.
403    ///
404    /// This is the same as leaving the direction unspecified. It is useful if
405    /// you need to provide an unknown ordering, and need to box the return
406    /// value of a function.
407    ///
408    /// # Example
409    ///
410    /// ```rust
411    /// # #[macro_use] extern crate diesel;
412    /// # include!("../doctest_setup.rs");
413    /// #
414    /// # fn main() {
415    /// #     use schema::users::dsl::*;
416    /// #     let order = "name";
417    /// let ordering: Box<BoxableExpression<users, DB, SqlType=()>> =
418    ///     if order == "name" {
419    ///         Box::new(name.desc())
420    ///     } else {
421    ///         Box::new(id.asc())
422    ///     };
423    /// # }
424    /// ```
425    fn asc(self) -> Asc<Self> {
426        Asc::new(self)
427    }
428}
429
430impl<T> ExpressionMethods for T
431where
432    T: Expression,
433    T::SqlType: SingleValue,
434{
435}
436
437/// Methods present on all expressions
438pub trait NullableExpressionMethods: Expression + Sized {
439    /// Converts this potentially non-null expression into one which is treated
440    /// as nullable. This method has no impact on the generated SQL, and is only
441    /// used to allow certain comparisons that would otherwise fail to compile.
442    ///
443    /// # Example
444    /// ```no_run
445    /// # #![allow(dead_code)]
446    /// # #[macro_use] extern crate diesel;
447    /// # include!("../doctest_setup.rs");
448    /// # use diesel::sql_types::*;
449    /// # use schema::users;
450    /// #
451    /// table! {
452    ///     posts {
453    ///         id -> Integer,
454    ///         user_id -> Integer,
455    ///         author_name -> Nullable<VarChar>,
456    ///     }
457    /// }
458    /// #
459    /// # joinable!(posts -> users (user_id));
460    /// # allow_tables_to_appear_in_same_query!(posts, users);
461    ///
462    /// fn main() {
463    ///     use self::users::dsl::*;
464    ///     use self::posts::dsl::{posts, author_name};
465    ///     let connection = establish_connection();
466    ///
467    ///     let data = users.inner_join(posts)
468    ///         .filter(name.nullable().eq(author_name))
469    ///         .select(name)
470    ///         .load::<String>(&connection);
471    ///     println!("{:?}", data);
472    /// }
473    /// ```
474    fn nullable(self) -> nullable::Nullable<Self> {
475        nullable::Nullable::new(self)
476    }
477}
478
479impl<T: Expression> NullableExpressionMethods for T {}