use arrow::datatypes::DataType;
use datafusion_common::{DFSchemaRef, DataFusionError, Result};
use crate::{execution_props::ExecutionProps, Expr, ExprSchemable};
pub trait SimplifyInfo {
fn is_boolean_type(&self, expr: &Expr) -> Result<bool>;
fn nullable(&self, expr: &Expr) -> Result<bool>;
fn execution_props(&self) -> &ExecutionProps;
fn get_data_type(&self, expr: &Expr) -> Result<DataType>;
}
#[derive(Debug, Clone)]
pub struct SimplifyContext<'a> {
schema: Option<DFSchemaRef>,
props: &'a ExecutionProps,
}
impl<'a> SimplifyContext<'a> {
pub fn new(props: &'a ExecutionProps) -> Self {
Self {
schema: None,
props,
}
}
pub fn with_schema(mut self, schema: DFSchemaRef) -> Self {
self.schema = Some(schema);
self
}
}
impl SimplifyInfo for SimplifyContext<'_> {
fn is_boolean_type(&self, expr: &Expr) -> Result<bool> {
if let Some(schema) = &self.schema {
if let Ok(DataType::Boolean) = expr.get_type(schema) {
return Ok(true);
}
}
Ok(false)
}
fn nullable(&self, expr: &Expr) -> Result<bool> {
let schema = self.schema.as_ref().ok_or_else(|| {
DataFusionError::Internal(
"attempt to get nullability without schema".to_string(),
)
})?;
expr.nullable(schema.as_ref())
}
fn get_data_type(&self, expr: &Expr) -> Result<DataType> {
let schema = self.schema.as_ref().ok_or_else(|| {
DataFusionError::Internal(
"attempt to get data type without schema".to_string(),
)
})?;
expr.get_type(schema)
}
fn execution_props(&self) -> &ExecutionProps {
self.props
}
}
#[derive(Debug)]
pub enum ExprSimplifyResult {
Simplified(Expr),
Original(Vec<Expr>),
}