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