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::{assume_not_null, cast, nullable, AsExpression, Expression};
6use crate::sql_types::{SingleValue, SqlType};
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", 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",
21        doc = "sqlite-specific [`is`](crate::SqliteExpressionMethods::is())"
22    )]
23    #[cfg_attr(all(feature = "sqlite", 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", 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    /// # fn main() {
48    /// #     run_test().unwrap();
49    /// # }
50    /// #
51    /// # fn run_test() -> QueryResult<()> {
52    /// #     use schema::animals::dsl::*;
53    /// #     let connection = &mut establish_connection();
54    /// #
55    /// let data = animals
56    ///     .select(species)
57    ///     .filter(name.eq::<Option<String>>(None))
58    ///     .first::<String>(connection);
59    /// assert_eq!(Err(diesel::NotFound), data);
60    ///
61    /// let data = animals
62    ///     .select(species)
63    ///     .filter(name.is_null())
64    ///     .first::<String>(connection)?;
65    /// assert_eq!("spider", data);
66    /// #     Ok(())
67    /// # }
68    /// ```
69    #[doc(alias = "=")]
70    fn eq<T>(self, other: T) -> dsl::Eq<Self, T>
71    where
72        Self::SqlType: SqlType,
73        T: AsExpression<Self::SqlType>,
74    {
75        Grouped(Eq::new(self, other.as_expression()))
76    }
77
78    /// Creates a SQL `!=` expression.
79    ///
80    /// # Example
81    ///
82    /// ```rust
83    /// # include!("../doctest_setup.rs");
84    /// #
85    /// # fn main() {
86    /// #     use schema::users::dsl::*;
87    /// #     let connection = &mut establish_connection();
88    /// let data = users.select(id).filter(name.ne("Sean"));
89    /// assert_eq!(Ok(2), data.first(connection));
90    /// # }
91    /// ```
92    #[doc(alias = "<>")]
93    fn ne<T>(self, other: T) -> dsl::NotEq<Self, T>
94    where
95        Self::SqlType: SqlType,
96        T: AsExpression<Self::SqlType>,
97    {
98        Grouped(NotEq::new(self, other.as_expression()))
99    }
100
101    /// Creates a SQL `IN` statement.
102    ///
103    /// Queries using this method will not typically be
104    /// placed in the prepared statement cache. However,
105    /// in cases when a subquery is passed to the method, that
106    /// query will use the cache (assuming the subquery
107    /// itself is safe to cache).
108    /// On PostgreSQL, this method automatically performs a `= ANY()`
109    /// query if this is possible. For cases where this is not possible
110    /// like for example if values is a vector of arrays we
111    /// generate an ordinary `IN` expression instead.
112    ///
113    /// # Example
114    ///
115    /// ```rust
116    /// # include!("../doctest_setup.rs");
117    /// #
118    /// # fn main() {
119    /// #     use schema::users;
120    /// #     use schema::posts;
121    /// #     let connection = &mut establish_connection();
122    /// #     diesel::sql_query("INSERT INTO users (name) VALUES
123    /// #         ('Jim')").execute(connection).unwrap();
124    /// let data = users::table
125    ///     .select(users::id)
126    ///     .filter(users::name.eq_any(vec!["Sean", "Jim"]));
127    /// assert_eq!(Ok(vec![1, 3]), data.load(connection));
128    ///
129    /// // Calling `eq_any` with an empty array is the same as doing `WHERE 1=0`
130    /// let data = users::table
131    ///     .select(users::id)
132    ///     .filter(users::name.eq_any(Vec::<String>::new()));
133    /// assert_eq!(Ok(vec![]), data.load::<i32>(connection));
134    ///
135    /// // Calling `eq_any` with a subquery is the same as using
136    /// // `WHERE {column} IN {subquery}`.
137    ///
138    /// let subquery = users::table
139    ///     .filter(users::name.eq("Sean"))
140    ///     .select(users::id)
141    ///     .into_boxed();
142    /// let data = posts::table
143    ///     .select(posts::id)
144    ///     .filter(posts::user_id.eq_any(subquery));
145    /// assert_eq!(Ok(vec![1, 2]), data.load::<i32>(connection));
146    ///
147    /// # }
148    /// ```
149    #[doc(alias = "in")]
150    fn eq_any<T>(self, values: T) -> dsl::EqAny<Self, T>
151    where
152        Self::SqlType: SqlType,
153        T: AsInExpression<Self::SqlType>,
154    {
155        Grouped(In::new(self, values.as_in_expression()))
156    }
157
158    /// Creates a SQL `NOT IN` statement.
159    ///
160    /// Queries using this method will not be
161    /// placed in the prepared statement cache. On PostgreSQL, this
162    /// method automatically performs a `!= ALL()` query if this is possible.
163    /// For cases where this is not possible
164    /// like for example if values is a vector of arrays we
165    /// generate an ordinary `NOT IN` expression instead.
166    ///
167    /// # Example
168    ///
169    /// ```rust
170    /// # include!("../doctest_setup.rs");
171    /// #
172    /// # fn main() {
173    /// #     use schema::users::dsl::*;
174    /// #     let connection = &mut establish_connection();
175    /// #     diesel::sql_query("INSERT INTO users (name) VALUES
176    /// #         ('Jim')").execute(connection).unwrap();
177    /// let data = users.select(id).filter(name.ne_all(vec!["Sean", "Jim"]));
178    /// assert_eq!(Ok(vec![2]), data.load(connection));
179    ///
180    /// let data = users.select(id).filter(name.ne_all(vec!["Tess"]));
181    /// assert_eq!(Ok(vec![1, 3]), data.load(connection));
182    ///
183    /// // Calling `ne_any` with an empty array is the same as doing `WHERE 1=1`
184    /// let data = users.select(id).filter(name.ne_all(Vec::<String>::new()));
185    /// assert_eq!(Ok(vec![1, 2, 3]), data.load(connection));
186    /// # }
187    /// ```
188    #[doc(alias = "in")]
189    fn ne_all<T>(self, values: T) -> dsl::NeAny<Self, T>
190    where
191        Self::SqlType: SqlType,
192        T: AsInExpression<Self::SqlType>,
193    {
194        Grouped(NotIn::new(self, values.as_in_expression()))
195    }
196
197    /// Creates a SQL `IS NULL` expression.
198    ///
199    /// # Example
200    ///
201    /// ```rust
202    /// # include!("../doctest_setup.rs");
203    /// #
204    /// # fn main() {
205    /// #     run_test().unwrap();
206    /// # }
207    /// #
208    /// # fn run_test() -> QueryResult<()> {
209    /// #     use schema::animals::dsl::*;
210    /// #     let connection = &mut establish_connection();
211    /// #
212    /// let data = animals
213    ///     .select(species)
214    ///     .filter(name.is_null())
215    ///     .first::<String>(connection)?;
216    /// assert_eq!("spider", data);
217    /// #     Ok(())
218    /// # }
219    /// ```
220    // This method is part of the public API,
221    // so we cannot just change the name to appease clippy
222    // (Otherwise it's also named after the `IS NULL` sql expression
223    // so that name is really fine)
224    #[allow(clippy::wrong_self_convention)]
225    fn is_null(self) -> dsl::IsNull<Self> {
226        Grouped(IsNull::new(self))
227    }
228
229    /// Creates a SQL `IS NOT NULL` expression.
230    ///
231    /// # Example
232    ///
233    /// ```rust
234    /// # include!("../doctest_setup.rs");
235    /// #
236    /// # fn main() {
237    /// #     run_test().unwrap();
238    /// # }
239    /// #
240    /// # fn run_test() -> QueryResult<()> {
241    /// #     use schema::animals::dsl::*;
242    /// #     let connection = &mut establish_connection();
243    /// #
244    /// let data = animals
245    ///     .select(species)
246    ///     .filter(name.is_not_null())
247    ///     .first::<String>(connection)?;
248    /// assert_eq!("dog", data);
249    /// #     Ok(())
250    /// # }
251    /// ```
252    // This method is part of the public API,
253    // so we cannot just change the name to appease clippy
254    // (Otherwise it's also named after the `IS NOT NULL` sql expression
255    // so that name is really fine)
256    #[allow(clippy::wrong_self_convention)]
257    fn is_not_null(self) -> dsl::IsNotNull<Self> {
258        Grouped(IsNotNull::new(self))
259    }
260
261    /// Creates a SQL `>` expression.
262    ///
263    /// # Example
264    ///
265    /// ```rust
266    /// # include!("../doctest_setup.rs");
267    /// #
268    /// # fn main() {
269    /// #     run_test().unwrap();
270    /// # }
271    /// #
272    /// # fn run_test() -> QueryResult<()> {
273    /// #     use schema::users::dsl::*;
274    /// #     let connection = &mut establish_connection();
275    /// let data = users
276    ///     .select(name)
277    ///     .filter(id.gt(1))
278    ///     .first::<String>(connection)?;
279    /// assert_eq!("Tess", data);
280    /// #     Ok(())
281    /// # }
282    /// ```
283    #[doc(alias = ">")]
284    fn gt<T>(self, other: T) -> dsl::Gt<Self, T>
285    where
286        Self::SqlType: SqlType,
287        T: AsExpression<Self::SqlType>,
288    {
289        Grouped(Gt::new(self, other.as_expression()))
290    }
291
292    /// Creates a SQL `>=` expression.
293    ///
294    /// # Example
295    ///
296    /// ```rust
297    /// # include!("../doctest_setup.rs");
298    /// #
299    /// # fn main() {
300    /// #     run_test().unwrap();
301    /// # }
302    /// #
303    /// # fn run_test() -> QueryResult<()> {
304    /// #     use schema::users::dsl::*;
305    /// #     let connection = &mut establish_connection();
306    /// let data = users
307    ///     .select(name)
308    ///     .filter(id.ge(2))
309    ///     .first::<String>(connection)?;
310    /// assert_eq!("Tess", data);
311    /// #     Ok(())
312    /// # }
313    /// ```
314    #[doc(alias = ">=")]
315    fn ge<T>(self, other: T) -> dsl::GtEq<Self, T>
316    where
317        Self::SqlType: SqlType,
318        T: AsExpression<Self::SqlType>,
319    {
320        Grouped(GtEq::new(self, other.as_expression()))
321    }
322
323    /// Creates a SQL `<` expression.
324    ///
325    /// # Example
326    ///
327    /// ```rust
328    /// # include!("../doctest_setup.rs");
329    /// #
330    /// # fn main() {
331    /// #     run_test().unwrap();
332    /// # }
333    /// #
334    /// # fn run_test() -> QueryResult<()> {
335    /// #     use schema::users::dsl::*;
336    /// #     let connection = &mut establish_connection();
337    /// let data = users
338    ///     .select(name)
339    ///     .filter(id.lt(2))
340    ///     .first::<String>(connection)?;
341    /// assert_eq!("Sean", data);
342    /// #     Ok(())
343    /// # }
344    /// ```
345    #[doc(alias = "<")]
346    fn lt<T>(self, other: T) -> dsl::Lt<Self, T>
347    where
348        Self::SqlType: SqlType,
349        T: AsExpression<Self::SqlType>,
350    {
351        Grouped(Lt::new(self, other.as_expression()))
352    }
353
354    /// Creates a SQL `<=` expression.
355    ///
356    /// # Example
357    ///
358    /// ```rust
359    /// # include!("../doctest_setup.rs");
360    /// #
361    /// # fn main() {
362    /// #     run_test().unwrap();
363    /// # }
364    /// #
365    /// # fn run_test() -> QueryResult<()> {
366    /// #     use schema::users::dsl::*;
367    /// #     let connection = &mut establish_connection();
368    /// let data = users
369    ///     .select(name)
370    ///     .filter(id.le(2))
371    ///     .first::<String>(connection)?;
372    /// assert_eq!("Sean", data);
373    /// #     Ok(())
374    /// # }
375    /// ```
376    #[doc(alias = "<=")]
377    fn le<T>(self, other: T) -> dsl::LtEq<Self, T>
378    where
379        Self::SqlType: SqlType,
380        T: AsExpression<Self::SqlType>,
381    {
382        Grouped(LtEq::new(self, other.as_expression()))
383    }
384
385    /// Creates a SQL `BETWEEN` expression using the given lower and upper
386    /// bounds.
387    ///
388    /// # Example
389    ///
390    /// ```rust
391    /// # include!("../doctest_setup.rs");
392    /// #
393    /// # fn main() {
394    /// #     use schema::animals::dsl::*;
395    /// #     let connection = &mut establish_connection();
396    /// #
397    /// let data = animals
398    ///     .select(species)
399    ///     .filter(legs.between(2, 6))
400    ///     .first(connection);
401    /// #
402    /// assert_eq!(Ok("dog".to_string()), data);
403    /// # }
404    /// ```
405    fn between<T, U>(self, lower: T, upper: U) -> dsl::Between<Self, T, U>
406    where
407        Self::SqlType: SqlType,
408        T: AsExpression<Self::SqlType>,
409        U: AsExpression<Self::SqlType>,
410    {
411        Grouped(Between::new(
412            self,
413            And::new(lower.as_expression(), upper.as_expression()),
414        ))
415    }
416
417    /// Creates a SQL `NOT BETWEEN` expression using the given lower and upper
418    /// bounds.
419    ///
420    /// # Example
421    ///
422    /// ```rust
423    /// # include!("../doctest_setup.rs");
424    /// #
425    /// # fn main() {
426    /// #     run_test().unwrap();
427    /// # }
428    /// #
429    /// # fn run_test() -> QueryResult<()> {
430    /// #     use schema::animals::dsl::*;
431    /// #     let connection = &mut establish_connection();
432    /// #
433    /// let data = animals
434    ///     .select(species)
435    ///     .filter(legs.not_between(2, 6))
436    ///     .first::<String>(connection)?;
437    /// assert_eq!("spider", data);
438    /// #     Ok(())
439    /// # }
440    /// ```
441    fn not_between<T, U>(self, lower: T, upper: U) -> dsl::NotBetween<Self, T, U>
442    where
443        Self::SqlType: SqlType,
444        T: AsExpression<Self::SqlType>,
445        U: AsExpression<Self::SqlType>,
446    {
447        Grouped(NotBetween::new(
448            self,
449            And::new(lower.as_expression(), upper.as_expression()),
450        ))
451    }
452
453    /// Generates a `CAST(expr AS sql_type)` expression
454    ///
455    /// It is necessary that the expression's SQL type can be casted to the
456    /// target SQL type (represented by the [`CastsTo`](cast::CastsTo) trait),
457    /// and that we know how the corresponding SQL type is named for the
458    /// specific backend (represented by the
459    /// [`KnownCastSqlTypeName`](cast::KnownCastSqlTypeName) trait).
460    ///
461    /// # Example
462    ///
463    /// ```rust
464    /// # include!("../doctest_setup.rs");
465    /// #
466    /// # fn main() {
467    /// #     run_test().unwrap();
468    /// # }
469    /// #
470    /// # fn run_test() -> QueryResult<()> {
471    /// #     use schema::animals::dsl::*;
472    /// #     let connection = &mut establish_connection();
473    /// #
474    /// use diesel::sql_types;
475    ///
476    /// let data = diesel::select(
477    ///     12_i32
478    ///         .into_sql::<sql_types::Int4>()
479    ///         .cast::<sql_types::Text>(),
480    /// )
481    /// .first::<String>(connection)?;
482    /// assert_eq!("12", data);
483    /// #     Ok(())
484    /// # }
485    /// ```
486    fn cast<ST>(self) -> dsl::Cast<Self, ST>
487    where
488        ST: SingleValue,
489        Self::SqlType: cast::CastsTo<ST>,
490    {
491        cast::Cast::new(self)
492    }
493
494    /// Generates a `CAST(expr AS sql_type)` expression, this version does not check the castability, like [`cast()`](Self::cast).
495    ///
496    /// # Example
497    ///
498    /// ```rust
499    /// # include!("../doctest_setup.rs");
500    /// #
501    /// # fn main() {
502    /// #     run_test().unwrap();
503    /// # }
504    /// #
505    /// # fn run_test() -> QueryResult<()> {
506    /// #     use schema::animals::dsl::*;
507    /// #     let connection = &mut establish_connection();
508    /// #
509    /// use diesel::sql_types;
510    ///
511    /// let data = diesel::select(
512    ///     "12".into_sql::<sql_types::Text>()
513    ///         .fallible_cast::<sql_types::Int8>(),
514    /// )
515    /// .first::<i64>(connection)?;
516    /// assert_eq!(12i64, data);
517    /// #     Ok(())
518    /// # }
519    /// ```
520    fn fallible_cast<ST>(self) -> dsl::Cast<Self, ST>
521    where
522        ST: SingleValue,
523        Self::SqlType: cast::FallibleCastsTo<ST>,
524    {
525        cast::Cast::new(self)
526    }
527
528    /// Creates a SQL `DESC` expression, representing this expression in
529    /// descending order.
530    ///
531    /// # Example
532    ///
533    /// ```rust
534    /// # include!("../doctest_setup.rs");
535    /// #
536    /// # fn main() {
537    /// #     run_test().unwrap();
538    /// # }
539    /// #
540    /// # fn run_test() -> QueryResult<()> {
541    /// #     use schema::users::dsl::*;
542    /// #     let connection = &mut establish_connection();
543    /// #
544    /// let names = users
545    ///     .select(name)
546    ///     .order(name.desc())
547    ///     .load::<String>(connection)?;
548    /// assert_eq!(vec!["Tess", "Sean"], names);
549    /// #     Ok(())
550    /// # }
551    /// ```
552    fn desc(self) -> dsl::Desc<Self> {
553        Desc::new(self)
554    }
555
556    /// Creates a SQL `ASC` expression, representing this expression in
557    /// ascending order.
558    ///
559    /// This is the same as leaving the direction unspecified. It is useful if
560    /// you need to provide an unknown ordering, and need to box the return
561    /// value of a function.
562    ///
563    /// # Example
564    ///
565    /// ```rust
566    /// # include!("../doctest_setup.rs");
567    /// # use diesel::expression::expression_types::NotSelectable;
568    /// #
569    /// # fn main() {
570    /// #     use schema::users::dsl::*;
571    /// #     let order = "name";
572    /// let ordering: Box<dyn BoxableExpression<users, DB, SqlType = NotSelectable>> =
573    ///     if order == "name" {
574    ///         Box::new(name.desc())
575    ///     } else {
576    ///         Box::new(id.asc())
577    ///     };
578    /// # }
579    /// ```
580    fn asc(self) -> dsl::Asc<Self> {
581        Asc::new(self)
582    }
583}
584
585impl<T> ExpressionMethods for T
586where
587    T: Expression,
588    T::SqlType: SingleValue,
589{
590}
591
592/// Methods present on all expressions
593pub trait NullableExpressionMethods: Expression + Sized {
594    /// Converts this potentially non-null expression into one which is treated
595    /// as nullable. This method has no impact on the generated SQL, and is only
596    /// used to allow certain comparisons that would otherwise fail to compile.
597    ///
598    /// # Example
599    /// ```no_run
600    /// # #![allow(dead_code)]
601    /// # include!("../doctest_setup.rs");
602    /// # use diesel::sql_types::*;
603    /// # use schema::users;
604    /// #
605    /// table! {
606    ///     posts {
607    ///         id -> Integer,
608    ///         user_id -> Integer,
609    ///         author_name -> Nullable<VarChar>,
610    ///     }
611    /// }
612    /// #
613    /// # joinable!(posts -> users (user_id));
614    /// # allow_tables_to_appear_in_same_query!(posts, users);
615    ///
616    /// fn main() {
617    ///     use self::posts::dsl::{author_name, posts};
618    ///     use self::users::dsl::*;
619    ///     let connection = &mut establish_connection();
620    ///
621    ///     let data = users
622    ///         .inner_join(posts)
623    ///         .filter(name.nullable().eq(author_name))
624    ///         .select(name)
625    ///         .load::<String>(connection);
626    ///     println!("{:?}", data);
627    /// }
628    /// ```
629    fn nullable(self) -> dsl::Nullable<Self> {
630        nullable::Nullable::new(self)
631    }
632
633    /// Converts this potentially nullable expression into one which will be **assumed**
634    /// to be not-null. This method has no impact on the generated SQL, however it will
635    /// enable you to attempt deserialization of the returned value in a non-`Option`.
636    ///
637    /// This is meant to cover for cases where you know that given the `WHERE` clause
638    /// the field returned by the database will never be `NULL`.
639    ///
640    /// This **will cause runtime errors** on `load()` if the "assume" turns out to be incorrect.
641    ///
642    /// # Examples
643    /// ## Normal usage
644    /// ```rust
645    /// # #![allow(dead_code)]
646    /// # include!("../doctest_setup.rs");
647    /// # use diesel::sql_types::*;
648    /// #
649    /// table! {
650    ///     animals {
651    ///         id -> Integer,
652    ///         species -> VarChar,
653    ///         legs -> Integer,
654    ///         name -> Nullable<VarChar>,
655    ///     }
656    /// }
657    ///
658    /// fn main() {
659    ///     use self::animals::dsl::*;
660    ///     let connection = &mut establish_connection();
661    ///
662    ///     let result = animals
663    ///         .filter(name.is_not_null())
664    ///         .select(name.assume_not_null())
665    ///         .load::<String>(connection);
666    ///     assert!(result.is_ok());
667    /// }
668    /// ```
669    ///
670    /// ## Incorrect usage
671    /// ```rust
672    /// # #![allow(dead_code)]
673    /// # include!("../doctest_setup.rs");
674    /// # use diesel::sql_types::*;
675    /// #
676    /// table! {
677    ///     animals {
678    ///         id -> Integer,
679    ///         species -> VarChar,
680    ///         legs -> Integer,
681    ///         name -> Nullable<VarChar>,
682    ///     }
683    /// }
684    ///
685    /// fn main() {
686    ///     use diesel::result::{Error, UnexpectedNullError};
687    ///     use self::animals::dsl::*;
688    ///     let connection = &mut establish_connection();
689    ///
690    ///     let result = animals
691    ///         .select(name.assume_not_null())
692    ///         .load::<String>(connection);
693    ///     assert!(matches!(
694    ///         result,
695    ///         Err(Error::DeserializationError(err)) if err.is::<UnexpectedNullError>()
696    ///     ));
697    /// }
698    /// ```
699    ///
700    /// ## Advanced usage - use only if you're sure you know what you're doing!
701    ///
702    /// This will cause the `Option` to be `None` where the `left_join` succeeded but the
703    /// `author_name` turned out to be `NULL`, due to how `Option` deserialization works.
704    /// (see [`Queryable` documentation](crate::deserialize::Queryable))
705    ///
706    /// ```rust
707    /// # #![allow(dead_code)]
708    /// # include!("../doctest_setup.rs");
709    /// # use diesel::sql_types::*;
710    /// # use schema::users;
711    /// #
712    /// table! {
713    ///     posts {
714    ///         id -> Integer,
715    ///         user_id -> Integer,
716    ///         author_name -> Nullable<Text>,
717    ///     }
718    /// }
719    /// #
720    /// # joinable!(posts -> users (user_id));
721    /// # allow_tables_to_appear_in_same_query!(posts, users);
722    ///
723    /// fn main() {
724    ///     use self::posts;
725    ///     use self::users;
726    ///     let connection = &mut establish_connection();
727    ///
728    /// #   diesel::sql_query("ALTER TABLE posts ADD COLUMN author_name Text")
729    /// #       .execute(connection)
730    /// #       .unwrap();
731    /// #   diesel::update(posts::table.filter(posts::user_id.eq(1)))
732    /// #       .set(posts::author_name.eq("Sean"))
733    /// #       .execute(connection);
734    ///
735    ///     let result = posts::table
736    ///         .left_join(users::table)
737    ///         .select((
738    ///             posts::id,
739    ///             (users::id, posts::author_name.assume_not_null()).nullable(),
740    ///         ))
741    ///         .order_by(posts::id)
742    ///         .load::<(i32, Option<(i32, String)>)>(connection);
743    ///     let expected = Ok(vec![
744    ///         (1, Some((1, "Sean".to_owned()))),
745    ///         (2, Some((1, "Sean".to_owned()))),
746    ///         (3, None),
747    ///     ]);
748    ///     assert_eq!(expected, result);
749    /// }
750    /// ```
751    fn assume_not_null(self) -> dsl::AssumeNotNull<Self> {
752        assume_not_null::AssumeNotNull::new(self)
753    }
754}
755
756impl<T: Expression> NullableExpressionMethods for T {}