Skip to content

Commit fc4e73e

Browse files
committed
sql_parser: window-defn improvement
1 parent d8431c7 commit fc4e73e

File tree

3 files changed

+49
-33
lines changed

3 files changed

+49
-33
lines changed

src/ast/expression.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ pub struct Function {
213213
/// The filter clause of the function
214214
pub filter_clause: Option<Box<Expression>>,
215215
/// The over clause of the function
216-
pub over_clause: Option<WindowDefinition>,
216+
pub over_clause: Option<OverClause>,
217217
}
218218

219219
/// A function argument
@@ -237,10 +237,19 @@ pub enum FunctionArgType {
237237
}
238238

239239
/// An over clause
240+
#[derive(Debug, PartialEq, Clone)]
241+
pub enum OverClause {
242+
/// A window definition
243+
WindowDefinition(WindowDefinition),
244+
/// A window name
245+
WindowName(String),
246+
}
247+
248+
/// A window definition
240249
#[derive(Debug, PartialEq, Clone, Default)]
241250
pub struct WindowDefinition {
242251
/// The window name
243-
pub window_name: Option<String>,
252+
pub base_window_name: Option<String>,
244253
/// The partition by clause
245254
pub partition_by: Option<Vec<Expression>>,
246255
/// The order by clause

src/parser/expression/function_expr.rs

+35-29
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::{
22
BetweenFrameSpec, BetweenFrameSpecType, Expression, FrameSpec, FrameSpecExclude, FrameSpecType,
33
FrameType, Function, FunctionArg, FunctionArgType, Identifier, Keyword, NullsOrdering,
4-
Ordering, OrderingTerm, Parser, ParsingError, TokenType, WindowDefinition,
4+
Ordering, OrderingTerm, OverClause, Parser, ParsingError, TokenType, WindowDefinition,
55
};
66

77
use super::ExpressionParser;
@@ -20,7 +20,7 @@ pub trait FunctionParser {
2020
fn parse_function_filter_clause(&mut self) -> Result<Expression, ParsingError>;
2121

2222
/// Parse a function over clause
23-
fn parse_function_over_clause(&mut self) -> Result<WindowDefinition, ParsingError>;
23+
fn parse_window_definition(&mut self) -> Result<WindowDefinition, ParsingError>;
2424

2525
/// Parse a frame spec
2626
fn parse_function_over_clause_frame_spec(&mut self) -> Result<FrameSpec, ParsingError>;
@@ -56,7 +56,14 @@ impl<'a> FunctionParser for Parser<'a> {
5656

5757
if let Ok(Keyword::Over) = self.peek_as_keyword() {
5858
self.consume_as_keyword(Keyword::Over)?;
59-
function.over_clause = Some(self.parse_function_over_clause()?);
59+
60+
function.over_clause = if let Ok(identifier) = self.consume_as_id() {
61+
Some(OverClause::WindowName(identifier.to_string()))
62+
} else {
63+
Some(OverClause::WindowDefinition(
64+
self.parse_window_definition()?,
65+
))
66+
};
6067
}
6168

6269
Ok(Expression::Function(function))
@@ -200,21 +207,12 @@ impl<'a> FunctionParser for Parser<'a> {
200207
}
201208

202209
/// Parse a function over clause
203-
fn parse_function_over_clause(&mut self) -> Result<WindowDefinition, ParsingError> {
204-
if let Ok(identifier) = self.peek_as_id() {
205-
let over_clause = WindowDefinition {
206-
window_name: Some(identifier.to_string()),
207-
..Default::default()
208-
};
209-
self.consume_as_id()?;
210-
return Ok(over_clause);
211-
}
212-
210+
fn parse_window_definition(&mut self) -> Result<WindowDefinition, ParsingError> {
213211
self.consume_as(TokenType::LeftParen)?;
214212

215213
let mut over_clause = WindowDefinition::default();
216214
if let Ok(base_window_name) = self.peek_as_id() {
217-
over_clause.window_name = Some(base_window_name.to_string());
215+
over_clause.base_window_name = Some(base_window_name.to_string());
218216
self.consume_as_id()?;
219217
}
220218

@@ -373,7 +371,7 @@ mod function_expression_tests {
373371
use crate::{
374372
expression::test_utils::*, BetweenFrameSpec, BetweenFrameSpecType, BinaryOp, FrameSpec,
375373
FrameSpecExclude, FrameSpecType, FrameType, FunctionArg, FunctionArgType, NullsOrdering,
376-
Ordering, OrderingTerm, WindowDefinition,
374+
Ordering, OrderingTerm, OverClause, WindowDefinition,
377375
};
378376

379377
#[test]
@@ -543,16 +541,14 @@ mod function_expression_tests {
543541
arguments: vec![FunctionArgType::Expression(numeric_literal_expression("1"))],
544542
};
545543

546-
let over_clause = WindowDefinition {
547-
window_name: Some("a".to_string()),
548-
partition_by: None,
549-
order_by: None,
550-
frame_spec: None,
551-
};
552-
553544
run_sunny_day_expression_test(
554545
"SELECT abc(1) over a;",
555-
&function_expression("abc", expected_arg, None, Some(over_clause)),
546+
&function_expression(
547+
"abc",
548+
expected_arg,
549+
None,
550+
Some(OverClause::WindowName("a".to_string())),
551+
),
556552
);
557553
}
558554

@@ -564,15 +560,20 @@ mod function_expression_tests {
564560
};
565561

566562
let over_clause = WindowDefinition {
567-
window_name: None,
563+
base_window_name: None,
568564
partition_by: Some(vec![numeric_literal_expression("1")]),
569565
order_by: None,
570566
frame_spec: None,
571567
};
572568

573569
run_sunny_day_expression_test(
574570
"SELECT abc(1) over (partition by 1);",
575-
&function_expression("abc", expected_arg, None, Some(over_clause)),
571+
&function_expression(
572+
"abc",
573+
expected_arg,
574+
None,
575+
Some(OverClause::WindowDefinition(over_clause)),
576+
),
576577
);
577578
}
578579

@@ -584,7 +585,7 @@ mod function_expression_tests {
584585
};
585586

586587
let over_clause = WindowDefinition {
587-
window_name: None,
588+
base_window_name: None,
588589
partition_by: None,
589590
order_by: Some(vec![OrderingTerm {
590591
expression: Box::new(numeric_literal_expression("1")),
@@ -596,7 +597,12 @@ mod function_expression_tests {
596597

597598
run_sunny_day_expression_test(
598599
"SELECT abc(1) over (order by 1 asc nulls last);",
599-
&function_expression("abc", expected_arg, None, Some(over_clause)),
600+
&function_expression(
601+
"abc",
602+
expected_arg,
603+
None,
604+
Some(OverClause::WindowDefinition(over_clause)),
605+
),
600606
);
601607
}
602608

@@ -608,7 +614,7 @@ mod function_expression_tests {
608614
};
609615

610616
let over_clause = WindowDefinition {
611-
window_name: Some("a".to_string()),
617+
base_window_name: Some("a".to_string()),
612618
partition_by: None,
613619
order_by: None,
614620
frame_spec: Some(FrameSpec {
@@ -625,7 +631,7 @@ mod function_expression_tests {
625631

626632
run_sunny_day_expression_test(
627633
"SELECT abc(1) over (a groups between 1 preceding and current row exclude current row);",
628-
&function_expression("abc", expected_arg, None, Some(over_clause)),
634+
&function_expression("abc", expected_arg, None, Some(OverClause::WindowDefinition(over_clause))),
629635
);
630636
}
631637
}

src/parser/expression/mod.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,8 @@ pub(crate) mod test_utils {
397397
use crate::ast::{Expression, SelectItem};
398398
use crate::{
399399
BinaryOp, DataType, ExistsStatement, Function, FunctionArg, Identifier, LiteralValue,
400-
Parser, RaiseFunction, SelectStatementType, Statement, UnaryOp, WindowDefinition,
400+
OverClause, Parser, RaiseFunction, SelectStatementType, Statement, UnaryOp,
401+
WindowDefinition,
401402
};
402403

403404
pub fn run_sunny_day_test_with_multiple_expressions(
@@ -488,7 +489,7 @@ pub(crate) mod test_utils {
488489
name: &str,
489490
arg: FunctionArg,
490491
filter: Option<Box<Expression>>,
491-
over: Option<WindowDefinition>,
492+
over: Option<OverClause>,
492493
) -> Expression {
493494
let function = Function {
494495
name: Identifier::Single(name.to_string()),

0 commit comments

Comments
 (0)