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