use crate::planner::{ContextProvider, PlannerContext, SqlToRel};
use datafusion_common::{DFSchema, DataFusionError, Result};
use datafusion_expr::expr::Sort;
use datafusion_expr::Expr;
use sqlparser::ast::{Expr as SQLExpr, OrderByExpr, Value};
impl<'a, S: ContextProvider> SqlToRel<'a, S> {
pub(crate) fn order_by_to_sort_expr(
&self,
e: OrderByExpr,
schema: &DFSchema,
) -> Result<Expr> {
let OrderByExpr {
asc,
expr,
nulls_first,
} = e;
let expr = match expr {
SQLExpr::Value(Value::Number(v, _)) => {
let field_index = v
.parse::<usize>()
.map_err(|err| DataFusionError::Plan(err.to_string()))?;
if field_index == 0 {
return Err(DataFusionError::Plan(
"Order by index starts at 1 for column indexes".to_string(),
));
} else if schema.fields().len() < field_index {
return Err(DataFusionError::Plan(format!(
"Order by column out of bounds, specified: {}, max: {}",
field_index,
schema.fields().len()
)));
}
let field = schema.field(field_index - 1);
Expr::Column(field.qualified_column())
}
e => self.sql_expr_to_logical_expr(e, schema, &mut PlannerContext::new())?,
};
Ok({
let asc = asc.unwrap_or(true);
Expr::Sort(Sort::new(
Box::new(expr),
asc,
nulls_first.unwrap_or(!asc),
))
})
}
}