1use crate::{expr::*, query::*, types::*};
2use inherent::inherent;
3
4pub trait OverStatement {
5 #[doc(hidden)]
6 fn add_partition_by(&mut self, partition: SimpleExpr) -> &mut Self;
8
9 fn partition_by<T>(&mut self, col: T) -> &mut Self
11 where
12 T: IntoColumnRef,
13 {
14 self.add_partition_by(SimpleExpr::Column(col.into_column_ref()))
15 }
16
17 fn partition_by_customs<I, T>(&mut self, cols: I) -> &mut Self
19 where
20 T: ToString,
21 I: IntoIterator<Item = T>,
22 {
23 cols.into_iter().for_each(|c| {
24 self.add_partition_by(SimpleExpr::Custom(c.to_string()));
25 });
26 self
27 }
28
29 fn partition_by_columns<I, T>(&mut self, cols: I) -> &mut Self
31 where
32 T: IntoColumnRef,
33 I: IntoIterator<Item = T>,
34 {
35 cols.into_iter().for_each(|c| {
36 self.add_partition_by(SimpleExpr::Column(c.into_column_ref()));
37 });
38 self
39 }
40}
41
42#[derive(Debug, Clone, PartialEq)]
44pub enum Frame {
45 UnboundedPreceding,
46 Preceding(u32),
47 CurrentRow,
48 Following(u32),
49 UnboundedFollowing,
50}
51
52#[derive(Debug, Clone, PartialEq)]
54pub enum FrameType {
55 Range,
56 Rows,
57}
58
59#[derive(Debug, Clone, PartialEq)]
61pub struct FrameClause {
62 pub(crate) r#type: FrameType,
63 pub(crate) start: Frame,
64 pub(crate) end: Option<Frame>,
65}
66
67#[derive(Default, Debug, Clone, PartialEq)]
75pub struct WindowStatement {
76 pub(crate) partition_by: Vec<SimpleExpr>,
77 pub(crate) order_by: Vec<OrderExpr>,
78 pub(crate) frame: Option<FrameClause>,
79}
80
81impl WindowStatement {
82 pub fn new() -> Self {
84 Self::default()
85 }
86
87 pub fn take(&mut self) -> Self {
88 Self {
89 partition_by: std::mem::take(&mut self.partition_by),
90 order_by: std::mem::take(&mut self.order_by),
91 frame: self.frame.take(),
92 }
93 }
94
95 pub fn partition_by<T>(col: T) -> Self
97 where
98 T: IntoColumnRef,
99 {
100 let mut window = Self::new();
101 window.add_partition_by(SimpleExpr::Column(col.into_column_ref()));
102 window
103 }
104
105 pub fn partition_by_custom<T>(col: T) -> Self
107 where
108 T: ToString,
109 {
110 let mut window = Self::new();
111 window.add_partition_by(SimpleExpr::Custom(col.to_string()));
112 window
113 }
114
115 pub fn frame_start(&mut self, r#type: FrameType, start: Frame) -> &mut Self {
145 self.frame(r#type, start, None)
146 }
147
148 pub fn frame_between(&mut self, r#type: FrameType, start: Frame, end: Frame) -> &mut Self {
179 self.frame(r#type, start, Some(end))
180 }
181
182 pub fn frame(&mut self, r#type: FrameType, start: Frame, end: Option<Frame>) -> &mut Self {
184 let frame_clause = FrameClause { r#type, start, end };
185 self.frame = Some(frame_clause);
186 self
187 }
188}
189
190impl OverStatement for WindowStatement {
191 fn add_partition_by(&mut self, partition: SimpleExpr) -> &mut Self {
192 self.partition_by.push(partition);
193 self
194 }
195}
196
197#[inherent]
198impl OrderedStatement for WindowStatement {
199 pub fn add_order_by(&mut self, order: OrderExpr) -> &mut Self {
200 self.order_by.push(order);
201 self
202 }
203
204 pub fn clear_order_by(&mut self) -> &mut Self {
205 self.order_by = Vec::new();
206 self
207 }
208
209 pub fn order_by<T>(&mut self, col: T, order: Order) -> &mut Self
210 where
211 T: IntoColumnRef;
212
213 pub fn order_by_expr(&mut self, expr: SimpleExpr, order: Order) -> &mut Self;
214 pub fn order_by_customs<I, T>(&mut self, cols: I) -> &mut Self
215 where
216 T: ToString,
217 I: IntoIterator<Item = (T, Order)>;
218 pub fn order_by_columns<I, T>(&mut self, cols: I) -> &mut Self
219 where
220 T: IntoColumnRef,
221 I: IntoIterator<Item = (T, Order)>;
222 pub fn order_by_with_nulls<T>(
223 &mut self,
224 col: T,
225 order: Order,
226 nulls: NullOrdering,
227 ) -> &mut Self
228 where
229 T: IntoColumnRef;
230 pub fn order_by_expr_with_nulls(
231 &mut self,
232 expr: SimpleExpr,
233 order: Order,
234 nulls: NullOrdering,
235 ) -> &mut Self;
236 pub fn order_by_customs_with_nulls<I, T>(&mut self, cols: I) -> &mut Self
237 where
238 T: ToString,
239 I: IntoIterator<Item = (T, Order, NullOrdering)>;
240 pub fn order_by_columns_with_nulls<I, T>(&mut self, cols: I) -> &mut Self
241 where
242 T: IntoColumnRef,
243 I: IntoIterator<Item = (T, Order, NullOrdering)>;
244}