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