1use crate::expression::{SelectableExpression, ValidGrouping};
2use crate::pg::Pg;
3use crate::query_builder::group_by_clause::ValidGroupByClause;
4use crate::query_builder::order_clause::NoOrderClause;
5use crate::query_builder::{
6 AstPass, FromClause, QueryFragment, QueryId, SelectClauseExpression, SelectQuery,
7 SelectStatement,
8};
9use crate::query_dsl::group_by_dsl::ValidDistinctForGroupBy;
10use crate::query_dsl::methods::DistinctOnDsl;
11use crate::query_dsl::order_dsl::ValidOrderingForDistinct;
12use crate::result::QueryResult;
13use crate::sql_types::SingleValue;
14use crate::QuerySource;
15use diesel::query_builder::order_clause::OrderClause;
16
17#[derive(Debug, Clone, Copy, QueryId)]
19#[cfg(feature = "postgres_backend")]
20pub struct DistinctOnClause<T>(pub(crate) T);
21
22impl<T> ValidOrderingForDistinct<DistinctOnClause<T>> for NoOrderClause {}
23impl<T> ValidOrderingForDistinct<DistinctOnClause<T>> for OrderClause<(T,)> {}
24impl<T> ValidOrderingForDistinct<DistinctOnClause<T>> for OrderClause<T> where T: crate::Expression {}
25
26impl<S, G, D> ValidDistinctForGroupBy<S, G> for DistinctOnClause<D> where (D, S): ValidGrouping<G> {}
27
28impl<T> ValidOrderingForDistinct<DistinctOnClause<T>>
29 for OrderClause<crate::expression::operators::Asc<T>>
30where
31 T: crate::Expression,
32 T::SqlType: SingleValue,
33{
34}
35
36impl<T> ValidOrderingForDistinct<DistinctOnClause<T>>
37 for OrderClause<crate::expression::operators::Desc<T>>
38where
39 T: crate::Expression,
40 T::SqlType: SingleValue,
41{
42}
43
44macro_rules! valid_ordering {
45 (
48 @optional_untuple:
49 [generics: $($T: ident)*]
50 [distinct: $D:ident]
51 [order: $O: ty,]
52 ) => {
53 };
55 (
56 @optional_untuple:
57 [generics: $($T: ident)*]
58 [distinct: $D:ident]
59 [order: $($O: ty,)*]
60 ) => {
61 #[diagnostic::do_not_recommend]
62 impl<$($T,)*> ValidOrderingForDistinct<DistinctOnClause<$D>>
63 for OrderClause<($($O,)*)>
64 {}
65 };
66 (
67 @optional_untuple:
68 [generics: $($T: ident)*]
69 [distinct: $($D:ident)*]
70 [order: $O: ty,]
71 ) => {
72 #[diagnostic::do_not_recommend]
73 impl<$($T,)*> ValidOrderingForDistinct<DistinctOnClause<($($D,)*)>>
74 for OrderClause<$O>
75 {}
76 };
77 (
78 @optional_untuple:
79 [generics: $($T: ident)*]
80 [distinct: $($D:ident)*]
81 [order: $($O: ty,)*]
82 ) => {};
83 (@impl_one:
89 [allow_plain = false]
90 $generics:tt
91 $distinct:tt
92 $other:tt
93 [$($T_:ident, )*]
94 ) => {
95 };
97 (@impl_one:
98 [allow_plain = $allow_plain: expr]
99 [generics: $($T:ident)*]
100 [distinct: $($D:ident)*]
101 [other: $($O:ident)*]
102 [$($Ty:ty, )*]
103 ) => {
104 #[diagnostic::do_not_recommend]
105 impl<$($T,)*> ValidOrderingForDistinct<DistinctOnClause<($($D, )*)>>
106 for OrderClause<($($Ty, )* $($O,)*)>
107 {}
108 valid_ordering!(@optional_untuple: [generics: $($T)*] [distinct: $($D)*] [order: $($Ty,)* $($O,)*]);
109 };
110 (
111 @perm:
112 $allow_plain:tt
113 $generics:tt
114 $distinct:tt
115 $other:tt
116 [acc: $([$($acc:tt)*])*]
117 $T:ident
118 $($rest:tt)*
119 ) => {
120 valid_ordering! {
121 @perm:
122 $allow_plain
123 $generics
124 $distinct
125 $other
126 [acc:
127 $(
128 [$($acc)* crate::expression::operators::Asc<$T>, ]
129 [$($acc)* $T , ]
130 [$($acc)* crate::expression::operators::Desc<$T>, ]
131 )*
132 ]
133 $($rest)*
134 }
135 };
136 (
137 @perm:
138 $allow_plain:tt
139 $generics:tt
140 $distinct:tt
141 $other:tt
142 [acc: $($Tys:tt)*]
143 ) => (
145 $(
146 valid_ordering! {@impl_one:
147 $allow_plain
148 $generics
149 $distinct
150 $other
151 $Tys
152 }
153 )*
154 );
155 (@skip_distinct_rev: [generics: $($G: ident)*] [other: $($O: ident)*] [acc: $($T: ident)*]) => {
156 valid_ordering!(@perm:
157 [allow_plain = true]
158 [generics: $($G)*]
159 [distinct: $($T)*]
160 [other: $($O)* ]
161 [acc: []]
162 $($T)*
163 );
164 };
165 (@skip_distinct_rev: [generics: $($G: ident)*] [other: $($O: ident)*] [acc: $($I: ident)*] $T: ident $($Ts: ident)*) => {
166 valid_ordering!(
167 @skip_distinct_rev:
168 [generics: $($G)*]
169 [other: $($O)*]
170 [acc: $T $($I)*]
171 $($Ts)*
172 );
173 };
174 (@skip_distinct:
175 [generics: $($G: ident)*]
176 [acc: $($O: ident)*]
177 $T: ident
178 ) => {};
179 (@skip_distinct:
180 [generics: $($G: ident)*]
181 [acc: $($O: ident)*]
182 $T:ident $($Ts: ident)*
183 ) => {
184 valid_ordering!(@skip_distinct_rev:
185 [generics: $($G)*]
186 [other: $($O)* $T]
187 [acc: ]
188 $($Ts)*
189 );
190 valid_ordering!(@skip_distinct: [generics: $($G)*] [acc: $($O)* $T] $($Ts)*);
191 };
192 (@skip_order_rev: [generics: $($G: ident)*] [acc: $($T: ident)*]) => {
193 valid_ordering!(@perm:
194 [allow_plain = true]
195 [generics: $($G)*]
196 [distinct: $($G)*]
197 [other: ]
198 [acc: []]
199 $($T)*
200 );
201 };
202 (@skip_order_rev: [generics: $($G: ident)*] [acc: $($I: ident)*] $T: ident $($Ts: ident)*) => {
203 valid_ordering!(
204 @skip_order_rev:
205 [generics: $($G)*]
206 [acc: $T $($I)*]
207 $($Ts)*
208 );
209 };
210 (@skip_order:
211 [generics: $($G: ident)*]
212 $T: ident
213 ) => {};
214 (@skip_order:
215 [generics: $($G: ident)*]
216 $T: ident $($Ts: ident)*
217 ) => {
218 valid_ordering!(@skip_order_rev: [generics: $($G)*] [acc: ] $($Ts)*);
219 valid_ordering!(@skip_order: [generics: $($G)*] $($Ts)*);
220 };
221 (@reverse_list: [generics: $($G: ident)*] [acc: $($I: ident)*]) => {
222 valid_ordering!(@skip_order: [generics: $($G)*] $($I)*);
223 valid_ordering!(@skip_distinct: [generics: $($G)*] [acc: ] $($I)*);
224 };
225 (@reverse_list: [generics: $($G: ident)*] [acc: $($I: ident)*] $T: ident $($Ts: ident)*) => {
226 valid_ordering!(@reverse_list: [generics: $($G)*] [acc: $T $($I)*] $($Ts)*);
227 };
228 ($(
229 $Tuple:tt {
230 $(($idx:tt) -> $T:ident, $ST:ident, $TT:ident,)+
231 }
232 )+) => {
233 $(
234 valid_ordering!(@perm:
235 [allow_plain = false]
236 [generics: $($T)*]
237 [distinct: $($T)*]
238 [other: ]
239 [acc: []]
240 $($T)*
241 );
242 valid_ordering!(@reverse_list: [generics: $($T)*] [acc: ] $($T)*);
243 )*
244 }
245}
246
247diesel_derives::__diesel_for_each_tuple!(valid_ordering, 5);
252
253pub trait OrderDecorator {
256 type Column;
258}
259
260impl<C> OrderDecorator for C
261where
262 C: crate::Column,
263{
264 type Column = C;
265}
266
267impl<C> OrderDecorator for crate::helper_types::Asc<C> {
268 type Column = C;
269}
270
271impl<C> OrderDecorator for crate::helper_types::Desc<C> {
272 type Column = C;
273}
274
275impl<T> QueryFragment<Pg> for DistinctOnClause<T>
276where
277 T: QueryFragment<Pg>,
278{
279 fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, Pg>) -> QueryResult<()> {
280 out.push_sql("DISTINCT ON (");
281 self.0.walk_ast(out.reborrow())?;
282 out.push_sql(") ");
283 Ok(())
284 }
285}
286
287impl<ST, F, S, D, W, O, LOf, G, H, Selection> DistinctOnDsl<Selection>
288 for SelectStatement<FromClause<F>, S, D, W, O, LOf, G, H>
289where
290 G: ValidGroupByClause,
291 F: QuerySource,
292 Selection: SelectableExpression<F>,
293 Self: SelectQuery<SqlType = ST>,
294 O: ValidOrderingForDistinct<DistinctOnClause<Selection>>,
295 SelectStatement<FromClause<F>, S, DistinctOnClause<Selection>, W, O, LOf, G, H>:
296 SelectQuery<SqlType = ST>,
297 S: SelectClauseExpression<FromClause<F>>,
298 (Selection, S::Selection): ValidGrouping<G::Expressions>,
299{
300 type Output = SelectStatement<FromClause<F>, S, DistinctOnClause<Selection>, W, O, LOf, G, H>;
301
302 fn distinct_on(self, selection: Selection) -> Self::Output {
303 SelectStatement::new(
304 self.select,
305 self.from,
306 DistinctOnClause(selection),
307 self.where_clause,
308 self.order,
309 self.limit_offset,
310 self.group_by,
311 self.having,
312 self.locking,
313 )
314 }
315}