Skip to content

Commit

Permalink
Implement user defined planner for position
Browse files Browse the repository at this point in the history
  • Loading branch information
xinlifoobar committed Jul 4, 2024
1 parent 515bce6 commit 9a9ae70
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 9 deletions.
9 changes: 6 additions & 3 deletions datafusion/expr/src/planner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,12 @@ pub trait UserDefinedSQLPlanner: Send + Sync {
Ok(PlannerResult::Original(exprs))
}

// Plan the POSITION expression, e.g., POSITION(<expr> in <expr>)
// returns origin expression arguments if not possible
fn plan_position(&self, args: Vec<Expr>) -> Result<PlannerResult<Vec<Expr>>> {
// Plan the user defined function, returns origin expression arguments if not possible
fn plan_udf(
&self,
_sql: &sqlparser::ast::Expr,
args: Vec<Expr>,
) -> Result<PlannerResult<Vec<Expr>>> {
Ok(PlannerResult::Original(args))
}
}
Expand Down
12 changes: 10 additions & 2 deletions datafusion/functions/src/unicode/planner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,22 @@ use datafusion_common::Result;
use datafusion_expr::{
expr::ScalarFunction,
planner::{PlannerResult, UserDefinedSQLPlanner},
Expr,
sqlparser, Expr,
};

#[derive(Default)]
pub struct PositionPlanner {}

impl UserDefinedSQLPlanner for PositionPlanner {
fn plan_position(&self, args: Vec<Expr>) -> Result<PlannerResult<Vec<Expr>>> {
fn plan_udf(
&self,
sql: &sqlparser::ast::Expr,
args: Vec<Expr>,
) -> Result<PlannerResult<Vec<Expr>>> {
let sqlparser::ast::Expr::Position { .. } = sql else {
return Ok(PlannerResult::Original(args));
};

Ok(PlannerResult::Planned(Expr::ScalarFunction(
ScalarFunction::new_udf(crate::unicode::strpos(), args),
)))
Expand Down
9 changes: 5 additions & 4 deletions datafusion/sql/src/expr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
schema: &DFSchema,
planner_context: &mut PlannerContext,
) -> Result<Expr> {
let sql_not_moved = sql.clone();
match sql {
SQLExpr::Value(value) => {
self.parse_value(value, planner_context.prepare_param_data_types())
Expand Down Expand Up @@ -601,18 +602,18 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
self.sql_expr_to_logical_expr(*expr, schema, planner_context)?;
let fullstr =
self.sql_expr_to_logical_expr(*r#in, schema, planner_context)?;
let mut extract_args = vec![fullstr, substr];
let mut extracted_args = vec![fullstr, substr];

for planner in self.planners.iter() {
match planner.plan_position(extract_args)? {
match planner.plan_udf(&sql_not_moved, extracted_args)? {
PlannerResult::Planned(expr) => return Ok(expr),
PlannerResult::Original(args) => {
extract_args = args;
extracted_args = args;
}
}
}

not_impl_err!("Position not supported by UserDefinedExtensionPlanners: {extract_args:?}")
not_impl_err!("Position not supported by UserDefinedExtensionPlanners: {extracted_args:?}")
}
SQLExpr::AtTimeZone {
timestamp,
Expand Down

0 comments on commit 9a9ae70

Please sign in to comment.