use std::fmt;
use arrow::datatypes::DataType as ArrowDataType;
use crate::{
error::Result,
expr::{AggregateSpec, BinaryOp, Expr},
plan::ProjectionOutput,
policy::PlanningPolicy,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ExpressionUse {
Value,
FilterPredicate,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AggregateBinding {
SingleStage,
FinalMerge,
}
pub trait BackendCapabilities: fmt::Debug + Send + Sync {
fn supports_type(&self, data_type: &ArrowDataType) -> bool;
fn binary_output_type(&self, op: BinaryOp, left: &ArrowDataType, right: &ArrowDataType) -> Result<ArrowDataType>;
fn check_expression(&self, expr: &Expr, expression_use: ExpressionUse) -> Result<()>;
fn check_projection_output(&self, output: &ProjectionOutput) -> Result<()>;
fn aggregate_output_names(&self, spec: &AggregateSpec, binding: AggregateBinding) -> Result<Vec<String>>;
}
#[derive(Debug, Clone, Copy)]
pub struct AnalysisContext<'a> {
backend: &'a dyn BackendCapabilities,
policy: PlanningPolicy,
}
impl<'a> AnalysisContext<'a> {
pub const fn new(backend: &'a dyn BackendCapabilities, policy: PlanningPolicy) -> Self {
Self { backend, policy }
}
#[must_use]
pub const fn with_policy(mut self, policy: PlanningPolicy) -> Self {
self.policy = policy;
self
}
pub(crate) const fn backend(&self) -> &'a dyn BackendCapabilities {
self.backend
}
pub const fn policy(&self) -> PlanningPolicy {
self.policy
}
}