Skip to main content

diesel/expression/
mod.rs

1//! AST types representing various typed SQL expressions.
2//!
3//! Almost all types implement either [`Expression`] or
4//! [`AsExpression`].
5//!
6//! The most common expression to work with is a
7//! [`Column`](crate::query_source::Column). There are various methods
8//! that you can call on these, found in
9//! [`expression_methods`](crate::expression_methods).
10//!
11//! You can also use numeric operators such as `+` on expressions of the
12//! appropriate type.
13//!
14//! Any primitive which implements [`ToSql`](crate::serialize::ToSql) will
15//! also implement [`AsExpression`], allowing it to be
16//! used as an argument to any of the methods described here.
17#[macro_use]
18pub(crate) mod ops;
19pub mod functions;
20
21#[cfg(not(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"))]
22pub(crate) mod array_comparison;
23#[cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")]
24pub mod array_comparison;
25pub(crate) mod assume_not_null;
26pub(crate) mod bound;
27mod coerce;
28pub(crate) mod count;
29#[cfg(not(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes"))]
30pub(crate) mod exists;
31#[cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")]
32pub mod exists;
33pub(crate) mod grouped;
34pub(crate) mod helper_types;
35mod not;
36pub(crate) mod nullable;
37#[macro_use]
38pub(crate) mod operators;
39mod case_when;
40pub(crate) mod cast;
41pub(crate) mod select_by;
42mod sql_literal;
43pub(crate) mod subselect;
44
45#[cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")]
46pub use self::operators::Concat;
47
48pub use self::operators::Collate;
49
50// we allow unreachable_pub here
51// as rustc otherwise shows false positives
52// for every item in this module. We reexport
53// everything from `crate::helper_types::`
54#[allow(non_camel_case_types, unreachable_pub)]
55pub(crate) mod dsl {
56    use crate::dsl::SqlTypeOf;
57
58    #[doc(inline)]
59    pub use super::case_when::case_when;
60    #[doc(inline)]
61    pub use super::count::*;
62    #[doc(inline)]
63    pub use super::exists::exists;
64    #[doc(inline)]
65    pub use super::functions::aggregate_folding::*;
66    #[doc(inline)]
67    pub use super::functions::aggregate_ordering::*;
68    #[doc(inline)]
69    pub use super::functions::date_and_time::*;
70    #[doc(inline)]
71    pub use super::functions::window_functions::*;
72    #[doc(inline)]
73    pub use super::not::not;
74    #[doc(inline)]
75    pub use super::sql_literal::sql;
76
77    #[cfg(feature = "postgres_backend")]
78    #[allow(ambiguous_glob_reexports)]
79    pub use crate::pg::expression::dsl::*;
80
81    #[cfg(feature = "__sqlite-shared")]
82    pub use crate::sqlite::expression::dsl::*;
83
84    /// The return type of [`count(expr)`](crate::dsl::count())
85    pub type count<Expr> = super::count::count<SqlTypeOf<Expr>, Expr>;
86
87    /// The return type of [`count_star()`](crate::dsl::count_star())
88    pub type count_star = super::count::CountStar;
89
90    #[cfg(all(feature = "with-deprecated", not(feature = "without-deprecated")))]
91    #[deprecated]
92    #[doc(hidden)]
93    pub type count_distinct<Expr> = super::count::CountDistinct<SqlTypeOf<Expr>, Expr>;
94
95    /// The return type of [`date(expr)`](crate::dsl::date())
96    pub type date<Expr> = super::functions::date_and_time::date<Expr>;
97
98    #[cfg(feature = "mysql_backend")]
99    pub use crate::mysql::query_builder::DuplicatedKeys;
100
101    pub use super::functions::aggregate_expressions::frame_clause::{
102        FrameBoundDsl, FrameClauseDsl,
103    };
104
105    /// Different frame clause specifications for window functions
106    pub mod frame {
107        pub use super::super::functions::aggregate_expressions::frame_clause::{
108            CurrentRow, ExcludeCurrentRow, ExcludeGroup, ExcludeNoOthers, ExcludeTies, Groups,
109            Range, Rows, UnboundedFollowing, UnboundedPreceding,
110        };
111    }
112}
113
114#[doc(inline)]
115pub use self::case_when::CaseWhen;
116#[doc(inline)]
117pub use self::cast::{CastsTo, FallibleCastsTo, KnownCastSqlTypeName};
118#[doc(inline)]
119pub use self::sql_literal::{SqlLiteral, UncheckedBind};
120
121use crate::backend::Backend;
122use crate::dsl::{AsExprOf, AsSelect};
123use crate::sql_types::{HasSqlType, SingleValue, SqlType};
124use alloc::boxed::Box;
125use alloc::vec::Vec;
126
127/// Represents a typed fragment of SQL.
128///
129/// Apps should not need to implement this type directly, but it may be common
130/// to use this in where clauses. Libraries should consider using
131/// [`infix_operator!`](crate::infix_operator!) or
132/// [`postfix_operator!`](crate::postfix_operator!) instead of
133/// implementing this directly.
134pub trait Expression {
135    /// The type that this expression represents in SQL
136    type SqlType: TypedExpressionType;
137}
138
139/// Marker trait for possible types of [`Expression::SqlType`]
140pub trait TypedExpressionType {}
141
142/// Possible types for []`Expression::SqlType`]
143pub mod expression_types {
144    use super::{QueryMetadata, TypedExpressionType};
145    use crate::backend::Backend;
146    use crate::sql_types::SingleValue;
147    use alloc::vec::Vec;
148
149    /// Query nodes with this expression type do not have a statically at compile
150    /// time known expression type.
151    ///
152    /// An example for such a query node in diesel itself, is `sql_query` as
153    /// we do not know which fields are returned from such a query at compile time.
154    ///
155    /// For loading values from queries returning a type of this expression, consider
156    /// using [`#[derive(QueryableByName)]`](derive@crate::deserialize::QueryableByName)
157    /// on the corresponding result type.
158    #[derive(#[automatically_derived]
impl ::core::clone::Clone for Untyped {
    #[inline]
    fn clone(&self) -> Untyped { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Untyped { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for Untyped {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f, "Untyped")
    }
}Debug)]
159    pub struct Untyped;
160
161    /// Query nodes which cannot be part of a select clause.
162    ///
163    /// If you see an error message containing `FromSqlRow` and this type
164    /// recheck that you have written a valid select clause
165    ///
166    /// These may notably be used as intermediate Expression nodes of the query builder
167    /// which do not map to actual SQL expressions (for implementation simplicity).
168    #[derive(#[automatically_derived]
impl ::core::fmt::Debug for NotSelectable {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f, "NotSelectable")
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for NotSelectable {
    #[inline]
    fn clone(&self) -> NotSelectable { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for NotSelectable { }Copy)]
