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