diesel/expression/functions/aggregate_expressions/
aggregate_order.rs

1use super::frame_clause::NoFrame;
2use super::over_clause::ValidAggregateFilterForWindow;
3use super::partition_by::NoPartition;
4use super::NoFilter;
5use super::NoPrefix;
6use super::NoWindow;
7use super::{over_clause::OverClause, AggregateExpression};
8use super::{IsAggregateFunction, IsWindowFunction};
9use crate::backend::{sql_dialect, Backend, SqlDialect};
10use crate::query_builder::order_clause::OrderClause;
11use crate::query_builder::QueryFragment;
12use crate::query_builder::{AstPass, QueryId};
13use crate::{Expression, QueryResult};
14
15empty_clause!(NoOrder);
16
17/// A order clause for window and aggregate function expressions
18#[derive(QueryId, Copy, Clone, Debug)]
19pub struct Order<T, const WINDOW: bool>(OrderClause<T>);
20
21impl<E, DB> QueryFragment<DB> for Order<E, false>
22where
23    Self: QueryFragment<DB, DB::AggregateFunctionExpressions>,
24    DB: Backend,
25{
26    fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
27        <Self as QueryFragment<DB, DB::AggregateFunctionExpressions>>::walk_ast(self, pass)
28    }
29}
30
31impl<E, DB>
32    QueryFragment<
33        DB,
34        sql_dialect::aggregate_function_expressions::PostgresLikeAggregateFunctionExpressions,
35    > for Order<E, false>
36where
37    OrderClause<E>: QueryFragment<DB>,
38    DB: Backend + SqlDialect<
39        AggregateFunctionExpressions = sql_dialect::aggregate_function_expressions::PostgresLikeAggregateFunctionExpressions
40    >,
41{
42    fn walk_ast<'b>(&'b self, mut pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
43        self.0.walk_ast(pass.reborrow())?;
44        Ok(())
45    }
46}
47
48impl<E, DB> QueryFragment<DB> for Order<E, true>
49where
50    OrderClause<E>: QueryFragment<DB>,
51    DB: Backend,
52{
53    fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
54        self.0.walk_ast(pass)
55    }
56}
57
58pub trait OrderAggregateDsl<E> {
59    type Output;
60
61    fn order(self, expr: E) -> Self::Output;
62}
63
64impl<E, T> OrderAggregateDsl<E> for T
65where
66    T: IsAggregateFunction,
67    E: Expression,
68{
69    type Output = AggregateExpression<T, NoPrefix, Order<E, false>>;
70
71    fn order(self, expr: E) -> Self::Output {
72        AggregateExpression {
73            prefix: NoPrefix,
74            function: self,
75            order: Order(OrderClause(expr)),
76            filter: NoFilter,
77            window: NoWindow,
78        }
79    }
80}
81
82impl<O, Fn, Prefix, Ord, Filter> OrderAggregateDsl<O>
83    for AggregateExpression<Fn, Prefix, Ord, Filter, NoWindow>
84{
85    type Output = AggregateExpression<Fn, Prefix, Order<O, false>, Filter>;
86
87    fn order(self, expr: O) -> Self::Output {
88        AggregateExpression {
89            prefix: self.prefix,
90            function: self.function,
91            order: Order(OrderClause(expr)),
92            filter: self.filter,
93            window: NoWindow,
94        }
95    }
96}
97
98pub trait OrderWindowDsl<O> {
99    type Output;
100
101    fn order(self, expr: O) -> Self::Output;
102}
103
104impl<E, Fn, Filter, Frame, Partition, O> OrderWindowDsl<E>
105    for AggregateExpression<Fn, NoPrefix, NoOrder, Filter, OverClause<Partition, O, Frame>>
106where
107    Filter: ValidAggregateFilterForWindow<Fn, OverClause<Partition, Order<E, true>, Frame>>,
108{
109    type Output = AggregateExpression<
110        Fn,
111        NoPrefix,
112        NoOrder,
113        Filter,
114        OverClause<Partition, Order<E, true>, Frame>,
115    >;
116
117    fn order(self, expr: E) -> Self::Output {
118        AggregateExpression {
119            prefix: NoPrefix,
120            function: self.function,
121            order: NoOrder,
122            filter: self.filter,
123            window: OverClause {
124                partition_by: self.window.partition_by,
125                order: Order(OrderClause(expr)),
126                frame_clause: self.window.frame_clause,
127            },
128        }
129    }
130}
131
132impl<Fn, Filter, E> OrderWindowDsl<E>
133    for AggregateExpression<Fn, NoPrefix, NoOrder, Filter, NoWindow>
134where
135    Filter: ValidAggregateFilterForWindow<Fn, OverClause<NoPartition, Order<E, true>, NoFrame>>,
136{
137    type Output = AggregateExpression<
138        Fn,
139        NoPrefix,
140        NoOrder,
141        Filter,
142        OverClause<NoPartition, Order<E, true>, NoFrame>,
143    >;
144
145    fn order(self, expr: E) -> Self::Output {
146        AggregateExpression {
147            prefix: NoPrefix,
148            function: self.function,
149            order: NoOrder,
150            filter: self.filter,
151            window: OverClause {
152                partition_by: NoPartition,
153                order: Order(OrderClause(expr)),
154                frame_clause: NoFrame,
155            },
156        }
157    }
158}
159
160impl<O, Fn> OrderWindowDsl<O> for Fn
161where
162    Fn: IsWindowFunction,
163{
164    type Output = AggregateExpression<
165        Fn,
166        NoPrefix,
167        NoOrder,
168        NoFilter,
169        OverClause<NoPartition, Order<O, true>, NoFrame>,
170    >;
171
172    fn order(self, expr: O) -> Self::Output {
173        AggregateExpression {
174            prefix: NoPrefix,
175            function: self,
176            order: NoOrder,
177            filter: NoFilter,
178            window: OverClause {
179                partition_by: NoPartition,
180                order: Order(OrderClause(expr)),
181                frame_clause: NoFrame,
182            },
183        }
184    }
185}