1use std::borrow::Cow;
2
3use crate::{Expr, IntoColumnRef, NullOrdering, Order, OrderExpr, OrderedStatement};
4
5pub trait OverStatement {
6 #[doc(hidden)]
7 fn add_partition_by(&mut self, partition: Expr) -> &mut Self;
9
10 fn partition_by<T>(&mut self, col: T) -> &mut Self
12 where
13 T: IntoColumnRef,
14 {
15 self.add_partition_by(Expr::Column(col.into_column_ref()))
16 }
17
18 fn partition_by_customs<I, T>(&mut self, cols: I) -> &mut Self
20 where
21 T: Into<Cow<'static, str>>,
22 I: IntoIterator<Item = T>,
23 {
24 cols.into_iter().for_each(|c| {
25 self.add_partition_by(Expr::Custom(c.into()));
26 });
27 self
28 }
29
30 fn partition_by_columns<I, T>(&mut self, cols: I) -> &mut Self
32 where
33 T: IntoColumnRef,
34 I: IntoIterator<Item = T>,
35 {
36 cols.into_iter().for_each(|c| {
37 self.add_partition_by(Expr::Column(c.into_column_ref()));
38 });
39 self
40 }
41}
42
43#[derive(Debug, Clone, PartialEq)]
45pub enum Frame {
46 UnboundedPreceding,
47 Preceding(u32),
48 CurrentRow,
49 Following(u32),
50 UnboundedFollowing,
51}
52
53#[derive(Debug, Clone, PartialEq)]
55pub enum FrameType {
56 Range,
57 Rows,
58}
59
60#[derive(Debug, Clone, PartialEq)]
62pub struct FrameClause {
63 pub(crate) r#type: FrameType,
64 pub(crate) start: Frame,
65 pub(crate) end: Option<Frame>,
66}
67
68#[derive(Default, Debug, Clone, PartialEq)]
76pub struct WindowStatement {
77 pub(crate) partition_by: Vec<Expr>,
78 pub(crate) order_by: Vec<OrderExpr>,
79 pub(crate) frame: Option<FrameClause>,
80}
81
82impl WindowStatement {
83 pub fn new() -> Self {
85 Self::default()
86 }
87
88 pub fn take(&mut self) -> Self {
89 Self {
90 partition_by: std::mem::take(&mut self.partition_by),
91 order_by: std::mem::take(&mut self.order_by),
92 frame: self.frame.take(),
93 }
94 }
95
96 pub fn partition_by<T>(col: T) -> Self
98 where
99 T: IntoColumnRef,
100 {
101 let mut window = Self::new();
102 window.add_partition_by(Expr::Column(col.into_column_ref()));
103 window
104 }
105
106 pub fn partition_by_custom<T>(col: T) -> Self
108 where
109 T: Into<Cow<'static, str>>,
110 {
111 let mut window = Self::new();
112 window.add_partition_by(Expr::cust(col));
113 window
114 }
115
116 pub fn frame_start(&mut self, r#type: FrameType, start: Frame) -> &mut Self {
146 self.frame(r#type, start, None)
147 }
148
149 pub fn frame_between(&mut self, r#type: FrameType, start: Frame, end: Frame) -> &mut Self {
180 self.frame(r#type, start, Some(end))
181 }
182
183 pub fn frame(&mut self, r#type: FrameType, start: Frame, end: Option<Frame>) -> &mut Self {
185 let frame_clause = FrameClause { r#type, start, end };
186 self.frame = Some(frame_clause);
187 self
188 }
189}
190
191impl OverStatement for WindowStatement {
192 fn add_partition_by(&mut self, partition: Expr) -> &mut Self {
193 self.partition_by.push(partition);
194 self
195 }
196}
197
198impl OrderedStatement for WindowStatement {
199 fn add_order_by(&mut self, order: OrderExpr) -> &mut Self {
200 self.order_by.push(order);
201 self
202 }
203
204 fn clear_order_by(&mut self) -> &mut Self {
205 self.order_by = Vec::new();
206 self
207 }
208}
209
210impl WindowStatement {
211 pub fn add_order_by(&mut self, order: OrderExpr) -> &mut Self {
212 <Self as OrderedStatement>::add_order_by(self, order)
213 }
214
215 pub fn clear_order_by(&mut self) -> &mut Self {
216 <Self as OrderedStatement>::clear_order_by(self)
217 }
218
219 pub fn order_by<T: IntoColumnRef>(&mut self, col: T, order: Order) -> &mut Self {
220 <Self as OrderedStatement>::order_by(self, col, order)
221 }
222
223 pub fn order_by_expr(&mut self, expr: Expr, order: Order) -> &mut Self {
224 <Self as OrderedStatement>::order_by_expr(self, expr, order)
225 }
226
227 pub fn order_by_customs<I, T>(&mut self, cols: I) -> &mut Self
228 where
229 T: Into<Cow<'static, str>>,
230 I: IntoIterator<Item = (T, Order)>,
231 {
232 <Self as OrderedStatement>::order_by_customs(self, cols)
233 }
234
235 pub fn order_by_columns<I, T>(&mut self, cols: I) -> &mut Self
236 where
237 T: IntoColumnRef,
238 I: IntoIterator<Item = (T, Order)>,
239 {
240 <Self as OrderedStatement>::order_by_columns(self, cols)
241 }
242
243 pub fn order_by_with_nulls<T: IntoColumnRef>(
244 &mut self,
245 col: T,
246 order: Order,
247 nulls: NullOrdering,
248 ) -> &mut Self {
249 <Self as OrderedStatement>::order_by_with_nulls(self, col, order, nulls)
250 }
251
252 pub fn order_by_expr_with_nulls(
253 &mut self,
254 expr: Expr,
255 order: Order,
256 nulls: NullOrdering,
257 ) -> &mut Self {
258 <Self as OrderedStatement>::order_by_expr_with_nulls(self, expr, order, nulls)
259 }
260
261 pub fn order_by_customs_with_nulls<I, T>(&mut self, cols: I) -> &mut Self
262 where
263 T: Into<Cow<'static, str>>,
264 I: IntoIterator<Item = (T, Order, NullOrdering)>,
265 {
266 <Self as OrderedStatement>::order_by_customs_with_nulls(self, cols)
267 }
268
269 pub fn order_by_columns_with_nulls<I, T>(&mut self, cols: I) -> &mut Self
270 where
271 T: IntoColumnRef,
272 I: IntoIterator<Item = (T, Order, NullOrdering)>,
273 {
274 <Self as OrderedStatement>::order_by_columns_with_nulls(self, cols)
275 }
276}