Skip to main content

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