use arrow::datatypes::DataType;
use datafusion_common::{DFSchemaRef, Result, internal_datafusion_err};
use crate::{Expr, ExprSchemable, execution_props::ExecutionProps};
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
&& 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(|| {
internal_datafusion_err!("attempt to get nullability without schema")
})?;
expr.nullable(schema.as_ref())
}
fn get_data_type(&self, expr: &Expr) -> Result<DataType> {
let schema = self.schema.as_ref().ok_or_else(|| {
internal_datafusion_err!("attempt to get data type without schema")
})?;
expr.get_type(schema)
}
fn execution_props(&self) -> &ExecutionProps {
self.props
}
}
#[derive(Debug)]
pub enum ExprSimplifyResult {
Simplified(Expr),
Original(Vec<Expr>),
}