Merge pull request #50 from nickolay/window-functions

Support OVER clause for window/analytic functions, add support for qualified function names
This commit is contained in:
Nickolay Ponomarev 2019-04-27 21:12:08 +03:00 committed by GitHub
commit 6bb2acc9f8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 295 additions and 89 deletions

View file

@ -101,12 +101,12 @@ fn parse_count_wildcard() {
fn parse_column_aliases() {
let sql = "SELECT a.col + 1 AS newname FROM foo AS a";
let select = verified_only_select(sql);
if let SQLSelectItem::ExpressionWithAlias(
ASTNode::SQLBinaryExpr {
if let SQLSelectItem::ExpressionWithAlias {
expr: ASTNode::SQLBinaryExpr {
ref op, ref right, ..
},
ref alias,
) = only(&select.projection)
} = only(&select.projection)
{
assert_eq!(&SQLOperator::Plus, op);
assert_eq!(&ASTNode::SQLValue(Value::Long(1)), right.as_ref());
@ -125,8 +125,9 @@ fn parse_select_count_wildcard() {
let select = verified_only_select(sql);
assert_eq!(
&ASTNode::SQLFunction {
id: "COUNT".to_string(),
name: SQLObjectName(vec!["COUNT".to_string()]),
args: vec![ASTNode::SQLWildcard],
over: None,
},
expr_from_projection(only(&select.projection))
);
@ -551,13 +552,43 @@ fn parse_scalar_function_in_projection() {
let select = verified_only_select(sql);
assert_eq!(
&ASTNode::SQLFunction {
id: String::from("sqrt"),
name: SQLObjectName(vec![String::from("sqrt")]),
args: vec![ASTNode::SQLIdentifier(String::from("id"))],
over: None,
},
expr_from_projection(only(&select.projection))
);
}
#[test]
fn parse_window_functions() {
let sql = "SELECT row_number() OVER (ORDER BY dt DESC), \
sum(foo) OVER (PARTITION BY a, b ORDER BY c, d \
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), \
avg(bar) OVER (ORDER BY a \
RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING), \
max(baz) OVER (ORDER BY a \
ROWS UNBOUNDED PRECEDING) \
FROM foo";
let select = verified_only_select(sql);
assert_eq!(4, select.projection.len());
assert_eq!(
&ASTNode::SQLFunction {
name: SQLObjectName(vec!["row_number".to_string()]),
args: vec![],
over: Some(SQLWindowSpec {
partition_by: vec![],
order_by: vec![SQLOrderByExpr {
expr: ASTNode::SQLIdentifier("dt".to_string()),
asc: Some(false)
}],
window_frame: None,
})
},
expr_from_projection(&select.projection[0])
);
}
#[test]
fn parse_aggregate_with_group_by() {
let sql = "SELECT a, COUNT(1), MIN(b), MAX(b) FROM foo GROUP BY a";
@ -624,13 +655,14 @@ fn parse_delimited_identifiers() {
);
assert_eq!(
&ASTNode::SQLFunction {
id: r#""myfun""#.to_string(),
args: vec![]
name: SQLObjectName(vec![r#""myfun""#.to_string()]),
args: vec![],
over: None,
},
expr_from_projection(&select.projection[1]),
);
match &select.projection[2] {
&SQLSelectItem::ExpressionWithAlias(ref expr, ref alias) => {
SQLSelectItem::ExpressionWithAlias { expr, alias } => {
assert_eq!(&ASTNode::SQLIdentifier(r#""simple id""#.to_string()), expr);
assert_eq!(r#""column alias""#, alias);
}