Skip to content

Commit c0937a1

Browse files
committed
refactor: ordery by all
1 parent 91fc9f6 commit c0937a1

File tree

5 files changed

+82
-243
lines changed

5 files changed

+82
-243
lines changed

datafusion/expr/src/expr.rs

Lines changed: 18 additions & 158 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ use datafusion_common::{
3939
use datafusion_functions_window_common::field::WindowUDFFieldArgs;
4040
use sqlparser::ast::{
4141
display_comma_separated, ExceptSelectItem, ExcludeSelectItem, IlikeSelectItem,
42-
NullTreatment, OrderByExpr, OrderByOptions, RenameSelectItem, ReplaceSelectElement,
42+
NullTreatment, RenameSelectItem, ReplaceSelectElement,
4343
};
4444

4545
/// Represents logical expressions such as `A + 1`, or `CAST(c1 AS int)`.
@@ -701,24 +701,6 @@ impl TryCast {
701701
}
702702
}
703703

704-
/// OrderBy Expressions
705-
pub enum OrderByExprs {
706-
OrderByExprVec(Vec<OrderByExpr>),
707-
All {
708-
exprs: Vec<Expr>,
709-
options: OrderByOptions,
710-
},
711-
}
712-
713-
impl OrderByExprs {
714-
pub fn is_empty(&self) -> bool {
715-
match self {
716-
OrderByExprs::OrderByExprVec(exprs) => exprs.is_empty(),
717-
OrderByExprs::All { exprs, .. } => exprs.is_empty(),
718-
}
719-
}
720-
}
721-
722704
/// SORT expression
723705
#[derive(Clone, PartialEq, Eq, PartialOrd, Hash, Debug)]
724706
pub struct Sort {
@@ -1765,38 +1747,23 @@ impl Expr {
17651747
pub fn infer_placeholder_types(self, schema: &DFSchema) -> Result<(Expr, bool)> {
17661748
let mut has_placeholder = false;
17671749
self.transform(|mut expr| {
1768-
match &mut expr {
1769-
// Default to assuming the arguments are the same type
1770-
Expr::BinaryExpr(BinaryExpr { left, op: _, right }) => {
1771-
rewrite_placeholder(left.as_mut(), right.as_ref(), schema)?;
1772-
rewrite_placeholder(right.as_mut(), left.as_ref(), schema)?;
1773-
}
1774-
Expr::Between(Between {
1775-
expr,
1776-
negated: _,
1777-
low,
1778-
high,
1779-
}) => {
1780-
rewrite_placeholder(low.as_mut(), expr.as_ref(), schema)?;
1781-
rewrite_placeholder(high.as_mut(), expr.as_ref(), schema)?;
1782-
}
1783-
Expr::InList(InList {
1784-
expr,
1785-
list,
1786-
negated: _,
1787-
}) => {
1788-
for item in list.iter_mut() {
1789-
rewrite_placeholder(item, expr.as_ref(), schema)?;
1790-
}
1791-
}
1792-
Expr::Like(Like { expr, pattern, .. })
1793-
| Expr::SimilarTo(Like { expr, pattern, .. }) => {
1794-
rewrite_placeholder(pattern.as_mut(), expr.as_ref(), schema)?;
1795-
}
1796-
Expr::Placeholder(_) => {
1797-
has_placeholder = true;
1798-
}
1799-
_ => {}
1750+
// Default to assuming the arguments are the same type
1751+
if let Expr::BinaryExpr(BinaryExpr { left, op: _, right }) = &mut expr {
1752+
rewrite_placeholder(left.as_mut(), right.as_ref(), schema)?;
1753+
rewrite_placeholder(right.as_mut(), left.as_ref(), schema)?;
1754+
};
1755+
if let Expr::Between(Between {
1756+
expr,
1757+
negated: _,
1758+
low,
1759+
high,
1760+
}) = &mut expr
1761+
{
1762+
rewrite_placeholder(low.as_mut(), expr.as_ref(), schema)?;
1763+
rewrite_placeholder(high.as_mut(), expr.as_ref(), schema)?;
1764+
}
1765+
if let Expr::Placeholder(_) = &expr {
1766+
has_placeholder = true;
18001767
}
18011768
Ok(Transformed::yes(expr))
18021769
})
@@ -3218,117 +3185,10 @@ mod test {
32183185
case, lit, qualified_wildcard, wildcard, wildcard_with_options, ColumnarValue,
32193186
ScalarFunctionArgs, ScalarUDF, ScalarUDFImpl, Volatility,
32203187
};
3221-
use arrow::datatypes::{Field, Schema};
32223188
use sqlparser::ast;
32233189
use sqlparser::ast::{Ident, IdentWithAlias};
32243190
use std::any::Any;
32253191

3226-
#[test]
3227-
fn infer_placeholder_in_clause() {
3228-
// SELECT * FROM employees WHERE department_id IN ($1, $2, $3);
3229-
let column = col("department_id");
3230-
let param_placeholders = vec![
3231-
Expr::Placeholder(Placeholder {
3232-
id: "$1".to_string(),
3233-
data_type: None,
3234-
}),
3235-
Expr::Placeholder(Placeholder {
3236-
id: "$2".to_string(),
3237-
data_type: None,
3238-
}),
3239-
Expr::Placeholder(Placeholder {
3240-
id: "$3".to_string(),
3241-
data_type: None,
3242-
}),
3243-
];
3244-
let in_list = Expr::InList(InList {
3245-
expr: Box::new(column),
3246-
list: param_placeholders,
3247-
negated: false,
3248-
});
3249-
3250-
let schema = Arc::new(Schema::new(vec![
3251-
Field::new("name", DataType::Utf8, true),
3252-
Field::new("department_id", DataType::Int32, true),
3253-
]));
3254-
let df_schema = DFSchema::try_from(schema).unwrap();
3255-
3256-
let (inferred_expr, contains_placeholder) =
3257-
in_list.infer_placeholder_types(&df_schema).unwrap();
3258-
3259-
assert!(contains_placeholder);
3260-
3261-
match inferred_expr {
3262-
Expr::InList(in_list) => {
3263-
for expr in in_list.list {
3264-
match expr {
3265-
Expr::Placeholder(placeholder) => {
3266-
assert_eq!(
3267-
placeholder.data_type,
3268-
Some(DataType::Int32),
3269-
"Placeholder {} should infer Int32",
3270-
placeholder.id
3271-
);
3272-
}
3273-
_ => panic!("Expected Placeholder expression"),
3274-
}
3275-
}
3276-
}
3277-
_ => panic!("Expected InList expression"),
3278-
}
3279-
}
3280-
3281-
#[test]
3282-
fn infer_placeholder_like_and_similar_to() {
3283-
// name LIKE $1
3284-
let schema =
3285-
Arc::new(Schema::new(vec![Field::new("name", DataType::Utf8, true)]));
3286-
let df_schema = DFSchema::try_from(schema).unwrap();
3287-
3288-
let like = Like {
3289-
expr: Box::new(col("name")),
3290-
pattern: Box::new(Expr::Placeholder(Placeholder {
3291-
id: "$1".to_string(),
3292-
data_type: None,
3293-
})),
3294-
negated: false,
3295-
case_insensitive: false,
3296-
escape_char: None,
3297-
};
3298-
3299-
let expr = Expr::Like(like.clone());
3300-
3301-
let (inferred_expr, _) = expr.infer_placeholder_types(&df_schema).unwrap();
3302-
match inferred_expr {
3303-
Expr::Like(like) => match *like.pattern {
3304-
Expr::Placeholder(placeholder) => {
3305-
assert_eq!(placeholder.data_type, Some(DataType::Utf8));
3306-
}
3307-
_ => panic!("Expected Placeholder"),
3308-
},
3309-
_ => panic!("Expected Like"),
3310-
}
3311-
3312-
// name SIMILAR TO $1
3313-
let expr = Expr::SimilarTo(like);
3314-
3315-
let (inferred_expr, _) = expr.infer_placeholder_types(&df_schema).unwrap();
3316-
match inferred_expr {
3317-
Expr::SimilarTo(like) => match *like.pattern {
3318-
Expr::Placeholder(placeholder) => {
3319-
assert_eq!(
3320-
placeholder.data_type,
3321-
Some(DataType::Utf8),
3322-
"Placeholder {} should infer Utf8",
3323-
placeholder.id
3324-
);
3325-
}
3326-
_ => panic!("Expected Placeholder expression"),
3327-
},
3328-
_ => panic!("Expected SimilarTo expression"),
3329-
}
3330-
}
3331-
33323192
#[test]
33333193
#[allow(deprecated)]
33343194
fn format_case_when() -> Result<()> {

datafusion/sql/src/expr/function.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use datafusion_common::{
2222
internal_datafusion_err, internal_err, not_impl_err, plan_datafusion_err, plan_err,
2323
DFSchema, Dependency, Diagnostic, Result, Span,
2424
};
25-
use datafusion_expr::expr::{OrderByExprs, ScalarFunction, Unnest, WildcardOptions};
25+
use datafusion_expr::expr::{ScalarFunction, Unnest, WildcardOptions};
2626
use datafusion_expr::planner::{PlannerResult, RawAggregateExpr, RawWindowExpr};
2727
use datafusion_expr::{
2828
expr, Expr, ExprFunctionExt, ExprSchemable, WindowFrame, WindowFunctionDefinition,
@@ -291,7 +291,7 @@ impl<S: ContextProvider> SqlToRel<'_, S> {
291291
.map(|e| self.sql_expr_to_logical_expr(e, schema, planner_context))
292292
.collect::<Result<Vec<_>>>()?;
293293
let mut order_by = self.order_by_to_sort_expr(
294-
OrderByExprs::OrderByExprVec(window.order_by),
294+
window.order_by,
295295
schema,
296296
planner_context,
297297
// Numeric literals in window function ORDER BY are treated as constants
@@ -405,7 +405,7 @@ impl<S: ContextProvider> SqlToRel<'_, S> {
405405
(!within_group.is_empty()).then_some(within_group)
406406
} else {
407407
let order_by = self.order_by_to_sort_expr(
408-
OrderByExprs::OrderByExprVec(order_by),
408+
order_by,
409409
schema,
410410
planner_context,
411411
true,

datafusion/sql/src/expr/order_by.rs

Lines changed: 38 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use crate::planner::{ContextProvider, PlannerContext, SqlToRel};
1919
use datafusion_common::{
2020
not_impl_err, plan_datafusion_err, plan_err, Column, DFSchema, Result,
2121
};
22-
use datafusion_expr::expr::{OrderByExprs, Sort};
22+
use datafusion_expr::expr::Sort;
2323
use datafusion_expr::{Expr, SortExpr};
2424
use sqlparser::ast::{
2525
Expr as SQLExpr, OrderByExpr, OrderByOptions, Value, ValueWithSpan,
@@ -41,7 +41,7 @@ impl<S: ContextProvider> SqlToRel<'_, S> {
4141
/// If false, interpret numeric literals as constant values.
4242
pub(crate) fn order_by_to_sort_expr(
4343
&self,
44-
order_by_exprs: OrderByExprs,
44+
order_by_exprs: Vec<OrderByExpr>,
4545
input_schema: &DFSchema,
4646
planner_context: &mut PlannerContext,
4747
literal_to_column: bool,
@@ -72,62 +72,48 @@ impl<S: ContextProvider> SqlToRel<'_, S> {
7272
Sort::new(expr, asc, nulls_first)
7373
};
7474

75-
match order_by_exprs {
76-
OrderByExprs::OrderByExprVec(expressions) => {
77-
for e in expressions {
78-
let OrderByExpr {
79-
expr,
80-
options: OrderByOptions { asc, nulls_first },
81-
with_fill,
82-
} = e;
75+
for order_by_expr in order_by_exprs {
76+
let OrderByExpr {
77+
expr,
78+
options: OrderByOptions { asc, nulls_first },
79+
with_fill,
80+
} = order_by_expr;
8381

84-
if let Some(with_fill) = with_fill {
85-
return not_impl_err!(
86-
"ORDER BY WITH FILL is not supported: {with_fill}"
87-
);
88-
}
82+
if let Some(with_fill) = with_fill {
83+
return not_impl_err!("ORDER BY WITH FILL is not supported: {with_fill}");
84+
}
8985

90-
let expr = match expr {
91-
SQLExpr::Value(ValueWithSpan {
92-
value: Value::Number(v, _),
93-
span: _,
94-
}) if literal_to_column => {
95-
let field_index = v
96-
.parse::<usize>()
97-
.map_err(|err| plan_datafusion_err!("{}", err))?;
86+
let expr = match expr {
87+
SQLExpr::Value(ValueWithSpan {
88+
value: Value::Number(v, _),
89+
span: _,
90+
}) if literal_to_column => {
91+
let field_index = v
92+
.parse::<usize>()
93+
.map_err(|err| plan_datafusion_err!("{}", err))?;
9894

99-
if field_index == 0 {
100-
return plan_err!(
101-
"Order by index starts at 1 for column indexes"
102-
);
103-
} else if input_schema.fields().len() < field_index {
104-
return plan_err!(
105-
"Order by column out of bounds, specified: {}, max: {}",
106-
field_index,
107-
input_schema.fields().len()
108-
);
109-
}
95+
if field_index == 0 {
96+
return plan_err!(
97+
"Order by index starts at 1 for column indexes"
98+
);
99+
} else if input_schema.fields().len() < field_index {
100+
return plan_err!(
101+
"Order by column out of bounds, specified: {}, max: {}",
102+
field_index,
103+
input_schema.fields().len()
104+
);
105+
}
110106

111-
Expr::Column(Column::from(
112-
input_schema.qualified_field(field_index - 1),
113-
))
114-
}
115-
e => self.sql_expr_to_logical_expr(
116-
e,
117-
order_by_schema,
118-
planner_context,
119-
)?,
120-
};
121-
sort_expr_vec.push(make_sort_expr(expr, asc, nulls_first));
107+
Expr::Column(Column::from(
108+
input_schema.qualified_field(field_index - 1),
109+
))
122110
}
123-
}
124-
OrderByExprs::All { exprs, options } => {
125-
let OrderByOptions { asc, nulls_first } = options;
126-
for expr in exprs {
127-
sort_expr_vec.push(make_sort_expr(expr, asc, nulls_first));
111+
e => {
112+
self.sql_expr_to_logical_expr(e, order_by_schema, planner_context)?
128113
}
129-
}
130-
};
114+
};
115+
sort_expr_vec.push(make_sort_expr(expr, asc, nulls_first));
116+
}
131117

132118
Ok(sort_expr_vec)
133119
}

0 commit comments

Comments
 (0)