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 {}