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