diesel/expression_methods/global_expression_methods.rs
1use crate::dsl;
2use crate::expression::array_comparison::{AsInExpression, In, NotIn};
3use crate::expression::grouped::Grouped;
4use crate::expression::operators::*;
5use crate::expression::{AsExpression, Expression, assume_not_null, cast, nullable};
6use crate::sql_types::{SingleValue, SqlType, Untyped};
7
8/// Methods present on all expressions, except tuples
9pub trait ExpressionMethods: Expression + Sized {
10 /// Creates a SQL `=` expression.
11 ///
12 /// Note that this function follows SQL semantics around `None`/`null` values,
13 /// so `eq(None)` will never match. Use [`is_null`](ExpressionMethods::is_null()) instead.
14 ///
15 #[cfg_attr(
16 any(feature = "__sqlite-shared", feature = "postgres"),
17 doc = "To get behavior that is more like the Rust `=` operator you can also use the"
18 )]
19 #[cfg_attr(
20 feature = "__sqlite-shared",
21 doc = "sqlite-specific [`is`](crate::SqliteExpressionMethods::is())"
22 )]
23 #[cfg_attr(all(feature = "__sqlite-shared", feature = "postgres"), doc = "or the")]
24 #[cfg_attr(
25 feature = "postgres",
26 doc = "postgres-specific [`is_not_distinct_from`](crate::PgExpressionMethods::is_not_distinct_from())"
27 )]
28 #[cfg_attr(any(feature = "__sqlite-shared", feature = "postgres"), doc = ".")]
29 ///
30 /// # Example
31 ///
32 /// ```rust
33 /// # include!("../doctest_setup.rs");
34 /// #
35 /// # fn main() {
36 /// # use schema::users::dsl::*;
37 /// # let connection = &mut establish_connection();
38 /// let data = users.select(id).filter(name.eq("Sean"));
39 /// assert_eq!(Ok(1), data.first(connection));
40 /// # }
41 /// ```
42 ///
43 /// Matching against `None` follows SQL semantics:
44 /// ```rust
45 /// # include!("../doctest_setup.rs");
46 /// #
47 /// # // Reading the query result requires reading memory allocated by the
48 /// # // native sqlite library, which miri cannot track provenance for.
49 /// # #[cfg(miri)]
50 /// # fn main() {}
51 /// # #[cfg(not(miri))]
52 /// # fn main() {
53 /// # run_test().unwrap();
54 /// # }
55 /// #
56 /// # fn run_test() -> QueryResult<()> {
57 /// # use schema::animals::dsl::*;
58 /// # let connection = &mut establish_connection();
59 /// #
60 /// let data = animals
61 /// .select(species)
62 /// .filter(name.eq::<Option<String>>(None))
63 /// .first::<String>(connection);
64 /// assert_eq!(Err(diesel::NotFound), data);
65 ///
66 /// let data = animals
67 /// .select(species)
68 /// .filter(name.is_null())
69 /// .first::<String>(connection)?;
70 /// assert_eq!("spider", data);
71 /// # Ok(())
72 /// # }
73 /// ```
74 #[doc(alias = "=")]
75 fn eq<T>(self, other: T) -> dsl::Eq<Self, T>
76 where
77 Self::SqlType: SqlType,
78 T: AsExpression<Self::SqlType>,
79 {
80 Grouped(Eq::new(self, other.as_expression()))
81 }
82
83 /// Creates a SQL `!=` expression.
84 ///
85 /// # Example
86 ///
87 /// ```rust
88 /// # include!("../doctest_setup.rs");
89 /// #
90 /// # fn main() {
91 /// # use schema::users::dsl::*;
92 /// # let connection = &mut establish_connection();
93 /// let data = users.select(id).filter(name.ne("Sean"));
94 /// assert_eq!(Ok(2), data.first(connection));
95 /// # }
96 /// ```
97 #[doc(alias = "<>")]
98 fn ne<T>(self, other: T) -> dsl::NotEq<Self, T>
99 where
100 Self::SqlType: SqlType,
101 T: AsExpression<Self::SqlType>,
102 {
103 Grouped(NotEq::new(self, other.as_expression()))
104 }
105
106 /// Creates a SQL `IN` statement.
107 ///
108 /// Queries using this method will not typically be
109 /// placed in the prepared statement cache. However,
110 /// in cases when a subquery is passed to the method, that
111 /// query will use the cache (assuming the subquery
112 /// itself is safe to cache).
113 /// On PostgreSQL, this method automatically performs a `= ANY()`
114 /// query if this is possible. For cases where this is not possible
115 /// like for example if values is a vector of arrays we
116 /// generate an ordinary `IN` expression instead.
117 ///
118 /// # Example
119 ///
120 /// ```rust
121 /// # include!("../doctest_setup.rs");
122 /// #
123 /// # fn main() {
124 /// # use schema::users;
125 /// # use schema::posts;
126 /// # let connection = &mut establish_connection();
127 /// # diesel::sql_query("INSERT INTO users (name) VALUES
128 /// # ('Jim')").execute(connection).unwrap();
129 /// let data = users::table
130 /// .select(users::id)
131 /// .filter(users::name.eq_any(vec!["Sean", "Jim"]));
132 /// assert_eq!(Ok(vec![1, 3]), data.load(connection));
133 ///
134 /// // Calling `eq_any` with an empty array is the same as doing `WHERE 1=0`
135 /// let data = users::table
136 /// .select(users::id)
137 /// .filter(users::name.eq_any(Vec::<String>::new()));
138 /// assert_eq!(Ok(vec![]), data.load::<i32>(connection));
139 ///
140 /// // Calling `eq_any` with a subquery is the same as using
141 /// // `WHERE {column} IN {subquery}`.
142 ///
143 /// let subquery = users::table
144 /// .filter(users::name.eq("Sean"))
145 /// .select(users::id)
146 /// .into_boxed();
147 /// let data = posts::table
148 /// .select(posts::id)
149 /// .filter(posts::user_id.eq_any(subquery));
150 /// assert_eq!(Ok(vec![1, 2]), data.load::<i32>(connection));
151 ///
152 /// # }
153 /// ```
154 #[doc(alias = "in")]
155 fn eq_any<T>(self, values: T) -> dsl::EqAny<Self, T>
156 where
157 Self::SqlType: SqlType,
158 T: AsInExpression<Self::SqlType>,
159 {
160 Grouped(In::new(self, values.as_in_expression()))
161 }
162
163 /// Creates a SQL `NOT IN` statement.
164 ///
165 /// Queries using this method will not be
166 /// placed in the prepared statement cache. On PostgreSQL, this
167 /// method automatically performs a `!= ALL()` query if this is possible.
168 /// For cases where this is not possible
169 /// like for example if values is a vector of arrays we
170 /// generate an ordinary `NOT IN` expression instead.
171 ///
172 /// # Example
173 ///
174 /// ```rust
175 /// # include!("../doctest_setup.rs");
176 /// #
177 /// # fn main() {
178 /// # use schema::users::dsl::*;
179 /// # let connection = &mut establish_connection();
180 /// # diesel::sql_query("INSERT INTO users (name) VALUES
181 /// # ('Jim')").execute(connection).unwrap();
182 /// let data = users.select(id).filter(name.ne_all(vec!["Sean", "Jim"]));
183 /// assert_eq!(Ok(vec![2]), data.load(connection));
184 ///
185 /// let data = users.select(id).filter(name.ne_all(vec!["Tess"]));
186 /// assert_eq!(Ok(vec![1, 3]), data.load(connection));
187 ///
188 /// // Calling `ne_any` with an empty array is the same as doing `WHERE 1=1`
189 /// let data = users.select(id).filter(name.ne_all(Vec::<String>::new()));
190 /// assert_eq!(Ok(vec![1, 2, 3]), data.load(connection));
191 /// # }
192 /// ```
193 #[doc(alias = "in")]
194 fn ne_all<T>(self, values: T) -> dsl::NeAny<Self, T>
195 where
196 Self::SqlType: SqlType,
197 T: AsInExpression<Self::SqlType>,
198 {
199 Grouped(NotIn::new(self, values.as_in_expression()))
200 }
201
202 /// Creates a SQL `IS NULL` expression.
203 ///
204 /// # Example
205 ///
206 /// ```rust
207 /// # include!("../doctest_setup.rs");
208 /// #
209 /// # // Reading the query result requires reading memory allocated by the
210 /// # // native sqlite library, which miri cannot track provenance for.
211 /// # #[cfg(miri)]
212 /// # fn main() {}
213 /// # #[cfg(not(miri))]
214 /// # fn main() {
215 /// # run_test().unwrap();
216 /// # }
217 /// #
218 /// # fn run_test() -> QueryResult<()> {
219 /// # use schema::animals::dsl::*;
220 /// # let connection = &mut establish_connection();
221 /// #
222 /// let data = animals
223 /// .select(species)
224 /// .filter(name.is_null())
225 /// .first::<String>(connection)?;
226 /// assert_eq!("spider", data);
227 /// # Ok(())
228 /// # }
229 /// ```
230 // This method is part of the public API,
231 // so we cannot just change the name to appease clippy
232 // (Otherwise it's also named after the `IS NULL` sql expression
233 // so that name is really fine)
234 #[allow(clippy::wrong_self_convention)]
235 fn is_null(self) -> dsl::IsNull<Self> {
236 Grouped(IsNull::new(self))
237 }
238
239 /// Creates a SQL `IS NOT NULL` expression.
240 ///
241 /// # Example
242 ///
243 /// ```rust
244 /// # include!("../doctest_setup.rs");
245 /// #
246 /// # // Reading the query result requires reading memory allocated by the
247 /// # // native sqlite library, which miri cannot track provenance for.
248 /// # #[cfg(miri)]
249 /// # fn main() {}
250 /// # #[cfg(not(miri))]
251 /// # fn main() {
252 /// # run_test().unwrap();
253 /// # }
254 /// #
255 /// # fn run_test() -> QueryResult<()> {
256 /// # use schema::animals::dsl::*;
257 /// # let connection = &mut establish_connection();
258 /// #
259 /// let data = animals
260 /// .select(species)
261 /// .filter(name.is_not_null())
262 /// .first::<String>(connection)?;
263 /// assert_eq!("dog", data);
264 /// # Ok(())
265 /// # }
266 /// ```
267 // This method is part of the public API,
268 // so we cannot just change the name to appease clippy
269 // (Otherwise it's also named after the `IS NOT NULL` sql expression
270 // so that name is really fine)
271 #[allow(clippy::wrong_self_convention)]
272 fn is_not_null(self) -> dsl::IsNotNull<Self> {
273 Grouped(IsNotNull::new(self))
274 }
275
276 /// Creates a SQL `>` expression.
277 ///
278 /// # Example
279 ///
280 /// ```rust
281 /// # include!("../doctest_setup.rs");
282 /// #
283 /// # // Reading the query result requires reading memory allocated by the
284 /// # // native sqlite library, which miri cannot track provenance for.
285 /// # #[cfg(miri)]
286 /// # fn main() {}
287 /// # #[cfg(not(miri))]
288 /// # fn main() {
289 /// # run_test().unwrap();
290 /// # }
291 /// #
292 /// # fn run_test() -> QueryResult<()> {
293 /// # use schema::users::dsl::*;
294 /// # let connection = &mut establish_connection();
295 /// let data = users
296 /// .select(name)
297 /// .filter(id.gt(1))
298 /// .first::<String>(connection)?;
299 /// assert_eq!("Tess", data);
300 /// # Ok(())
301 /// # }
302 /// ```
303 #[doc(alias = ">")]
304 fn gt<T>(self, other: T) -> dsl::Gt<Self, T>
305 where
306 Self::SqlType: SqlType,
307 T: AsExpression<Self::SqlType>,
308 {
309 Grouped(Gt::new(self, other.as_expression()))
310 }
311
312 /// Creates a SQL `>=` expression.
313 ///
314 /// # Example
315 ///
316 /// ```rust
317 /// # include!("../doctest_setup.rs");
318 /// #
319 /// # // Reading the query result requires reading memory allocated by the
320 /// # // native sqlite library, which miri cannot track provenance for.
321 /// # #[cfg(miri)]
322 /// # fn main() {}
323 /// # #[cfg(not(miri))]
324 /// # fn main() {
325 /// # run_test().unwrap();
326 /// # }
327 /// #
328 /// # fn run_test() -> QueryResult<()> {
329 /// # use schema::users::dsl::*;
330 /// # let connection = &mut establish_connection();
331 /// let data = users
332 /// .select(name)
333 /// .filter(id.ge(2))
334 /// .first::<String>(connection)?;
335 /// assert_eq!("Tess", data);
336 /// # Ok(())
337 /// # }
338 /// ```
339 #[doc(alias = ">=")]
340 fn ge<T>(self, other: T) -> dsl::GtEq<Self, T>
341 where
342 Self::SqlType: SqlType,
343 T: AsExpression<Self::SqlType>,
344 {
345 Grouped(GtEq::new(self, other.as_expression()))
346 }
347
348 /// Creates a SQL `<` expression.
349 ///
350 /// # Example
351 ///
352 /// ```rust
353 /// # include!("../doctest_setup.rs");
354 /// #
355 /// # // Reading the query result requires reading memory allocated by the
356 /// # // native sqlite library, which miri cannot track provenance for.
357 /// # #[cfg(miri)]
358 /// # fn main() {}
359 /// # #[cfg(not(miri))]
360 /// # fn main() {
361 /// # run_test().unwrap();
362 /// # }
363 /// #
364 /// # fn run_test() -> QueryResult<()> {
365 /// # use schema::users::dsl::*;
366 /// # let connection = &mut establish_connection();
367 /// let data = users
368 /// .select(name)
369 /// .filter(id.lt(2))
370 /// .first::<String>(connection)?;
371 /// assert_eq!("Sean", data);
372 /// # Ok(())
373 /// # }
374 /// ```
375 #[doc(alias = "<")]
376 fn lt<T>(self, other: T) -> dsl::Lt<Self, T>
377 where
378 Self::SqlType: SqlType,
379 T: AsExpression<Self::SqlType>,
380 {
381 Grouped(Lt::new(self, other.as_expression()))
382 }
383
384 /// Creates a SQL `<=` expression.
385 ///
386 /// # Example
387 ///
388 /// ```rust
389 /// # include!("../doctest_setup.rs");
390 /// #
391 /// # // Reading the query result requires reading memory allocated by the
392 /// # // native sqlite library, which miri cannot track provenance for.
393 /// # #[cfg(miri)]
394 /// # fn main() {}
395 /// # #[cfg(not(miri))]
396 /// # fn main() {
397 /// # run_test().unwrap();
398 /// # }
399 /// #
400 /// # fn run_test() -> QueryResult<()> {
401 /// # use schema::users::dsl::*;
402 /// # let connection = &mut establish_connection();
403 /// let data = users
404 /// .select(name)
405 /// .filter(id.le(2))
406 /// .first::<String>(connection)?;
407 /// assert_eq!("Sean", data);
408 /// # Ok(())
409 /// # }
410 /// ```
411 #[doc(alias = "<=")]
412 fn le<T>(self, other: T) -> dsl::LtEq<Self, T>
413 where
414 Self::SqlType: SqlType,
415 T: AsExpression<Self::SqlType>,
416 {
417 Grouped(LtEq::new(self, other.as_expression()))
418 }
419
420 /// Creates a SQL `BETWEEN` expression using the given lower and upper
421 /// bounds.
422 ///
423 /// # Example
424 ///
425 /// ```rust
426 /// # include!("../doctest_setup.rs");
427 /// #
428 /// # // Reading the query result requires reading memory allocated by the
429 /// # // native sqlite library, which miri cannot track provenance for.
430 /// # #[cfg(miri)]
431 /// # fn main() {}
432 /// # #[cfg(not(miri))]
433 /// # fn main() {
434 /// # use schema::animals::dsl::*;
435 /// # let connection = &mut establish_connection();
436 /// #
437 /// let data = animals
438 /// .select(species)
439 /// .filter(legs.between(2, 6))
440 /// .first(connection);
441 /// #
442 /// assert_eq!(Ok("dog".to_string()), data);
443 /// # }
444 /// ```
445 fn between<T, U>(self, lower: T, upper: U) -> dsl::Between<Self, T, U>
446 where
447 Self::SqlType: SqlType,
448 T: AsExpression<Self::SqlType>,
449 U: AsExpression<Self::SqlType>,
450 {
451 Grouped(Between::new(
452 self,
453 And::new(lower.as_expression(), upper.as_expression()),
454 ))
455 }
456
457 /// Creates a SQL `NOT BETWEEN` expression using the given lower and upper
458 /// bounds.
459 ///
460 /// # Example
461 ///
462 /// ```rust
463 /// # include!("../doctest_setup.rs");
464 /// #
465 /// # // Reading the query result requires reading memory allocated by the
466 /// # // native sqlite library, which miri cannot track provenance for.
467 /// # #[cfg(miri)]
468 /// # fn main() {}
469 /// # #[cfg(not(miri))]
470 /// # fn main() {
471 /// # run_test().unwrap();
472 /// # }
473 /// #
474 /// # fn run_test() -> QueryResult<()> {
475 /// # use schema::animals::dsl::*;
476 /// # let connection = &mut establish_connection();
477 /// #
478 /// let data = animals
479 /// .select(species)
480 /// .filter(legs.not_between(2, 6))
481 /// .first::<String>(connection)?;
482 /// assert_eq!("spider", data);
483 /// # Ok(())
484 /// # }
485 /// ```
486 fn not_between<T, U>(self, lower: T, upper: U) -> dsl::NotBetween<Self, T, U>
487 where
488 Self::SqlType: SqlType,
489 T: AsExpression<Self::SqlType>,
490 U: AsExpression<Self::SqlType>,
491 {
492 Grouped(NotBetween::new(
493 self,
494 And::new(lower.as_expression(), upper.as_expression()),
495 ))
496 }
497
498 /// Generates a `CAST(expr AS sql_type)` expression
499 ///
500 /// It is necessary that the expression's SQL type can be casted to the
501 /// target SQL type (represented by the [`CastsTo`](cast::CastsTo) trait),
502 /// and that we know how the corresponding SQL type is named for the
503 /// specific backend (represented by the
504 /// [`KnownCastSqlTypeName`](cast::KnownCastSqlTypeName) trait).
505 ///
506 /// # Example
507 ///
508 /// ```rust
509 /// # include!("../doctest_setup.rs");
510 /// #
511 /// # // Reading the query result requires reading memory allocated by the
512 /// # // native sqlite library, which miri cannot track provenance for.
513 /// # #[cfg(miri)]
514 /// # fn main() {}
515 /// # #[cfg(not(miri))]
516 /// # fn main() {
517 /// # run_test().unwrap();
518 /// # }
519 /// #
520 /// # fn run_test() -> QueryResult<()> {
521 /// # use schema::animals::dsl::*;
522 /// # let connection = &mut establish_connection();
523 /// #
524 /// use diesel::sql_types;
525 ///
526 /// let data = diesel::select(
527 /// 12_i32
528 /// .into_sql::<sql_types::Int4>()
529 /// .cast::<sql_types::Text>(),
530 /// )
531 /// .first::<String>(connection)?;
532 /// assert_eq!("12", data);
533 /// # Ok(())
534 /// # }
535 /// ```
536 fn cast<ST>(self) -> dsl::Cast<Self, ST>
537 where
538 ST: SingleValue,
539 Self::SqlType: cast::CastsTo<ST>,
540 {
541 cast::Cast::new(self)
542 }
543
544 /// Generates a `CAST(expr AS sql_type)` expression, this version does not check the castability, like [`cast()`](Self::cast).
545 ///
546 /// # Example
547 ///
548 /// ```rust
549 /// # include!("../doctest_setup.rs");
550 /// #
551 /// # fn main() {
552 /// # run_test().unwrap();
553 /// # }
554 /// #
555 /// # fn run_test() -> QueryResult<()> {
556 /// # use schema::animals::dsl::*;
557 /// # let connection = &mut establish_connection();
558 /// #
559 /// use diesel::sql_types;
560 ///
561 /// let data = diesel::select(
562 /// "12".into_sql::<sql_types::Text>()
563 /// .fallible_cast::<sql_types::Int8>(),
564 /// )
565 /// .first::<i64>(connection)?;
566 /// assert_eq!(12i64, data);
567 /// # Ok(())
568 /// # }
569 /// ```
570 fn fallible_cast<ST>(self) -> dsl::Cast<Self, ST>
571 where
572 ST: SingleValue,
573 Self::SqlType: cast::FallibleCastsTo<ST>,
574 {
575 cast::Cast::new(self)
576 }
577
578 /// Creates a SQL `DESC` expression, representing this expression in
579 /// descending order.
580 ///
581 /// # Example
582 ///
583 /// ```rust
584 /// # include!("../doctest_setup.rs");
585 /// #
586 /// # // Reading the query result requires reading memory allocated by the
587 /// # // native sqlite library, which miri cannot track provenance for.
588 /// # #[cfg(miri)]
589 /// # fn main() {}
590 /// # #[cfg(not(miri))]
591 /// # fn main() {
592 /// # run_test().unwrap();
593 /// # }
594 /// #
595 /// # fn run_test() -> QueryResult<()> {
596 /// # use schema::users::dsl::*;
597 /// # let connection = &mut establish_connection();
598 /// #
599 /// let names = users
600 /// .select(name)
601 /// .order(name.desc())
602 /// .load::<String>(connection)?;
603 /// assert_eq!(vec!["Tess", "Sean"], names);
604 /// # Ok(())
605 /// # }
606 /// ```
607 fn desc(self) -> dsl::Desc<Self> {
608 Desc::new(self)
609 }
610
611 /// Creates a SQL `ASC` expression, representing this expression in
612 /// ascending order.
613 ///
614 /// This is the same as leaving the direction unspecified. It is useful if
615 /// you need to provide an unknown ordering, and need to box the return
616 /// value of a function.
617 ///
618 /// # Example
619 ///
620 /// ```rust
621 /// # include!("../doctest_setup.rs");
622 /// # use diesel::expression::expression_types::NotSelectable;
623 /// #
624 /// # fn main() {
625 /// # use schema::users::dsl::*;
626 /// # let order = "name";
627 /// let ordering: Box<dyn BoxableExpression<users, DB, SqlType = NotSelectable>> =
628 /// if order == "name" {
629 /// Box::new(name.desc())
630 /// } else {
631 /// Box::new(id.asc())
632 /// };
633 /// # }
634 /// ```
635 fn asc(self) -> dsl::Asc<Self> {
636 Asc::new(self)
637 }
638}
639
640impl<T> ExpressionMethods for T
641where
642 T: Expression,
643 T::SqlType: SingleValue,
644{
645}
646
647/// Methods present on untyped expressions.
648///
649/// This trait is implemented for expressions where the sql type is [`Untyped`].
650/// This allows calling common operators on these expressions.
651///
652/// This trait is primarily meant to be used for untyped queries in
653/// [`diesel_dynamic_schema`](https://docs.rs/diesel-dynamic-schema/latest/diesel_dynamic_schema/).
654pub trait UntypedExpressionMethods: Sized {
655 /// Creates a SQL `IS NULL` expression.
656 ///
657 /// # Example
658 ///
659 /// ```rust
660 /// # include!("../doctest_setup.rs");
661 /// #
662 /// # // Reading the query result requires reading memory allocated by the
663 /// # // native sqlite library, which miri cannot track provenance for.
664 /// # #[cfg(miri)]
665 /// # fn main() {}
666 /// # #[cfg(not(miri))]
667 /// # fn main() {
668 /// # run_test().unwrap();
669 /// # }
670 /// #
671 /// # fn run_test() -> QueryResult<()> {
672 /// # use schema::animals::dsl::*;
673 /// # let connection = &mut establish_connection();
674 /// #
675 /// use diesel::sql_types::Untyped;
676 /// use diesel::dsl::sql;
677 ///
678 /// let data = animals
679 /// .select(species)
680 /// .filter(sql::<Untyped>("name").is_null())
681 /// .first::<String>(connection)?;
682 /// assert_eq!("spider", data);
683 /// # Ok(())
684 /// # }
685 /// ```
686 #[allow(clippy::wrong_self_convention)]
687 fn is_null(self) -> dsl::IsNull<Self> {
688 Grouped(IsNull::new(self))
689 }
690
691 /// Creates a SQL `IS NOT NULL` expression.
692 ///
693 /// # Example
694 ///
695 /// ```rust
696 /// # include!("../doctest_setup.rs");
697 /// #
698 /// # // Reading the query result requires reading memory allocated by the
699 /// # // native sqlite library, which miri cannot track provenance for.
700 /// # #[cfg(miri)]
701 /// # fn main() {}
702 /// # #[cfg(not(miri))]
703 /// # fn main() {
704 /// # run_test().unwrap();
705 /// # }
706 /// #
707 /// # fn run_test() -> QueryResult<()> {
708 /// # use schema::animals::dsl::*;
709 /// # let connection = &mut establish_connection();
710 /// #
711 /// use diesel::sql_types::Untyped;
712 /// use diesel::dsl::sql;
713 ///
714 /// let data = animals
715 /// .select(species)
716 /// .filter(sql::<Untyped>("name").is_not_null())
717 /// .first::<String>(connection)?;
718 /// assert_eq!("dog", data);
719 /// # Ok(())
720 /// # }
721 /// ```
722 #[allow(clippy::wrong_self_convention)]
723 fn is_not_null(self) -> dsl::IsNotNull<Self> {
724 Grouped(IsNotNull::new(self))
725 }
726
727 /// Creates a SQL `DESC` expression, representing this expression in
728 /// descending order.
729 ///
730 /// # Example
731 ///
732 /// ```rust
733 /// # include!("../doctest_setup.rs");
734 /// #
735 /// # // Reading the query result requires reading memory allocated by the
736 /// # // native sqlite library, which miri cannot track provenance for.
737 /// # #[cfg(miri)]
738 /// # fn main() {}
739 /// # #[cfg(not(miri))]
740 /// # fn main() {
741 /// # run_test().unwrap();
742 /// # }
743 /// #
744 /// # fn run_test() -> QueryResult<()> {
745 /// # use schema::users::dsl::*;
746 /// # let connection = &mut establish_connection();
747 /// #
748 /// use diesel::sql_types::Untyped;
749 /// use diesel::dsl::sql;
750 ///
751 /// let data = users
752 /// .select(name)
753 /// .order(sql::<Untyped>("name").desc())
754 /// .load::<String>(connection)?;
755 /// let expected = vec!["Tess", "Sean"];
756 /// assert_eq!(expected, data);
757 /// # Ok(())
758 /// # }
759 /// ```
760 fn desc(self) -> dsl::Desc<Self> {
761 Desc::new(self)
762 }
763
764 /// Creates a SQL `ASC` expression, representing this expression in
765 /// ascending order.
766 ///
767 /// # Example
768 ///
769 /// ```rust
770 /// # include!("../doctest_setup.rs");
771 /// #
772 /// # // Reading the query result requires reading memory allocated by the
773 /// # // native sqlite library, which miri cannot track provenance for.
774 /// # #[cfg(miri)]
775 /// # fn main() {}
776 /// # #[cfg(not(miri))]
777 /// # fn main() {
778 /// # run_test().unwrap();
779 /// # }
780 /// #
781 /// # fn run_test() -> QueryResult<()> {
782 /// # use schema::users::dsl::*;
783 /// # let connection = &mut establish_connection();
784 /// #
785 /// use diesel::sql_types::Untyped;
786 /// use diesel::dsl::sql;
787 ///
788 /// let data = users
789 /// .select(name)
790 /// .order(sql::<Untyped>("name").asc())
791 /// .load::<String>(connection)?;
792 /// let expected = vec!["Sean", "Tess"];
793 /// assert_eq!(expected, data);
794 /// # Ok(())
795 /// # }
796 /// ```
797 fn asc(self) -> dsl::Asc<Self> {
798 Asc::new(self)
799 }
800}
801
802impl<T> UntypedExpressionMethods for T where T: Expression<SqlType = Untyped> {}
803
804/// Methods present on all expressions
805pub trait NullableExpressionMethods: Expression + Sized {
806 /// Converts this potentially non-null expression into one which is treated
807 /// as nullable. This method has no impact on the generated SQL, and is only
808 /// used to allow certain comparisons that would otherwise fail to compile.
809 ///
810 /// # Example
811 /// ```no_run
812 /// # #![allow(dead_code)]
813 /// # include!("../doctest_setup.rs");
814 /// # use diesel::sql_types::*;
815 /// # use schema::users;
816 /// #
817 /// table! {
818 /// posts {
819 /// id -> Integer,
820 /// user_id -> Integer,
821 /// author_name -> Nullable<VarChar>,
822 /// }
823 /// }
824 /// #
825 /// # joinable!(posts -> users (user_id));
826 /// # allow_tables_to_appear_in_same_query!(posts, users);
827 ///
828 /// fn main() {
829 /// use self::posts::dsl::{author_name, posts};
830 /// use self::users::dsl::*;
831 /// let connection = &mut establish_connection();
832 ///
833 /// let data = users
834 /// .inner_join(posts)
835 /// .filter(name.nullable().eq(author_name))
836 /// .select(name)
837 /// .load::<String>(connection);
838 /// println!("{:?}", data);
839 /// }
840 /// ```
841 fn nullable(self) -> dsl::Nullable<Self> {
842 nullable::Nullable::new(self)
843 }
844
845 /// Converts this potentially nullable expression into one which will be **assumed**
846 /// to be not-null. This method has no impact on the generated SQL, however it will
847 /// enable you to attempt deserialization of the returned value in a non-`Option`.
848 ///
849 /// This is meant to cover for cases where you know that given the `WHERE` clause
850 /// the field returned by the database will never be `NULL`.
851 ///
852 /// This **will cause runtime errors** on `load()` if the "assume" turns out to be incorrect.
853 ///
854 /// # Examples
855 /// ## Normal usage
856 /// ```rust
857 /// # #![allow(dead_code)]
858 /// # include!("../doctest_setup.rs");
859 /// # use diesel::sql_types::*;
860 /// #
861 /// table! {
862 /// animals {
863 /// id -> Integer,
864 /// species -> VarChar,
865 /// legs -> Integer,
866 /// name -> Nullable<VarChar>,
867 /// }
868 /// }
869 ///
870 /// # // Reading the query result requires reading memory allocated by the
871 /// # // native sqlite library, which miri cannot track provenance for.
872 /// #[cfg(miri)]
873 /// fn main() {}
874 /// #[cfg(not(miri))]
875 /// fn main() {
876 /// use self::animals::dsl::*;
877 /// let connection = &mut establish_connection();
878 ///
879 /// let result = animals
880 /// .filter(name.is_not_null())
881 /// .select(name.assume_not_null())
882 /// .load::<String>(connection);
883 /// assert!(result.is_ok());
884 /// }
885 /// ```
886 ///
887 /// ## Incorrect usage
888 /// ```rust
889 /// # #![allow(dead_code)]
890 /// # include!("../doctest_setup.rs");
891 /// # use diesel::sql_types::*;
892 /// #
893 /// table! {
894 /// animals {
895 /// id -> Integer,
896 /// species -> VarChar,
897 /// legs -> Integer,
898 /// name -> Nullable<VarChar>,
899 /// }
900 /// }
901 ///
902 /// # // Reading the query result requires reading memory allocated by the
903 /// # // native sqlite library, which miri cannot track provenance for.
904 /// #[cfg(miri)]
905 /// fn main() {}
906 /// #[cfg(not(miri))]
907 /// fn main() {
908 /// use diesel::result::{Error, UnexpectedNullError};
909 /// use self::animals::dsl::*;
910 /// let connection = &mut establish_connection();
911 ///
912 /// let result = animals
913 /// .select(name.assume_not_null())
914 /// .load::<String>(connection);
915 /// assert!(matches!(
916 /// result,
917 /// Err(Error::DeserializationError(err)) if err.is::<UnexpectedNullError>()
918 /// ));
919 /// }
920 /// ```
921 ///
922 /// ## Advanced usage - use only if you're sure you know what you're doing!
923 ///
924 /// This will cause the `Option` to be `None` where the `left_join` succeeded but the
925 /// `author_name` turned out to be `NULL`, due to how `Option` deserialization works.
926 /// (see [`Queryable` documentation](crate::deserialize::Queryable))
927 ///
928 /// ```rust
929 /// # #![allow(dead_code)]
930 /// # include!("../doctest_setup.rs");
931 /// # use diesel::sql_types::*;
932 /// # use schema::users;
933 /// #
934 /// table! {
935 /// posts {
936 /// id -> Integer,
937 /// user_id -> Integer,
938 /// author_name -> Nullable<Text>,
939 /// }
940 /// }
941 /// #
942 /// # joinable!(posts -> users (user_id));
943 /// # allow_tables_to_appear_in_same_query!(posts, users);
944 ///
945 /// # // Reading the query result requires reading memory allocated by the
946 /// # // native sqlite library, which miri cannot track provenance for.
947 /// #[cfg(miri)]
948 /// fn main() {}
949 /// #[cfg(not(miri))]
950 /// fn main() {
951 /// use self::posts;
952 /// use self::users;
953 /// let connection = &mut establish_connection();
954 ///
955 /// # diesel::sql_query("ALTER TABLE posts ADD COLUMN author_name Text")
956 /// # .execute(connection)
957 /// # .unwrap();
958 /// # diesel::update(posts::table.filter(posts::user_id.eq(1)))
959 /// # .set(posts::author_name.eq("Sean"))
960 /// # .execute(connection);
961 ///
962 /// let result = posts::table
963 /// .left_join(users::table)
964 /// .select((
965 /// posts::id,
966 /// (users::id, posts::author_name.assume_not_null()).nullable(),
967 /// ))
968 /// .order_by(posts::id)
969 /// .load::<(i32, Option<(i32, String)>)>(connection);
970 /// let expected = Ok(vec![
971 /// (1, Some((1, "Sean".to_owned()))),
972 /// (2, Some((1, "Sean".to_owned()))),
973 /// (3, None),
974 /// ]);
975 /// assert_eq!(expected, result);
976 /// }
977 /// ```
978 fn assume_not_null(self) -> dsl::AssumeNotNull<Self> {
979 assume_not_null::AssumeNotNull::new(self)
980 }
981}
982
983impl<T: Expression> NullableExpressionMethods for T {}