mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-30 18:57:21 +00:00
Support IGNORE|RESPECT
NULLs clause in window functions (#998)
Co-authored-by: Andrew Lamb <andrew@nerdnetworks.org>
This commit is contained in:
parent
8262abcd31
commit
b89edaa98b
14 changed files with 124 additions and 0 deletions
|
@ -875,6 +875,7 @@ fn parse_select_count_wildcard() {
|
|||
&Expr::Function(Function {
|
||||
name: ObjectName(vec![Ident::new("COUNT")]),
|
||||
args: vec![FunctionArg::Unnamed(FunctionArgExpr::Wildcard)],
|
||||
null_treatment: None,
|
||||
filter: None,
|
||||
over: None,
|
||||
distinct: false,
|
||||
|
@ -896,6 +897,7 @@ fn parse_select_count_distinct() {
|
|||
op: UnaryOperator::Plus,
|
||||
expr: Box::new(Expr::Identifier(Ident::new("x"))),
|
||||
}))],
|
||||
null_treatment: None,
|
||||
filter: None,
|
||||
over: None,
|
||||
distinct: true,
|
||||
|
@ -1864,6 +1866,7 @@ fn parse_select_having() {
|
|||
left: Box::new(Expr::Function(Function {
|
||||
name: ObjectName(vec![Ident::new("COUNT")]),
|
||||
args: vec![FunctionArg::Unnamed(FunctionArgExpr::Wildcard)],
|
||||
null_treatment: None,
|
||||
filter: None,
|
||||
over: None,
|
||||
distinct: false,
|
||||
|
@ -1890,6 +1893,7 @@ fn parse_select_qualify() {
|
|||
left: Box::new(Expr::Function(Function {
|
||||
name: ObjectName(vec![Ident::new("ROW_NUMBER")]),
|
||||
args: vec![],
|
||||
null_treatment: None,
|
||||
filter: None,
|
||||
over: Some(WindowType::WindowSpec(WindowSpec {
|
||||
partition_by: vec![Expr::Identifier(Ident::new("p"))],
|
||||
|
@ -2287,6 +2291,45 @@ fn parse_agg_with_order_by() {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_window_rank_function() {
|
||||
let supported_dialects = TestedDialects {
|
||||
dialects: vec![
|
||||
Box::new(GenericDialect {}),
|
||||
Box::new(PostgreSqlDialect {}),
|
||||
Box::new(MsSqlDialect {}),
|
||||
Box::new(AnsiDialect {}),
|
||||
Box::new(HiveDialect {}),
|
||||
Box::new(SnowflakeDialect {}),
|
||||
],
|
||||
options: None,
|
||||
};
|
||||
|
||||
for sql in [
|
||||
"SELECT column1, column2, FIRST_VALUE(column2) OVER (PARTITION BY column1 ORDER BY column2 NULLS LAST) AS column2_first FROM t1",
|
||||
"SELECT column1, column2, FIRST_VALUE(column2) OVER (ORDER BY column2 NULLS LAST) AS column2_first FROM t1",
|
||||
"SELECT col_1, col_2, LAG(col_2) OVER (ORDER BY col_1) FROM t1",
|
||||
"SELECT LAG(col_2, 1, 0) OVER (ORDER BY col_1) FROM t1",
|
||||
"SELECT LAG(col_2, 1, 0) OVER (PARTITION BY col_3 ORDER BY col_1)",
|
||||
] {
|
||||
supported_dialects.verified_stmt(sql);
|
||||
}
|
||||
|
||||
let supported_dialects_nulls = TestedDialects {
|
||||
dialects: vec![Box::new(MsSqlDialect {}), Box::new(SnowflakeDialect {})],
|
||||
options: None,
|
||||
};
|
||||
|
||||
for sql in [
|
||||
"SELECT column1, column2, FIRST_VALUE(column2) IGNORE NULLS OVER (PARTITION BY column1 ORDER BY column2 NULLS LAST) AS column2_first FROM t1",
|
||||
"SELECT column1, column2, FIRST_VALUE(column2) RESPECT NULLS OVER (PARTITION BY column1 ORDER BY column2 NULLS LAST) AS column2_first FROM t1",
|
||||
"SELECT LAG(col_2, 1, 0) IGNORE NULLS OVER (ORDER BY col_1) FROM t1",
|
||||
"SELECT LAG(col_2, 1, 0) RESPECT NULLS OVER (ORDER BY col_1) FROM t1",
|
||||
] {
|
||||
supported_dialects_nulls.verified_stmt(sql);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_create_table() {
|
||||
let sql = "CREATE TABLE uk_cities (\
|
||||
|
@ -3346,6 +3389,7 @@ fn parse_scalar_function_in_projection() {
|
|||
args: vec![FunctionArg::Unnamed(FunctionArgExpr::Expr(
|
||||
Expr::Identifier(Ident::new("id"))
|
||||
))],
|
||||
null_treatment: None,
|
||||
filter: None,
|
||||
over: None,
|
||||
distinct: false,
|
||||
|
@ -3466,6 +3510,7 @@ fn parse_named_argument_function() {
|
|||
))),
|
||||
},
|
||||
],
|
||||
null_treatment: None,
|
||||
filter: None,
|
||||
over: None,
|
||||
distinct: false,
|
||||
|
@ -3498,6 +3543,7 @@ fn parse_window_functions() {
|
|||
&Expr::Function(Function {
|
||||
name: ObjectName(vec![Ident::new("row_number")]),
|
||||
args: vec![],
|
||||
null_treatment: None,
|
||||
filter: None,
|
||||
over: Some(WindowType::WindowSpec(WindowSpec {
|
||||
partition_by: vec![],
|
||||
|
@ -3542,6 +3588,7 @@ fn test_parse_named_window() {
|
|||
quote_style: None,
|
||||
}),
|
||||
))],
|
||||
null_treatment: None,
|
||||
filter: None,
|
||||
over: Some(WindowType::NamedWindow(Ident {
|
||||
value: "window1".to_string(),
|
||||
|
@ -3568,6 +3615,7 @@ fn test_parse_named_window() {
|
|||
quote_style: None,
|
||||
}),
|
||||
))],
|
||||
null_treatment: None,
|
||||
filter: None,
|
||||
over: Some(WindowType::NamedWindow(Ident {
|
||||
value: "window2".to_string(),
|
||||
|
@ -4038,6 +4086,7 @@ fn parse_at_timezone() {
|
|||
quote_style: None,
|
||||
}]),
|
||||
args: vec![FunctionArg::Unnamed(FunctionArgExpr::Expr(zero.clone()))],
|
||||
null_treatment: None,
|
||||
filter: None,
|
||||
over: None,
|
||||
distinct: false,
|
||||
|
@ -4066,6 +4115,7 @@ fn parse_at_timezone() {
|
|||
quote_style: None,
|
||||
},],),
|
||||
args: vec![FunctionArg::Unnamed(FunctionArgExpr::Expr(zero))],
|
||||
null_treatment: None,
|
||||
filter: None,
|
||||
over: None,
|
||||
distinct: false,
|
||||
|
@ -4078,6 +4128,7 @@ fn parse_at_timezone() {
|
|||
Value::SingleQuotedString("%Y-%m-%dT%H".to_string()),
|
||||
),),),
|
||||
],
|
||||
null_treatment: None,
|
||||
filter: None,
|
||||
over: None,
|
||||
distinct: false,
|
||||
|
@ -4237,6 +4288,7 @@ fn parse_table_function() {
|
|||
args: vec![FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(
|
||||
Value::SingleQuotedString("1".to_owned()),
|
||||
)))],
|
||||
null_treatment: None,
|
||||
filter: None,
|
||||
over: None,
|
||||
distinct: false,
|
||||
|
@ -4389,6 +4441,7 @@ fn parse_unnest_in_from_clause() {
|
|||
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(number("2")))),
|
||||
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(number("3")))),
|
||||
],
|
||||
null_treatment: None,
|
||||
filter: None,
|
||||
over: None,
|
||||
distinct: false,
|
||||
|
@ -4419,6 +4472,7 @@ fn parse_unnest_in_from_clause() {
|
|||
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(number("2")))),
|
||||
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(number("3")))),
|
||||
],
|
||||
null_treatment: None,
|
||||
filter: None,
|
||||
over: None,
|
||||
distinct: false,
|
||||
|
@ -4431,6 +4485,7 @@ fn parse_unnest_in_from_clause() {
|
|||
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(number("5")))),
|
||||
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(number("6")))),
|
||||
],
|
||||
null_treatment: None,
|
||||
filter: None,
|
||||
over: None,
|
||||
distinct: false,
|
||||
|
@ -6904,6 +6959,7 @@ fn parse_time_functions() {
|
|||
let select_localtime_func_call_ast = Function {
|
||||
name: ObjectName(vec![Ident::new(func_name)]),
|
||||
args: vec![],
|
||||
null_treatment: None,
|
||||
filter: None,
|
||||
over: None,
|
||||
distinct: false,
|
||||
|
@ -7391,6 +7447,7 @@ fn parse_pivot_table() {
|
|||
args: (vec![FunctionArg::Unnamed(FunctionArgExpr::Expr(
|
||||
Expr::CompoundIdentifier(vec![Ident::new("a"), Ident::new("amount"),])
|
||||
))]),
|
||||
null_treatment: None,
|
||||
filter: None,
|
||||
over: None,
|
||||
distinct: false,
|
||||
|
@ -7541,6 +7598,7 @@ fn parse_pivot_unpivot_table() {
|
|||
args: (vec![FunctionArg::Unnamed(FunctionArgExpr::Expr(
|
||||
Expr::Identifier(Ident::new("population"))
|
||||
))]),
|
||||
null_treatment: None,
|
||||
filter: None,
|
||||
over: None,
|
||||
distinct: false,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue