-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC / Prototype user defined sql planner might look like #11168
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,6 +31,7 @@ use sqlparser::ast::{ArrayElemTypeDef, ExactNumberInfo}; | |
use sqlparser::ast::{ColumnDef as SQLColumnDef, ColumnOption}; | ||
use sqlparser::ast::{DataType as SQLDataType, Ident, ObjectName, TableAlias}; | ||
|
||
use crate::expr::ArrayFunctionPlanner; | ||
use datafusion_common::config::ConfigOptions; | ||
use datafusion_common::TableReference; | ||
use datafusion_common::{ | ||
|
@@ -236,11 +237,28 @@ impl PlannerContext { | |
} | ||
} | ||
|
||
/// This trait allows users to customize the behavior of the SQL planner | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The idea is to pull the custom logic for planning binary operators into a trait -- then we can extend the sql planner by providing trait instances I think this is beneficial because:
I think this kind of approach is what might close #10534 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this seems like a fair approach. It's worth noting that we could do some of this with #11137 - e.g. we could move the array stuff into a |
||
pub trait UserDefinedPlanner { | ||
/// Plan the binary operation between two expressions, return None if not possible | ||
/// TODO make an API that avoids the need to clone the expressions | ||
fn plan_binary_op( | ||
&self, | ||
_op: sqlparser::ast::BinaryOperator, | ||
_left: Expr, | ||
_right: Expr, | ||
_schema: &DFSchema, | ||
) -> Result<Option<Expr>> { | ||
Ok(None) | ||
} | ||
} | ||
|
||
/// SQL query planner | ||
pub struct SqlToRel<'a, S: ContextProvider> { | ||
pub(crate) context_provider: &'a S, | ||
pub(crate) options: ParserOptions, | ||
pub(crate) normalizer: IdentNormalizer, | ||
/// user defined planner extensions | ||
pub(crate) planners: Vec<Arc<dyn UserDefinedPlanner>>, | ||
} | ||
|
||
impl<'a, S: ContextProvider> SqlToRel<'a, S> { | ||
|
@@ -249,14 +267,29 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> { | |
Self::new_with_options(context_provider, ParserOptions::default()) | ||
} | ||
|
||
/// add an user defined planner | ||
pub fn with_user_defined_planner( | ||
mut self, | ||
planner: Arc<dyn UserDefinedPlanner>, | ||
) -> Self { | ||
self.planners.push(planner); | ||
self | ||
} | ||
|
||
/// Create a new query planner | ||
pub fn new_with_options(context_provider: &'a S, options: ParserOptions) -> Self { | ||
let normalize = options.enable_ident_normalization; | ||
let array_planner = | ||
Arc::new(ArrayFunctionPlanner::try_new(context_provider).unwrap()) as _; | ||
|
||
SqlToRel { | ||
context_provider, | ||
options, | ||
normalizer: IdentNormalizer::new(normalize), | ||
planners: vec![], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why not just put the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My thinking was that I eventually wanted to move the definition into a different crate |
||
} | ||
// todo put this somewhere else | ||
.with_user_defined_planner(array_planner) | ||
} | ||
|
||
pub fn build_schema(&self, columns: Vec<SQLColumnDef>) -> Result<Schema> { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My thinking is that this
ArrayFunctionPlanner
would be in the array_functions crate and thus avoid the implicit dependency on names of functions