reinhardt_query/types/window.rs
1//! Window function types and structures.
2//!
3//! This module defines types for SQL window functions, including:
4//! - Frame types (RANGE, ROWS, GROUPS)
5//! - Frame boundaries (UNBOUNDED PRECEDING, CURRENT ROW, etc.)
6//! - Frame clauses
7//! - Window specifications (PARTITION BY, ORDER BY, frame clauses)
8
9use crate::{expr::SimpleExpr, types::order::OrderExpr};
10
11/// Frame type for window functions.
12///
13/// Defines how the frame is calculated:
14/// - `Range`: Frame based on value range
15/// - `Rows`: Frame based on physical row positions
16/// - `Groups`: Frame based on peer groups (PostgreSQL only)
17#[derive(Debug, Clone, PartialEq, Eq)]
18pub enum FrameType {
19 /// RANGE frame type.
20 Range,
21 /// ROWS frame type.
22 Rows,
23 /// GROUPS frame type (PostgreSQL only).
24 ///
25 /// Using this with MySQL or SQLite will cause a panic during SQL generation.
26 Groups,
27}
28
29/// Frame boundary for window functions.
30///
31/// Defines the start or end boundary of a window frame.
32#[derive(Debug, Clone, PartialEq, Eq)]
33pub enum Frame {
34 /// UNBOUNDED PRECEDING - beginning of partition.
35 UnboundedPreceding,
36 /// N PRECEDING - N rows/values before current row.
37 Preceding(i64),
38 /// CURRENT ROW - the current row.
39 CurrentRow,
40 /// N FOLLOWING - N rows/values after current row.
41 Following(i64),
42 /// UNBOUNDED FOLLOWING - end of partition.
43 UnboundedFollowing,
44}
45
46/// Frame clause for window functions.
47///
48/// Defines the frame boundaries for a window function.
49///
50/// # Examples
51///
52/// ```rust
53/// use reinhardt_query::types::{FrameClause, FrameType, Frame};
54///
55/// // ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
56/// let frame = FrameClause {
57/// frame_type: FrameType::Rows,
58/// start: Frame::UnboundedPreceding,
59/// end: Some(Frame::CurrentRow),
60/// };
61///
62/// // RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING
63/// let frame2 = FrameClause {
64/// frame_type: FrameType::Range,
65/// start: Frame::Preceding(1),
66/// end: Some(Frame::Following(1)),
67/// };
68/// ```
69#[derive(Debug, Clone)]
70pub struct FrameClause {
71 /// Frame type (RANGE, ROWS, or GROUPS).
72 pub frame_type: FrameType,
73 /// Start boundary of the frame.
74 pub start: Frame,
75 /// End boundary of the frame (if `None`, only start is specified).
76 pub end: Option<Frame>,
77}
78
79/// Window specification for window functions.
80///
81/// Defines a complete window specification including:
82/// - `PARTITION BY` clause
83/// - `ORDER BY` clause
84/// - Frame clause (optional)
85///
86/// # Examples
87///
88/// ```rust
89/// use reinhardt_query::{
90/// types::{WindowStatement, FrameClause, FrameType, Frame, OrderExpr, Order},
91/// expr::Expr,
92/// };
93///
94/// // PARTITION BY department_id ORDER BY salary DESC
95/// let window = WindowStatement {
96/// partition_by: vec![Expr::col("department_id").into_simple_expr()],
97/// order_by: vec![],
98/// frame: None,
99/// };
100/// ```
101#[derive(Debug, Clone)]
102pub struct WindowStatement {
103 /// PARTITION BY expressions.
104 pub partition_by: Vec<SimpleExpr>,
105 /// ORDER BY expressions.
106 pub order_by: Vec<OrderExpr>,
107 /// Optional frame clause.
108 pub frame: Option<FrameClause>,
109}
110
111impl WindowStatement {
112 /// Creates a new empty window specification.
113 pub fn new() -> Self {
114 Self {
115 partition_by: Vec::new(),
116 order_by: Vec::new(),
117 frame: None,
118 }
119 }
120}
121
122impl Default for WindowStatement {
123 fn default() -> Self {
124 Self::new()
125 }
126}