-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #129 from Fedomn/conjunction-function
feat(planner): introduce conjunction function
- Loading branch information
Showing
14 changed files
with
350 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
use arrow::array::ArrayRef; | ||
use derive_new::new; | ||
|
||
use crate::function::FunctionError; | ||
|
||
pub type ConjunctionFunc = fn(left: &ArrayRef, right: &ArrayRef) -> Result<ArrayRef, FunctionError>; | ||
|
||
#[derive(new, Clone)] | ||
pub struct ConjunctionFunction { | ||
pub(crate) name: String, | ||
pub(crate) function: ConjunctionFunc, | ||
} | ||
|
||
impl std::fmt::Debug for ConjunctionFunction { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
f.debug_struct("ConjunctionFunction") | ||
.field("name", &self.name) | ||
.finish() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
use std::sync::Arc; | ||
|
||
use arrow::array::{ArrayRef, BooleanArray}; | ||
use arrow::compute::{and_kleene, or_kleene}; | ||
use arrow::datatypes::DataType; | ||
use sqlparser::ast::BinaryOperator; | ||
|
||
use super::{ConjunctionFunc, ConjunctionFunction}; | ||
use crate::function::FunctionError; | ||
|
||
pub struct DefaultConjunctionFunctions; | ||
|
||
macro_rules! boolean_op { | ||
($LEFT:expr, $RIGHT:expr, $OP:ident) => {{ | ||
if *$LEFT.data_type() != DataType::Boolean || *$RIGHT.data_type() != DataType::Boolean { | ||
return Err(FunctionError::ConjunctionError(format!( | ||
"Cannot evaluate binary expression with types {:?} and {:?}, only Boolean supported", | ||
$LEFT.data_type(), | ||
$RIGHT.data_type() | ||
))); | ||
} | ||
|
||
let ll = $LEFT | ||
.as_any() | ||
.downcast_ref::<BooleanArray>() | ||
.expect("boolean_op failed to downcast array"); | ||
let rr = $RIGHT | ||
.as_any() | ||
.downcast_ref::<BooleanArray>() | ||
.expect("boolean_op failed to downcast array"); | ||
Ok(Arc::new($OP(&ll, &rr)?)) | ||
}}; | ||
} | ||
|
||
impl DefaultConjunctionFunctions { | ||
fn default_and_function(left: &ArrayRef, right: &ArrayRef) -> Result<ArrayRef, FunctionError> { | ||
boolean_op!(left, right, and_kleene) | ||
} | ||
|
||
fn default_or_function(left: &ArrayRef, right: &ArrayRef) -> Result<ArrayRef, FunctionError> { | ||
boolean_op!(left, right, or_kleene) | ||
} | ||
|
||
fn get_conjunction_function_internal( | ||
op: &BinaryOperator, | ||
) -> Result<(&str, ConjunctionFunc), FunctionError> { | ||
Ok(match op { | ||
BinaryOperator::And => ("and", Self::default_and_function), | ||
BinaryOperator::Or => ("or", Self::default_or_function), | ||
_ => { | ||
return Err(FunctionError::ConjunctionError(format!( | ||
"Unsupported conjunction operator {:?}", | ||
op | ||
))) | ||
} | ||
}) | ||
} | ||
|
||
pub fn get_conjunction_function( | ||
op: &BinaryOperator, | ||
) -> Result<ConjunctionFunction, FunctionError> { | ||
let (name, func) = Self::get_conjunction_function_internal(op)?; | ||
Ok(ConjunctionFunction::new(name.to_string(), func)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
mod conjunction_function; | ||
mod default_conjunction; | ||
pub use conjunction_function::*; | ||
pub use default_conjunction::*; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
55 changes: 55 additions & 0 deletions
55
src/planner_v2/binder/expression/bind_conjunction_expression.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
use derive_new::new; | ||
|
||
use super::{BoundCastExpression, BoundExpression, BoundExpressionBase}; | ||
use crate::function::{ConjunctionFunction, DefaultConjunctionFunctions}; | ||
use crate::planner_v2::{BindError, ExpressionBinder}; | ||
use crate::types_v2::LogicalType; | ||
|
||
#[derive(new, Debug, Clone)] | ||
pub struct BoundConjunctionExpression { | ||
pub(crate) base: BoundExpressionBase, | ||
pub(crate) function: ConjunctionFunction, | ||
pub(crate) children: Vec<BoundExpression>, | ||
} | ||
|
||
impl ExpressionBinder<'_> { | ||
pub fn bind_conjunction_expression( | ||
&mut self, | ||
left: &sqlparser::ast::Expr, | ||
op: &sqlparser::ast::BinaryOperator, | ||
right: &sqlparser::ast::Expr, | ||
result_names: &mut Vec<String>, | ||
result_types: &mut Vec<LogicalType>, | ||
) -> Result<BoundExpression, BindError> { | ||
let function = DefaultConjunctionFunctions::get_conjunction_function(op)?; | ||
let mut return_names = vec![]; | ||
let mut left = self.bind_expression(left, &mut return_names, &mut vec![])?; | ||
let mut right = self.bind_expression(right, &mut return_names, &mut vec![])?; | ||
if left.return_type() != LogicalType::Boolean { | ||
let alias = format!("cast({} as {}", left.alias(), LogicalType::Boolean); | ||
left = BoundCastExpression::add_cast_to_type( | ||
left, | ||
LogicalType::Boolean, | ||
alias.clone(), | ||
true, | ||
)?; | ||
return_names[0] = alias; | ||
} | ||
if right.return_type() != LogicalType::Boolean { | ||
let alias = format!("cast({} as {}", right.alias(), LogicalType::Boolean); | ||
right = BoundCastExpression::add_cast_to_type( | ||
right, | ||
LogicalType::Boolean, | ||
alias.clone(), | ||
true, | ||
)?; | ||
return_names[1] = alias; | ||
} | ||
result_names.push(format!("{}({},{})", op, return_names[0], return_names[1])); | ||
result_types.push(LogicalType::Boolean); | ||
let base = BoundExpressionBase::new("".to_string(), LogicalType::Boolean); | ||
Ok(BoundExpression::BoundConjunctionExpression( | ||
BoundConjunctionExpression::new(base, function, vec![left, right]), | ||
)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.