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