mod constant_folding;
mod distributed_pushdown;
mod limit_pushdown;
mod predicate_pushdown;
mod projection_pushdown;
mod subquery_unnesting;
mod tier_pruning;
#[cfg(test)]
mod tests;
use crate::error::DbxResult;
use crate::sql::planner::LogicalPlan;
pub use constant_folding::ConstantFoldingRule;
pub use distributed_pushdown::DistributedPushdownRule;
pub use limit_pushdown::LimitPushdownRule;
pub use predicate_pushdown::PredicatePushdownRule;
pub use projection_pushdown::ProjectionPushdownRule;
pub use subquery_unnesting::SubqueryUnnestingRule;
pub use tier_pruning::TierPruningRule;
pub trait OptimizationRule: Send + Sync {
fn name(&self) -> &str;
fn apply(&self, plan: LogicalPlan) -> DbxResult<LogicalPlan>;
}
pub struct QueryOptimizer {
rules: Vec<Box<dyn OptimizationRule>>,
}
impl QueryOptimizer {
pub fn new() -> Self {
Self {
rules: vec![
Box::new(SubqueryUnnestingRule), Box::new(PredicatePushdownRule),
Box::new(ProjectionPushdownRule),
Box::new(ConstantFoldingRule),
Box::new(DistributedPushdownRule),
Box::new(LimitPushdownRule),
],
}
}
pub fn register_rule(&mut self, rule: Box<dyn OptimizationRule>) {
self.rules.push(rule);
}
pub fn optimize(&self, plan: LogicalPlan) -> DbxResult<LogicalPlan> {
let mut optimized = plan;
for rule in &self.rules {
optimized = rule.apply(optimized)?;
}
Ok(optimized)
}
}
impl Default for QueryOptimizer {
fn default() -> Self {
Self::new()
}
}