Skip to main content

linkrs_query/executor/expression/functions/builtin/
window.rs

1//! Window function implementations
2//!
3//! Provides window-style functions: ROW_NUMBER, RANK, DENSE_RANK, LEAD, LAG, FIRST_VALUE, LAST_VALUE.
4//! These functions currently operate as row-level functions.
5//! Full OVER clause support (PARTITION BY, ORDER BY, frame specification) will be added in a future phase.
6
7use crate::executor::expression::ExpressionError;
8use linkrs_core::value::NullType;
9use linkrs_core::Value;
10
11define_function_enum! {
12    /// Window function enumeration
13    pub enum WindowFunction {
14        RowNumber => {
15            name: "row_number",
16            arity: 0,
17            variadic: false,
18            description: "Returns the sequential number of a row within a result set",
19            handler: execute_row_number
20        },
21        Rank => {
22            name: "rank",
23            arity: 0,
24            variadic: false,
25            description: "Returns the rank of each row within the partition",
26            handler: execute_rank
27        },
28        DenseRank => {
29            name: "dense_rank",
30            arity: 0,
31            variadic: false,
32            description: "Returns the rank of each row without gaps",
33            handler: execute_dense_rank
34        },
35        Lead => {
36            name: "lead",
37            arity: 2,
38            variadic: false,
39            description: "Returns the value of a column from the next row",
40            handler: execute_lead
41        },
42        Lag => {
43            name: "lag",
44            arity: 2,
45            variadic: false,
46            description: "Returns the value of a column from the previous row",
47            handler: execute_lag
48        },
49        FirstValue => {
50            name: "first_value",
51            arity: 1,
52            variadic: false,
53            description: "Returns the first value in an ordered set of values",
54            handler: execute_first_value
55        },
56        LastValue => {
57            name: "last_value",
58            arity: 1,
59            variadic: false,
60            description: "Returns the last value in an ordered set of values",
61            handler: execute_last_value
62        },
63        NthValue => {
64            name: "nth_value",
65            arity: 2,
66            variadic: false,
67            description: "Returns the Nth value in an ordered set of values",
68            handler: execute_nth_value
69        },
70        Ntile => {
71            name: "ntile",
72            arity: 1,
73            variadic: false,
74            description: "Divides rows into N buckets",
75            handler: execute_ntile
76        },
77    }
78}
79
80fn execute_row_number(_args: &[Value]) -> Result<Value, ExpressionError> {
81    Ok(Value::BigInt(1))
82}
83
84fn execute_rank(_args: &[Value]) -> Result<Value, ExpressionError> {
85    Ok(Value::BigInt(1))
86}
87
88fn execute_dense_rank(_args: &[Value]) -> Result<Value, ExpressionError> {
89    Ok(Value::BigInt(1))
90}
91
92fn execute_lead(args: &[Value]) -> Result<Value, ExpressionError> {
93    let offset = match &args[1] {
94        Value::Int(i) => *i as i64,
95        Value::BigInt(i) => *i,
96        _ => {
97            return Err(ExpressionError::type_error(
98                "lead offset must be an integer",
99            ))
100        }
101    };
102    if offset < 0 {
103        return Err(ExpressionError::type_error(
104            "lead offset must be non-negative",
105        ));
106    }
107    Ok(Value::Null(NullType::Null))
108}
109
110fn execute_lag(args: &[Value]) -> Result<Value, ExpressionError> {
111    let offset = match &args[1] {
112        Value::Int(i) => *i as i64,
113        Value::BigInt(i) => *i,
114        _ => return Err(ExpressionError::type_error("lag offset must be an integer")),
115    };
116    if offset < 0 {
117        return Err(ExpressionError::type_error(
118            "lag offset must be non-negative",
119        ));
120    }
121    Ok(Value::Null(NullType::Null))
122}
123
124fn execute_first_value(args: &[Value]) -> Result<Value, ExpressionError> {
125    Ok(args[0].clone())
126}
127
128fn execute_last_value(args: &[Value]) -> Result<Value, ExpressionError> {
129    Ok(args[0].clone())
130}
131
132fn execute_nth_value(args: &[Value]) -> Result<Value, ExpressionError> {
133    let n = match &args[1] {
134        Value::Int(i) => *i as i64,
135        Value::BigInt(i) => *i,
136        _ => {
137            return Err(ExpressionError::type_error(
138                "nth_value n must be an integer",
139            ))
140        }
141    };
142    if n < 1 {
143        return Err(ExpressionError::type_error("nth_value n must be positive"));
144    }
145    Ok(args[0].clone())
146}
147
148fn execute_ntile(args: &[Value]) -> Result<Value, ExpressionError> {
149    let n = match &args[0] {
150        Value::Int(i) => *i as i64,
151        Value::BigInt(i) => *i,
152        _ => return Err(ExpressionError::type_error("ntile n must be an integer")),
153    };
154    if n < 1 {
155        return Err(ExpressionError::type_error("ntile n must be positive"));
156    }
157    Ok(Value::BigInt(1))
158}