Skip to main content

diesel/expression/
mod.rs

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