diesel/expression/functions/aggregate_expressions/
over_clause.rs1use super::aggregate_filter::{Filter, NoFilter};
2use super::aggregate_order::NoOrder;
3use super::partition_by::NoPartition;
4use super::prefix::NoPrefix;
5use super::IsWindowFunction;
6use super::NoFrame;
7use super::WindowFunctionFragment;
8use super::{AggregateExpression, IsAggregateFunction};
9use crate::query_builder::QueryFragment;
10use crate::query_builder::{AstPass, QueryId};
11use crate::QueryResult;
12
13pub(super) trait ValidAggregateFilterForWindow<Fn, Window> {}
15
16impl<Fn, W> ValidAggregateFilterForWindow<Fn, W> for NoFilter {}
17empty_clause!(NoWindow);
18
19impl<F, Fn> ValidAggregateFilterForWindow<Fn, NoWindow> for Filter<F> {}
20
21impl<DB, T> WindowFunctionFragment<T, DB> for NoWindow where DB: crate::backend::Backend {}
22
23#[derive(Clone, Copy, QueryId, Debug)]
24#[doc(hidden)] #[diesel(diesel_internal_is_window = true)]
26pub struct OverClause<Partition = NoPartition, Order = NoOrder, Frame = NoFrame> {
27 pub(crate) partition_by: Partition,
28 pub(crate) order: Order,
29 pub(crate) frame_clause: Frame,
30}
31
32impl<F, Fn, Partition, Order, Frame>
33 ValidAggregateFilterForWindow<Fn, OverClause<Partition, Order, Frame>> for Filter<F>
34where
35 Fn: IsAggregateFunction,
36{
37}
38
39impl<Partition, Order, Frame, DB> QueryFragment<DB> for OverClause<Partition, Order, Frame>
40where
41 Partition: QueryFragment<DB>,
42 Order: QueryFragment<DB>,
43 Frame: QueryFragment<DB>,
44 DB: crate::backend::Backend,
45{
46 fn walk_ast<'b>(&'b self, mut pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
47 pass.push_sql(" OVER (");
48 self.partition_by.walk_ast(pass.reborrow())?;
49 self.order.walk_ast(pass.reborrow())?;
50 self.frame_clause.walk_ast(pass.reborrow())?;
51 pass.push_sql(")");
52 Ok(())
53 }
54}
55
56pub trait OverDsl {
57 type Output;
58
59 fn over(self) -> Self::Output;
60}
61
62impl<F> OverDsl for F
63where
64 F: IsWindowFunction,
65{
66 type Output = AggregateExpression<F, NoPrefix, NoOrder, NoFilter, OverClause>;
67
68 fn over(self) -> Self::Output {
69 AggregateExpression {
70 prefix: NoPrefix,
71 function: self,
72 order: NoOrder,
73 filter: NoFilter,
74 window: OverClause {
75 partition_by: NoPartition,
76 order: NoOrder,
77 frame_clause: NoFrame,
78 },
79 }
80 }
81}
82
83impl<Fn, Filter> OverDsl for AggregateExpression<Fn, NoPrefix, NoOrder, Filter, NoWindow>
84where
85 Filter: ValidAggregateFilterForWindow<Fn, OverClause>,
86{
87 type Output = AggregateExpression<Fn, NoPrefix, NoOrder, Filter, OverClause>;
88
89 fn over(self) -> Self::Output {
90 AggregateExpression {
91 prefix: NoPrefix,
92 function: self.function,
93 order: NoOrder,
94 filter: self.filter,
95 window: OverClause {
96 partition_by: NoPartition,
97 order: NoOrder,
98 frame_clause: NoFrame,
99 },
100 }
101 }
102}