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