diesel/query_dsl/
distinct_dsl.rs

1use crate::dsl;
2#[cfg(feature = "postgres_backend")]
3use crate::expression::SelectableExpression;
4use crate::expression::TypedExpressionType;
5use crate::expression::ValidGrouping;
6use crate::query_builder::FromClause;
7use crate::query_builder::{AsQuery, SelectStatement};
8use crate::query_source::Table;
9use crate::Expression;
10
11/// The `distinct` method
12///
13/// This trait should not be relied on directly by most apps. Its behavior is
14/// provided by [`QueryDsl`]. However, you may need a where clause on this trait
15/// to call `distinct` from generic code.
16///
17/// [`QueryDsl`]: crate::QueryDsl
18#[diagnostic::on_unimplemented(
19    note = "a `DISTINCT` clause is not compatible with various other clauses like `LOCKING` clauses"
20)]
21pub trait DistinctDsl {
22    /// The type returned by `.distinct`
23    type Output;
24
25    /// See the trait documentation.
26    fn distinct(self) -> dsl::Distinct<Self>;
27}
28
29#[diagnostic::do_not_recommend]
30impl<T> DistinctDsl for T
31where
32    T: Table + AsQuery<Query = SelectStatement<FromClause<T>>>,
33    T::DefaultSelection: Expression<SqlType = T::SqlType> + ValidGrouping<()>,
34    T::SqlType: TypedExpressionType,
35{
36    type Output = dsl::Distinct<SelectStatement<FromClause<T>>>;
37
38    fn distinct(self) -> dsl::Distinct<SelectStatement<FromClause<T>>> {
39        self.as_query().distinct()
40    }
41}
42
43/// The `distinct_on` method
44///
45/// This trait should not be relied on directly by most apps. Its behavior is
46/// provided by [`QueryDsl`]. However, you may need a where clause on this trait
47/// to call `distinct_on` from generic code.
48///
49/// [`QueryDsl`]: crate::QueryDsl
50#[cfg(feature = "postgres_backend")]
51#[diagnostic::on_unimplemented(
52    note = "a `DISTINCT ON` clause is not compatible with various other clauses like `LOCKING` clauses",
53    note = "a `DISTINCT ON` clause also disallows mixing aggregate and non-aggregate expressions with the `SELECT` clause"
54)]
55pub trait DistinctOnDsl<Selection> {
56    /// The type returned by `.distinct_on`
57    type Output;
58
59    /// See the trait documentation
60    fn distinct_on(self, selection: Selection) -> dsl::DistinctOn<Self, Selection>;
61}
62
63#[cfg(feature = "postgres_backend")]
64#[diagnostic::do_not_recommend]
65impl<T, Selection> DistinctOnDsl<Selection> for T
66where
67    Selection: SelectableExpression<T>,
68    T: Table + AsQuery<Query = SelectStatement<FromClause<T>>>,
69    SelectStatement<FromClause<T>>: DistinctOnDsl<Selection>,
70    T::DefaultSelection: Expression<SqlType = T::SqlType> + ValidGrouping<()>,
71    T::SqlType: TypedExpressionType,
72{
73    type Output = dsl::DistinctOn<SelectStatement<FromClause<T>>, Selection>;
74
75    fn distinct_on(self, selection: Selection) -> dsl::DistinctOn<Self, Selection> {
76        self.as_query().distinct_on(selection)
77    }
78}