-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Unparser: Support ORDER BY in window function definition
#10370
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
datafusion/sql/src/unparser/expr.rs
Outdated
| null_treatment: None, | ||
| }), | ||
| r#"COUNT(*) OVER (RANGE BETWEEN 6 PRECEDING AND 2 FOLLOWING)"#, | ||
| r#"COUNT(* ORDER BY "a" DESC NULLS FIRST) OVER (RANGE BETWEEN 6 PRECEDING AND 2 FOLLOWING)"#, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a bit out of my expectation. I don't know whether the two expressions are the same.🤔
From
datafusion/datafusion/core/tests/dataframe/mod.rs
Lines 171 to 194 in 8190cb9
| let sql_results = ctx | |
| .sql("select COUNT(*) OVER(ORDER BY a DESC RANGE BETWEEN 6 PRECEDING AND 2 FOLLOWING) from t1") | |
| .await? | |
| .explain(false, false)? | |
| .collect() | |
| .await?; | |
| let df_results = ctx | |
| .table("t1") | |
| .await? | |
| .select(vec![Expr::WindowFunction(expr::WindowFunction::new( | |
| WindowFunctionDefinition::AggregateFunction(AggregateFunction::Count), | |
| vec![wildcard()], | |
| vec![], | |
| vec![Expr::Sort(Sort::new(Box::new(col("a")), false, true))], | |
| WindowFrame::new_bounds( | |
| WindowFrameUnits::Range, | |
| WindowFrameBound::Preceding(ScalarValue::UInt32(Some(6))), | |
| WindowFrameBound::Following(ScalarValue::UInt32(Some(2))), | |
| ), | |
| None, | |
| ))])? | |
| .explain(false, false)? | |
| .collect() | |
| .await?; |
it should be
COUNT(*) OVER(ORDER BY a DESC RANGE BETWEEN 6 PRECEDING AND 2 FOLLOWING),I doubt it should be an issue from the fmt for Function in sql-parser, if there is an over and order_by, it should put the order by in Over https://github.com/sqlparser-rs/sqlparser-rs/blob/71a7262e38e1c10a46fd50ea7c5610091e1aca3c/src/ast/mod.rs#L4869-L4904
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like somehow the ordering was assciated with the aggregate function rather than the window frame -- see comment above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, got it!
alamb
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @yyy1000 for this contribution -- this looks pretty sweet indeed.
I left a few comments but I think it is quite close
datafusion/sql/src/unparser/expr.rs
Outdated
| asc: _, | ||
| nulls_first: _, | ||
| }) => self.expr_to_sql(expr), | ||
| }) => internal_err!("Sort expression should be handled by expr_to_unparsed"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is a public API I don't think this should be an internal_err as it isn't a bug in datafusion (it could be a bug in the input that was passed in)-- perhaps we can make it a plan_err?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ohh, great. Now I know better when to use these types of error.
datafusion/sql/src/unparser/expr.rs
Outdated
| } | ||
|
|
||
| impl Unparsed { | ||
| fn into_order_by_expr(self) -> Result<ast::OrderByExpr> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can call this try_into_order_by_expr to reflect the fact it is fallable
Perhaps it should also be marked pub 🤔
datafusion/sql/src/unparser/expr.rs
Outdated
| let order_by_expr_vec: Vec<ast::OrderByExpr> = order_by | ||
| .iter() | ||
| .flat_map(|expr| expr_to_unparsed(expr)?.into_order_by_expr()) | ||
| .collect(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be just map (flat map I think will discard Result`s 🤔
| let order_by_expr_vec: Vec<ast::OrderByExpr> = order_by | |
| .iter() | |
| .flat_map(|expr| expr_to_unparsed(expr)?.into_order_by_expr()) | |
| .collect(); | |
| let order_by: Vec<ast::OrderByExpr> = order_by | |
| .iter() | |
| .map(|expr| expr_to_unparsed(expr)?.into_order_by_expr()) | |
| .collect()?; |
datafusion/sql/src/unparser/expr.rs
Outdated
| null_treatment: None, | ||
| }), | ||
| r#"COUNT(*) OVER (RANGE BETWEEN 6 PRECEDING AND 2 FOLLOWING)"#, | ||
| r#"COUNT(* ORDER BY "a" DESC NULLS FIRST) OVER (RANGE BETWEEN 6 PRECEDING AND 2 FOLLOWING)"#, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like somehow the ordering was assciated with the aggregate function rather than the window frame -- see comment above
|
Thanks for your review! @alamb |
alamb
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great -- thank you @yyy1000 🚀
|
|
||
| /// Convert a DataFusion [`Expr`] to [`Unparsed`] | ||
| /// | ||
| /// This function is similar to expr_to_sql, but it supports converting more [`Expr`] types like |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
| .map(|e| self.expr_to_sql(e)) | ||
| .collect::<Result<Vec<_>>>()?, | ||
| order_by: vec![], | ||
| order_by, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
ORDER BY in window function definition
Which issue does this PR close?
Closes #10256 .
Rationale for this change
What changes are included in this PR?
Are these changes tested?
Are there any user-facing changes?