Skip to content

Commit 156a525

Browse files
authored
Support LogicalPlan::Distinct in unparser (#10690)
* support distinct * cargo fmt * better fmt * add support for order by * add another test
1 parent 9fba34d commit 156a525

File tree

2 files changed

+39
-3
lines changed

2 files changed

+39
-3
lines changed

datafusion/sql/src/unparser/plan.rs

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
// under the License.
1717

1818
use datafusion_common::{internal_err, not_impl_err, plan_err, DataFusionError, Result};
19-
use datafusion_expr::{expr::Alias, Expr, JoinConstraint, JoinType, LogicalPlan};
19+
use datafusion_expr::{
20+
expr::Alias, Distinct, Expr, JoinConstraint, JoinType, LogicalPlan,
21+
};
2022
use sqlparser::ast::{self, SetExpr};
2123

2224
use crate::unparser::utils::unproject_agg_exprs;
@@ -271,8 +273,39 @@ impl Unparser<'_> {
271273
relation,
272274
)
273275
}
274-
LogicalPlan::Distinct(_distinct) => {
275-
not_impl_err!("Unsupported operator: {plan:?}")
276+
LogicalPlan::Distinct(distinct) => {
277+
let (select_distinct, input) = match distinct {
278+
Distinct::All(input) => (ast::Distinct::Distinct, input.as_ref()),
279+
Distinct::On(on) => {
280+
let exprs = on
281+
.on_expr
282+
.iter()
283+
.map(|e| self.expr_to_sql(e))
284+
.collect::<Result<Vec<_>>>()?;
285+
let items = on
286+
.select_expr
287+
.iter()
288+
.map(|e| self.select_item_to_sql(e))
289+
.collect::<Result<Vec<_>>>()?;
290+
match &on.sort_expr {
291+
Some(sort_expr) => {
292+
if let Some(query_ref) = query {
293+
query_ref
294+
.order_by(self.sort_to_sql(sort_expr.clone())?);
295+
} else {
296+
return internal_err!(
297+
"Sort operator only valid in a statement context."
298+
);
299+
}
300+
}
301+
None => {}
302+
}
303+
select.projection(items);
304+
(ast::Distinct::On(exprs), on.input.as_ref())
305+
}
306+
};
307+
select.distinct(Some(select_distinct));
308+
self.select_to_sql_recursively(input, query, select, relation)
276309
}
277310
LogicalPlan::Join(join) => {
278311
match join.join_constraint {

datafusion/sql/tests/sql_integration.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4631,6 +4631,9 @@ fn roundtrip_statement() -> Result<()> {
46314631
"select (id-1)/2, count(*) / (sum(id/10)-1) as agg_expr from (select (id-1) as id from person) group by id",
46324632
"select CAST(id/2 as VARCHAR) NOT LIKE 'foo*' from person where NOT EXISTS (select ta.j1_id, tb.j2_string from j1 ta join j2 tb on (ta.j1_id = tb.j2_id))",
46334633
r#"select "First Name" from person_quoted_cols"#,
4634+
"select DISTINCT id FROM person",
4635+
"select DISTINCT on (id) id, first_name from person",
4636+
"select DISTINCT on (id) id, first_name from person order by id",
46344637
r#"select id, count("First Name") as cnt from (select id, "First Name" from person_quoted_cols) group by id"#,
46354638
"select id, count(*) as cnt from (select p1.id as id from person p1 inner join person p2 on p1.id=p2.id) group by id",
46364639
"select id, count(*), first_name from person group by first_name, id",

0 commit comments

Comments
 (0)