1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
//! Window function types for Shape AST
use serde::{Deserialize, Serialize};
use super::expressions::Expr;
/// SQL-style window function
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum WindowFunction {
/// LAG(expr, offset, default) - access previous row value
Lag {
expr: Box<Expr>,
offset: usize,
default: Option<Box<Expr>>,
},
/// LEAD(expr, offset, default) - access next row value
Lead {
expr: Box<Expr>,
offset: usize,
default: Option<Box<Expr>>,
},
/// ROW_NUMBER() - sequential row number in partition
RowNumber,
/// RANK() - rank with gaps for ties
Rank,
/// DENSE_RANK() - rank without gaps
DenseRank,
/// NTILE(n) - divide rows into n buckets
Ntile(usize),
/// FIRST_VALUE(expr) - first value in window
FirstValue(Box<Expr>),
/// LAST_VALUE(expr) - last value in window
LastValue(Box<Expr>),
/// NTH_VALUE(expr, n) - nth value in window
NthValue(Box<Expr>, usize),
/// Running aggregate functions
Sum(Box<Expr>),
Avg(Box<Expr>),
Min(Box<Expr>),
Max(Box<Expr>),
Count(Option<Box<Expr>>),
}
/// Sort direction for ORDER BY clause
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum SortDirection {
Ascending,
Descending,
}
/// ORDER BY clause for query results
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct OrderByClause {
/// List of (expression, direction) pairs
pub columns: Vec<(Expr, SortDirection)>,
}
/// Window specification for OVER clause
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct WindowSpec {
/// PARTITION BY expressions
pub partition_by: Vec<Expr>,
/// ORDER BY clause
pub order_by: Option<OrderByClause>,
/// Window frame (ROWS/RANGE BETWEEN)
pub frame: Option<WindowFrame>,
}
/// Window frame definition
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct WindowFrame {
/// Frame type (ROWS or RANGE)
pub frame_type: WindowFrameType,
/// Start boundary
pub start: WindowBound,
/// End boundary (defaults to CURRENT ROW if not specified)
pub end: WindowBound,
}
/// Window frame type
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum WindowFrameType {
Rows,
Range,
}
/// Window frame boundary
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum WindowBound {
/// UNBOUNDED PRECEDING
UnboundedPreceding,
/// UNBOUNDED FOLLOWING
UnboundedFollowing,
/// CURRENT ROW
CurrentRow,
/// n PRECEDING
Preceding(usize),
/// n FOLLOWING
Following(usize),
}
/// Window function expression: func() OVER (window_spec)
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct WindowExpr {
pub function: WindowFunction,
pub over: WindowSpec,
}