169    pub struct NotSelectable;
170
171    impl TypedExpressionType for Untyped {}
172    impl TypedExpressionType for NotSelectable {}
173
174    impl<ST> TypedExpressionType for ST where ST: SingleValue {}
175
176    impl<DB: Backend> QueryMetadata<Untyped> for DB {
177        fn row_metadata(_: &mut DB::MetadataLookup, row: &mut Vec<Option<DB::TypeMetadata>>) {
178            row.push(None)
179        }
180    }
181}
182
183impl<T: Expression + ?Sized> Expression for Box<T> {
184    type SqlType = T::SqlType;
185}
186
187impl<T: Expression + ?Sized> Expression for &T {
188    type SqlType = T::SqlType;
189}
190
191/// A helper to translate type level sql type information into
192/// runtime type information for specific queries
193///
194/// If you do not implement a custom backend implementation
195/// this trait is likely not relevant for you.
196pub trait QueryMetadata<T>: Backend {
197    /// The exact return value of this function is considered to be a
198    /// backend specific implementation detail. You should not rely on those
199    /// values if you not own the corresponding backend
200    fn row_metadata(lookup: &mut Self::MetadataLookup, out: &mut Vec<Option<Self::TypeMetadata>>);
201}
202
203impl<T, DB> QueryMetadata<T> for DB
204where
205    DB: Backend + HasSqlType<T>,
206    T: SingleValue,
207{
208    fn row_metadata(lookup: &mut Self::MetadataLookup, out: &mut Vec<Option<Self::TypeMetadata>>) {
209        out.push(Some(<DB as HasSqlType<T>>::metadata(lookup)))
210    }
211}
212
213/// Converts a type to its representation for use in Diesel's query builder.
214///
215/// This trait is used directly. Apps should typically use [`IntoSql`] instead.
216///
217/// Implementations of this trait will generally do one of 3 things:
218///
219/// - Return `self` for types which are already parts of Diesel's query builder
220/// - Perform some implicit coercion (for example, allowing [`now`] to be used as
221///   both [`Timestamp`] and [`Timestamptz`].
222/// - Indicate that the type has data which will be sent separately from the
223///   query. This is generally referred as a "bind parameter". Types which
224///   implement [`ToSql`] will generally implement `AsExpression` this way.
225///
226///   [`IntoSql`]: crate::IntoSql
227///   [`now`]: crate::dsl::now
228///   [`Timestamp`]: crate::sql_types::Timestamp
229///   [`Timestamptz`]: ../pg/types/sql_types/struct.Timestamptz.html
230///   [`ToSql`]: crate::serialize::ToSql
231///
232///  This trait could be [derived](derive@AsExpression)
233pub trait AsExpression<T>
234where
235    T: SqlType + TypedExpressionType,
236{
237    /// The expression being returned
238    type Expression: Expression<SqlType = T>;
239
240    /// Perform the conversion
241    #[allow(clippy::wrong_self_convention)]
242    // That's public API we cannot change it to appease clippy
243    fn as_expression(self) -> Self::Expression;
244}
245
246#[doc(inline)]
247pub use diesel_derives::AsExpression;
248
249#[diagnostic::do_not_recommend]
250impl<T, ST> AsExpression<ST> for T
251where
252    T: Expression<SqlType = ST>,
253    ST: SqlType + TypedExpressionType,
254{
255    type Expression = T;
256
257    fn as_expression(self) -> T {
258        self
259    }
260}
261
262/// Converts a type to its representation for use in Diesel's query builder.
263///
264/// This trait only exists to make usage of `AsExpression` more ergonomic when
265/// the `SqlType` cannot be inferred. It is generally used when you need to use
266/// a Rust value as the left hand side of an expression, or when you want to
267/// select a constant value.
268///
269/// # Example
270///
271/// ```rust
272/// # include!("../doctest_setup.rs");
273/// # use schema::users;
274/// #
275/// # fn main() {
276/// use diesel::sql_types::Text;
277/// #   let conn = &mut establish_connection();
278/// let names = users::table
279///     .select("The Amazing ".into_sql::<Text>().concat(users::name))
280///     .load(conn);
281/// let expected_names = vec![
282///     "The Amazing Sean".to_string(),
283///     "The Amazing Tess".to_string(),
284/// ];
285/// assert_eq!(Ok(expected_names), names);
286/// # }
287/// ```
288pub trait IntoSql {
289    /// Convert `self` to an expression for Diesel's query builder.
290    ///
291    /// There is no difference in behavior between `x.into_sql::<Y>()` and
292    /// `AsExpression::<Y>::as_expression(x)`.
293    fn into_sql<T>(self) -> AsExprOf<Self, T>
294    where
295        Self: AsExpression<T> + Sized,
296        T: SqlType + TypedExpressionType,
297    {
298        self.as_expression()
299    }
300
301    /// Convert `&self` to an expression for Diesel's query builder.
302    ///
303    /// There is no difference in behavior between `x.as_sql::<Y>()` and
304    /// `AsExpression::<Y>::as_expression(&x)`.
305    fn as_sql<'a, T>(&'a self) -> AsExprOf<&'a Self, T>
306    where
307        &'a Self: AsExpression<T>,
308        T: SqlType + TypedExpressionType,
309    {
310        <&'a Self as AsExpression<T>>::as_expression(self)
311    }
312}
313
314impl<T> IntoSql for T {}
315
316/// Indicates that all elements of an expression are valid given a from clause.
317///
318/// This is used to ensure that `users.filter(posts::id.eq(1))` fails to
319/// compile. This constraint is only used in places where the nullability of a
320/// SQL type doesn't matter (everything except `select` and `returning`). For
321/// places where nullability is important, `SelectableExpression` is used
322/// instead.
323pub trait AppearsOnTable<QS: ?Sized>: Expression {}
324
325impl<T: ?Sized, QS> AppearsOnTable<QS> for Box<T>
326where
327    T: AppearsOnTable<QS>,
328    Box<T>: Expression,
329{
330}
331
332impl<'a, T: ?Sized, QS> AppearsOnTable<QS> for &'a T
333where
334    T: AppearsOnTable<QS>,
335    &'a T: Expression,
336{
337}
338
339/// Indicates that an expression can be selected from a source.
340///
341/// Columns will implement this for their table. Certain special types, like
342/// `CountStar` and `Bound` will implement this for all sources. Most compound
343/// expressions will implement this if each of their parts implement it.
344///
345/// Notably, columns will not implement this trait for the right side of a left
346/// join. To select a column or expression using a column from the right side of
347/// a left join, you must call `.nullable()` on it.
348#[diagnostic::on_unimplemented(
349    message = "cannot select `{Self}` from `{QS}`",
350    note = "`{Self}` is no valid selection for `{QS}`"
351)]
352pub trait SelectableExpression<QS: ?Sized>: AppearsOnTable<QS> {}
353
354impl<T: ?Sized, QS> SelectableExpression<QS> for Box<T>
355where
356    T: SelectableExpression<QS>,
357    Box<T>: AppearsOnTable<QS>,
358{
359}
360
361impl<'a, T: ?Sized, QS> SelectableExpression<QS> for &'a T
362where
363    T: SelectableExpression<QS>,
364    &'a T: AppearsOnTable<QS>,
365{
366}
367
368/// Trait indicating that a record can be selected and queried from the database.
369///
370/// Types which implement `Selectable` represent the select clause of a SQL query.
371/// Use [`SelectableHelper::as_select()`] to construct the select clause. Once you
372/// called `.select(YourType::as_select())` we enforce at the type system level that you
373/// use the same type to load the query result into.
374///
375/// The constructed select clause can contain arbitrary expressions coming from different
376/// tables. The corresponding [derive](derive@Selectable) provides a simple way to
377/// construct a select clause matching fields to the corresponding table columns.
378///
379/// # Examples
380///
381/// If you just want to construct a select clause using an existing struct, you can use
382/// `#[derive(Selectable)]`, See [`#[derive(Selectable)]`](derive@Selectable) for details.
383///
384///
385/// ```rust
386/// # include!("../doctest_setup.rs");
387/// #
388/// use schema::users;
389///
390/// #[derive(Queryable, PartialEq, Debug, Selectable)]
391/// struct User {
392///     id: i32,
393///     name: String,
394/// }
395///
396/// # fn main() {
397/// #     run_test();
398/// # }
399/// #
400/// # fn run_test() -> QueryResult<()> {
401/// #     use schema::users::dsl::*;
402/// #     let connection = &mut establish_connection();
403/// let first_user = users.select(User::as_select()).first(connection)?;
404/// let expected = User {
405///     id: 1,
406///     name: "Sean".into(),
407/// };
408/// assert_eq!(expected, first_user);
409/// #     Ok(())
410/// # }
411/// ```
412///
413/// Alternatively, we can implement the trait for our struct manually.
414///
415/// ```rust
416/// # include!("../doctest_setup.rs");
417/// #
418/// use diesel::backend::Backend;
419/// use diesel::prelude::{Queryable, Selectable};
420/// use schema::users;
421///
422/// #[derive(Queryable, PartialEq, Debug)]
423/// struct User {
424///     id: i32,
425///     name: String,
426/// }
427///
428/// impl<DB> Selectable<DB> for User
429/// where
430///     DB: Backend,
431/// {
432///     type SelectExpression = (users::id, users::name);
433///
434///     fn construct_selection() -> Self::SelectExpression {
435///         (users::id, users::name)
436///     }
437/// }
438///
439/// # fn main() {
440/// #     run_test();
441/// # }
442/// #
443/// # fn run_test() -> QueryResult<()> {
444/// #     use schema::users::dsl::*;
445/// #     let connection = &mut establish_connection();
446/// let first_user = users.select(User::as_select()).first(connection)?;
447/// let expected = User {
448///     id: 1,
449///     name: "Sean".into(),
450/// };
451/// assert_eq!(expected, first_user);
452/// #     Ok(())
453/// # }
454/// ```
455///
456/// When selecting from joined tables, you can select from a
457/// composition of types that implement `Selectable`. The simplest way
458/// is to use a tuple of all the types you wish to select.
459///
460/// ```rust
461/// # include!("../doctest_setup.rs");
462/// use schema::{posts, users};
463///
464/// #[derive(Debug, PartialEq, Queryable, Selectable)]
465/// struct User {
466///     id: i32,
467///     name: String,
468/// }
469///
470/// #[derive(Debug, PartialEq, Queryable, Selectable)]
471/// struct Post {
472///     id: i32,
473///     user_id: i32,
474///     title: String,
475/// }
476///
477/// # fn main() -> QueryResult<()> {
478/// #     let connection = &mut establish_connection();
479/// #
480/// let (first_user, first_post) = users::table
481///     .inner_join(posts::table)
482///     .select(<(User, Post)>::as_select())
483///     .first(connection)?;
484///
485/// let expected_user = User {
486///     id: 1,
487///     name: "Sean".into(),
488/// };
489/// assert_eq!(expected_user, first_user);
490///
491/// let expected_post = Post {
492///     id: 1,
493///     user_id: 1,
494///     title: "My first post".into(),
495/// };
496/// assert_eq!(expected_post, first_post);
497/// #
498/// #     Ok(())
499/// # }
500/// ```
501///
502/// If you want to load only a subset of fields, you can create types
503/// with those fields and use them in the composition.
504///
505/// ```rust
506/// # include!("../doctest_setup.rs");
507/// use schema::{posts, users};
508///
509/// #[derive(Debug, PartialEq, Queryable, Selectable)]
510/// struct User {
511///     id: i32,
512///     name: String,
513/// }
514///
515/// #[derive(Debug, PartialEq, Queryable, Selectable)]
516/// #[diesel(table_name = posts)]
517/// struct PostTitle {
518///     title: String,
519/// }
520///
521/// # fn main() -> QueryResult<()> {
522/// #     let connection = &mut establish_connection();
523/// #
524/// let (first_user, first_post_title) = users::table
525///     .inner_join(posts::table)
526///     .select(<(User, PostTitle)>::as_select())
527///     .first(connection)?;
528///
529/// let expected_user = User {
530///     id: 1,
531///     name: "Sean".into(),
532/// };
533/// assert_eq!(expected_user, first_user);
534///
535/// let expected_post_title = PostTitle {
536///     title: "My first post".into(),
537/// };
538/// assert_eq!(expected_post_title, first_post_title);
539/// #
540/// #     Ok(())
541/// # }
542/// ```
543///
544/// You are not limited to using only tuples to build the composed
545/// type. The [`Selectable`](derive@Selectable) derive macro allows
546/// you to *embed* other types. This is useful when you want to
547/// implement methods or traits on the composed type.
548///
549/// ```rust
550/// # include!("../doctest_setup.rs");
551/// use schema::{posts, users};
552///
553/// #[derive(Debug, PartialEq, Queryable, Selectable)]
554/// struct User {
555///     id: i32,
556///     name: String,
557/// }
558///
559/// #[derive(Debug, PartialEq, Queryable, Selectable)]
560/// #[diesel(table_name = posts)]
561/// struct PostTitle {
562///     title: String,
563/// }
564///
565/// #[derive(Debug, PartialEq, Queryable, Selectable)]
566/// struct UserPost {
567///     #[diesel(embed)]
568///     user: User,
569///     #[diesel(embed)]
570///     post_title: PostTitle,
571/// }
572///
573/// # fn main() -> QueryResult<()> {
574/// #     let connection = &mut establish_connection();
575/// #
576/// let first_user_post = users::table
577///     .inner_join(posts::table)
578///     .select(UserPost::as_select())
579///     .first(connection)?;
580///
581/// let expected_user_post = UserPost {
582///     user: User {
583///         id: 1,
584///         name: "Sean".into(),
585///     },
586///     post_title: PostTitle {
587///         title: "My first post".into(),
588///     },
589/// };
590/// assert_eq!(expected_user_post, first_user_post);
591/// #
592/// #     Ok(())
593/// # }
594/// ```
595///
596/// It is also possible to specify an entirely custom select expression
597/// for fields when deriving [`Selectable`](derive@Selectable).
598/// This is useful for example to
599///
600///  * avoid nesting types, or to
601///  * populate fields with values other than table columns, such as
602///    the result of an SQL function like `CURRENT_TIMESTAMP()`
603///    or a custom SQL function.
604///
605/// The select expression is specified via the `select_expression` parameter.
606///
607/// Query fragments created using [`dsl::auto_type`](crate::dsl::auto_type) are supported, which
608/// may be useful as the select expression gets large: it may not be practical to inline it in
609/// the attribute then.
610///
611/// The type of the expression is usually inferred. If it can't be fully inferred automatically,
612/// one may either:
613/// - Put type annotations in inline blocks in the query fragment itself
614/// - Use a dedicated [`dsl::auto_type`](crate::dsl::auto_type) function as `select_expression`
615///   and use [`dsl::auto_type`'s type annotation features](crate::dsl::auto_type)
616/// - Specify the type of the expression using the `select_expression_type` attribute
617///
618/// ```rust
619/// # include!("../doctest_setup.rs");
620/// use diesel::dsl;
621/// use schema::{posts, users};
622///
623/// #[derive(Debug, PartialEq, Queryable, Selectable)]
624/// struct User {
625///     id: i32,
626///     name: String,
627/// }
628///
629/// #[derive(Debug, PartialEq, Queryable, Selectable)]
630/// #[diesel(table_name = posts)]
631/// struct PostTitle {
632///     title: String,
633/// }
634///
635/// #[derive(Debug, PartialEq, Queryable, Selectable)]
636/// struct UserPost {
637///     #[diesel(select_expression = users::columns::id)]
638///     #[diesel(select_expression_type = users::columns::id)]
639///     id: i32,
640///     #[diesel(select_expression = users::columns::name)]
641///     name: String,
642///     #[diesel(select_expression = complex_fragment_for_title())]
643///     title: String,
644/// #   #[cfg(feature = "chrono")]
645///     #[diesel(select_expression = diesel::dsl::now)]
646///     access_time: chrono::NaiveDateTime,
647///     #[diesel(select_expression = users::columns::id.eq({let id: i32 = FOO; id}))]
648///     user_id_is_foo: bool,
649/// }
650/// const FOO: i32 = 42; // Type of FOO can't be inferred automatically in the select_expression
651/// #[dsl::auto_type]
652/// fn complex_fragment_for_title() -> _ {
653///     // See the `#[dsl::auto_type]` documentation for examples of more complex usage
654///     posts::columns::title
655/// }
656///
657/// # fn main() -> QueryResult<()> {
658/// #     let connection = &mut establish_connection();
659/// #
660/// let first_user_post = users::table
661///     .inner_join(posts::table)
662///     .select(UserPost::as_select())
663///     .first(connection)?;
664///
665/// let expected_user_post = UserPost {
666///     id: 1,
667///     name: "Sean".into(),
668///     title: "My first post".into(),
669/// #   #[cfg(feature = "chrono")]
670///     access_time: first_user_post.access_time,
671///     user_id_is_foo: false,
672/// };
673/// assert_eq!(expected_user_post, first_user_post);
674/// #
675/// #     Ok(())
676/// # }
677/// ```
678pub trait Selectable<DB: Backend> {
679    /// The expression you'd like to select.
680    ///
681    /// This is typically a tuple of corresponding to the table columns of your struct's fields.
682    type SelectExpression: Expression;
683
684    /// Construct an instance of the expression
685    fn construct_selection() -> Self::SelectExpression;
686}
687
688#[doc(inline)]
689pub use diesel_derives::Selectable;
690
691/// This helper trait provides several methods for
692/// constructing a select or returning clause based on a
693/// [`Selectable`] implementation.
694pub trait SelectableHelper<DB: Backend>: Selectable<DB> + Sized {
695    /// Construct a select clause based on a [`Selectable`] implementation.
696    ///
697    /// The returned select clause enforces that you use the same type
698    /// for constructing the select clause and for loading the query result into.
699    fn as_select() -> AsSelect<Self, DB>;
700
701    /// An alias for `as_select` that can be used with returning clauses
702    fn as_returning() -> AsSelect<Self, DB> {
703        Self::as_select()
704    }
705}
706
707impl<T, DB> SelectableHelper<DB> for T
708where
709    T: Selectable<DB>,
710    DB: Backend,
711{
712    fn as_select() -> AsSelect<Self, DB> {
713        select_by::SelectBy::new()
714    }
715}
716
717/// Is this expression valid for a given group by clause?
718///
719/// Implementations of this trait must ensure that aggregate expressions are
720/// not mixed with non-aggregate expressions.
721///
722/// For generic types, you can determine if your sub-expressions can appear
723/// together using the [`MixedAggregates`] trait.
724///
725/// `GroupByClause` will be a tuple containing the set of expressions appearing
726/// in the `GROUP BY` portion of the query. If there is no `GROUP BY`, it will
727/// be `()`.
728///
729/// This trait can be [derived]
730///
731/// [derived]: derive@ValidGrouping
732pub trait ValidGrouping<GroupByClause> {
733    /// Is this expression aggregate?
734    ///
735    /// This type should always be one of the structs in the [`is_aggregate`]
736    /// module. See the documentation of those structs for more details.
737    type IsAggregate;
738}
739
740impl<T: ValidGrouping<GB> + ?Sized, GB> ValidGrouping<GB> for Box<T> {
741    type IsAggregate = T::IsAggregate;
742}
743
744impl<T: ValidGrouping<GB> + ?Sized, GB> ValidGrouping<GB> for &T {
745    type IsAggregate = T::IsAggregate;
746}
747
748impl<GB> ValidGrouping<GB> for () {
749    type IsAggregate = is_aggregate::Never;
750}
751
752#[doc(inline)]
753pub use diesel_derives::ValidGrouping;
754
755#[doc(hidden)]
756#[diagnostic::on_unimplemented(
757    note = "if your query contains columns from several tables in your group by or select \
758            clause make sure to call `allow_columns_to_appear_in_same_group_by_clause!` \
759            with these columns"
760)]
761pub trait IsContainedInGroupBy<T> {
762    type Output;
763}
764
765#[doc(hidden)]
766#[allow(missing_debug_implementations, missing_copy_implementations)]
767pub mod is_contained_in_group_by {
768    pub struct Yes;
769    pub struct No;
770
771    pub trait IsAny<O> {
772        type Output;
773    }
774
775    impl<T> IsAny<T> for Yes {
776        type Output = Yes;
777    }
778
779    impl IsAny<Yes> for No {
780        type Output = Yes;
781    }
782
783    impl IsAny<No> for No {
784        type Output = No;
785    }
786}
787
788/// Can two `IsAggregate` types appear in the same expression?
789///
790/// You should never implement this trait. It will eventually become a trait
791/// alias.
792///
793/// [`is_aggregate::Yes`] and [`is_aggregate::No`] can only appear with
794/// themselves or [`is_aggregate::Never`]. [`is_aggregate::Never`] can appear
795/// with anything.
796#[diagnostic::on_unimplemented(
797    message = "mixing aggregate and not aggregate expressions is not allowed in SQL",
798    note = "you tried to combine expressions that aggregate over a certain column with expressions that don't aggregate over that column",
799    note = "try to either use aggregate functions like `min`/`max`/… for this column or add the column to your `GROUP BY` clause",
800    note = "also there are clauses like `WHERE` or `RETURNING` that does not accept aggregate expressions at all"
801)]
802pub trait MixedAggregates<Other> {
803    /// What is the resulting `IsAggregate` type?
804    type Output;
805}
806
807#[allow(missing_debug_implementations, missing_copy_implementations)]
808/// Possible values for `ValidGrouping::IsAggregate`
809pub mod is_aggregate {
810    use super::MixedAggregates;
811
812    /// Yes, this expression is aggregate for the given group by clause.
813    pub struct Yes;
814
815    /// No, this expression is not aggregate with the given group by clause,
816    /// but it might be aggregate with a different group by clause.
817    pub struct No;
818
819    /// This expression is never aggregate, and can appear with any other
820    /// expression, regardless of whether it is aggregate.
821    ///
822    /// Examples of this are literals. `1` does not care about aggregation.
823    /// `foo + 1` is always valid, regardless of whether `foo` appears in the
824    /// group by clause or not.
825    pub struct Never;
826
827    impl MixedAggregates<Yes> for Yes {
828        type Output = Yes;
829    }
830
831    impl MixedAggregates<Never> for Yes {
832        type Output = Yes;
833    }
834
835    impl MixedAggregates<No> for No {
836        type Output = No;
837    }
838
839    impl MixedAggregates<Never> for No {
840        type Output = No;
841    }
842
843    impl<T> MixedAggregates<T> for Never {
844        type Output = T;
845    }
846}
847
848#[cfg(feature = "unstable")]
849// this needs to be a separate module for the reasons given in
850// https://github.com/rust-lang/rust/issues/65860
851mod unstable;
852
853#[cfg(feature = "unstable")]
854#[doc(inline)]
855pub use self::unstable::NonAggregate;
856
857// Note that these docs are similar to but slightly different than the unstable
858// docs above. Make sure if you change these that you also change the docs
859// above.
860/// Trait alias to represent an expression that isn't aggregate by default.
861///
862/// This trait should never be implemented directly. It is replaced with a
863/// trait alias when the `unstable` feature is enabled.
864///
865/// This alias represents a type which is not aggregate if there is no group by
866/// clause. More specifically, it represents for types which implement
867/// [`ValidGrouping<()>`] where `IsAggregate` is [`is_aggregate::No`] or
868/// [`is_aggregate::Yes`].
869///
870/// While this trait is a useful stand-in for common cases, `T: NonAggregate`
871/// cannot always be used when `T: ValidGrouping<(), IsAggregate = No>` or
872/// `T: ValidGrouping<(), IsAggregate = Never>` could be. For that reason,
873/// unless you need to abstract over both columns and literals, you should
874/// prefer to use [`ValidGrouping<()>`] in your bounds instead.
875///
876/// [`ValidGrouping<()>`]: ValidGrouping
877#[cfg(not(feature = "unstable"))]
878pub trait NonAggregate: ValidGrouping<()> {}
879
880#[cfg(not(feature = "unstable"))]
881impl<T> NonAggregate for T
882where
883    T: ValidGrouping<()>,
884    T::IsAggregate: MixedAggregates<is_aggregate::No, Output = is_aggregate::No>,
885{
886}
887
888use crate::query_builder::{QueryFragment, QueryId};
889
890/// Helper trait used when boxing expressions.
891///
892/// In Rust you cannot create a trait object with more than one trait.
893/// This type has all of the additional traits you would want when using
894/// `Box<Expression>` as a single trait object.
895///
896/// By default `BoxableExpression` is not usable in queries that have a custom
897/// group by clause. Setting the generic parameters `GB` and `IsAggregate` allows
898/// to configure the expression to be used with a specific group by clause.
899///
900/// This is typically used as the return type of a function.
901/// For cases where you want to dynamically construct a query,
902/// [boxing the query] is usually more ergonomic.
903///
904/// [boxing the query]: crate::query_dsl::QueryDsl::into_boxed()
905///
906/// # Examples
907///
908/// ## Usage without group by clause
909///
910/// ```rust
911/// # include!("../doctest_setup.rs");
912/// # use schema::users;
913/// use diesel::sql_types::Bool;
914///
915/// # fn main() {
916/// #     run_test().unwrap();
917/// # }
918/// #
919/// # fn run_test() -> QueryResult<()> {
920/// #     let conn = &mut establish_connection();
921/// enum Search {
922///     Id(i32),
923///     Name(String),
924/// }
925///
926/// # /*
927/// type DB = diesel::sqlite::Sqlite;
928/// # */
929/// fn find_user(search: Search) -> Box<dyn BoxableExpression<users::table, DB, SqlType = Bool>> {
930///     match search {
931///         Search::Id(id) => Box::new(users::id.eq(id)),
932///         Search::Name(name) => Box::new(users::name.eq(name)),
933///     }
934/// }
935///
936/// let user_one = users::table.filter(find_user(Search::Id(1))).first(conn)?;
937/// assert_eq!((1, String::from("Sean")), user_one);
938///
939/// let tess = users::table
940///     .filter(find_user(Search::Name("Tess".into())))
941///     .first(conn)?;
942/// assert_eq!((2, String::from("Tess")), tess);
943/// #     Ok(())
944/// # }
945/// ```
946///
947/// ## Allow usage with group by clause
948///
949/// ```rust
950/// # include!("../doctest_setup.rs");
951///
952/// # use schema::users;
953/// use diesel::dsl;
954/// use diesel::expression::ValidGrouping;
955/// use diesel::sql_types::Text;
956///
957/// # fn main() {
958/// #     run_test().unwrap();
959/// # }
960/// #
961/// # fn run_test() -> QueryResult<()> {
962/// #     let conn = &mut establish_connection();
963/// enum NameOrConst {
964///     Name,
965///     Const(String),
966/// }
967///
968/// # /*
969/// type DB = diesel::sqlite::Sqlite;
970/// # */
971/// fn selection<GB>(
972///     selection: NameOrConst,
973/// ) -> Box<
974///     dyn BoxableExpression<
975///         users::table,
976///         DB,
977///         GB,
978///         <users::name as ValidGrouping<GB>>::IsAggregate,
979///         SqlType = Text,
980///     >,
981/// >
982/// where
983///     users::name: BoxableExpression<
984///             users::table,
985///             DB,
986///             GB,
987///             <users::name as ValidGrouping<GB>>::IsAggregate,
988///             SqlType = Text,
989///         > + ValidGrouping<GB>,
990/// {
991///     match selection {
992///         NameOrConst::Name => Box::new(users::name),
993///         NameOrConst::Const(name) => Box::new(name.into_sql::<Text>()),
994///     }
995/// }
996///
997/// let user_one = users::table
998///     .select(selection(NameOrConst::Name))
999///     .first::<String>(conn)?;
1000/// assert_eq!(String::from("Sean"), user_one);
1001///
1002/// let with_name = users::table
1003///     .group_by(users::name)
1004///     .select(selection(NameOrConst::Const("Jane Doe".into())))
1005///     .first::<String>(conn)?;
1006/// assert_eq!(String::from("Jane Doe"), with_name);
1007/// #     Ok(())
1008/// # }
1009/// ```
1010///
1011/// ## More advanced query source
1012///
1013/// This example is a bit contrived, but in general, if you want to for example filter based on
1014/// different criteria on a joined table, you can use `InnerJoinQuerySource` and
1015/// `LeftJoinQuerySource` in the QS parameter of `BoxableExpression`.
1016///
1017/// ```rust
1018/// # include!("../doctest_setup.rs");
1019/// # use schema::{users, posts};
1020/// use diesel::dsl::InnerJoinQuerySource;
1021/// use diesel::sql_types::Bool;
1022///
1023/// # fn main() {
1024/// #     run_test().unwrap();
1025/// # }
1026/// #
1027/// # fn run_test() -> QueryResult<()> {
1028/// #     let conn = &mut establish_connection();
1029/// enum UserPostFilter {
1030///     User(i32),
1031///     Post(i32),
1032/// }
1033///
1034/// # /*
1035/// type DB = diesel::sqlite::Sqlite;
1036/// # */
1037/// fn filter_user_posts(
1038///     filter: UserPostFilter,
1039/// ) -> Box<
1040///     dyn BoxableExpression<InnerJoinQuerySource<users::table, posts::table>, DB, SqlType = Bool>,
1041/// > {
1042///     match filter {
1043///         UserPostFilter::User(user_id) => Box::new(users::id.eq(user_id)),
1044///         UserPostFilter::Post(post_id) => Box::new(posts::id.eq(post_id)),
1045///     }
1046/// }
1047///
1048/// let post_by_user_one = users::table
1049///     .inner_join(posts::table)
1050///     .filter(filter_user_posts(UserPostFilter::User(2)))
1051///     .select((posts::title, users::name))
1052///     .first::<(String, String)>(conn)?;
1053///
1054/// assert_eq!(
1055///     ("My first post too".to_string(), "Tess".to_string()),
1056///     post_by_user_one
1057/// );
1058/// #     Ok(())
1059/// # }
1060/// ```
1061pub trait BoxableExpression<QS, DB, GB = (), IsAggregate = is_aggregate::No>
1062where
1063    DB: Backend,
1064    Self: Expression,
1065    Self: SelectableExpression<QS>,
1066    Self: QueryFragment<DB>,
1067    Self: Send,
1068{
1069}
1070
1071impl<QS, T, DB, GB, IsAggregate> BoxableExpression<QS, DB, GB, IsAggregate> for T
1072where
1073    DB: Backend,
1074    T: Expression,
1075    T: SelectableExpression<QS>,
1076    T: ValidGrouping<GB>,
1077    T: QueryFragment<DB>,
1078    T: Send,
1079    T::IsAggregate: MixedAggregates<IsAggregate, Output = IsAggregate>,
1080{
1081}
1082
1083impl<QS, ST, DB, GB, IsAggregate> QueryId
1084    for dyn BoxableExpression<QS, DB, GB, IsAggregate, SqlType = ST> + '_
1085{
1086    type QueryId = ();
1087
1088    const HAS_STATIC_QUERY_ID: bool = false;
1089}
1090
1091impl<QS, ST, DB, GB, IsAggregate> ValidGrouping<GB>
1092    for dyn BoxableExpression<QS, DB, GB, IsAggregate, SqlType = ST> + '_
1093{
1094    type IsAggregate = IsAggregate;
1095}
1096
1097/// Converts a tuple of values into a tuple of Diesel expressions.
1098#[deprecated(note = "Use `IntoArrayExpression` instead")]
1099#[cfg(all(feature = "with-deprecated", not(feature = "without-deprecated")))]
1100pub trait AsExpressionList<ST> {
1101    /// The final output expression
1102    type Expression;
1103
1104    /// Perform the conversion
1105    // That's public API, we cannot change
1106    // that to appease clippy
1107    #[allow(clippy::wrong_self_convention)]
1108    fn as_expression_list(self) -> Self::Expression;
1109}
1110
1111#[cfg(feature = "postgres_backend")]
1112#[cfg(all(feature = "with-deprecated", not(feature = "without-deprecated")))]
1113#[allow(deprecated)]
1114impl<T, ST> AsExpressionList<ST> for T
1115where
1116    T: crate::pg::expression::array::IntoArrayExpression<ST>,
1117    ST: SqlType + TypedExpressionType,
1118{
1119    type Expression = <T as crate::pg::expression::array::IntoArrayExpression<ST>>::ArrayExpression;
1120
1121    fn as_expression_list(self) -> Self::Expression {
1122        self.into_array_expression()
1123    }
1124}