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