Skip to main content

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}