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