Skip to content

Conversation

@yyy1000
Copy link
Contributor

@yyy1000 yyy1000 commented May 3, 2024

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?

@github-actions github-actions bot added the sql SQL Planner label May 3, 2024
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)"#,
Copy link
Contributor Author

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

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

Copy link
Contributor

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, got it!

Copy link
Contributor

@alamb alamb left a 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

cc @devinjdangelo

asc: _,
nulls_first: _,
}) => self.expr_to_sql(expr),
}) => internal_err!("Sort expression should be handled by expr_to_unparsed"),
Copy link
Contributor

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?

Copy link
Contributor Author

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.

}

impl Unparsed {
fn into_order_by_expr(self) -> Result<ast::OrderByExpr> {
Copy link
Contributor

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 🤔

Comment on lines 249 to 252
let order_by_expr_vec: Vec<ast::OrderByExpr> = order_by
.iter()
.flat_map(|expr| expr_to_unparsed(expr)?.into_order_by_expr())
.collect();
Copy link
Contributor

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 🤔

Suggested change
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()?;

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)"#,
Copy link
Contributor

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

@yyy1000
Copy link
Contributor Author

yyy1000 commented May 3, 2024

Thanks for your review! @alamb
I resolved your comment and you can review it again when you are available. :)

Copy link
Contributor

@alamb alamb left a 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
Copy link
Contributor

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,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@alamb alamb changed the title Support OrderByExpr in Unparsed Unparser: Support ORDER BY in window function definition May 4, 2024
@alamb alamb merged commit 5d3bbaa into apache:main May 4, 2024
@yyy1000 yyy1000 deleted the orderby branch May 4, 2024 15:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

sql SQL Planner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support OrderBy and Sort in Expr->String

2 participants