dbx_core/sql/optimizer/
mod.rs1mod constant_folding;
7mod distributed_pushdown;
8mod limit_pushdown;
9mod predicate_pushdown;
10mod projection_pushdown;
11mod subquery_unnesting;
12mod tier_pruning;
13
14#[cfg(test)]
15mod tests;
16
17use crate::error::DbxResult;
18use crate::sql::planner::LogicalPlan;
19
20pub use constant_folding::ConstantFoldingRule;
21pub use distributed_pushdown::DistributedPushdownRule;
22pub use limit_pushdown::LimitPushdownRule;
23pub use predicate_pushdown::PredicatePushdownRule;
24pub use projection_pushdown::ProjectionPushdownRule;
25pub use subquery_unnesting::SubqueryUnnestingRule;
26pub use tier_pruning::TierPruningRule;
27
28pub trait OptimizationRule: Send + Sync {
30 fn name(&self) -> &str;
32
33 fn apply(&self, plan: LogicalPlan) -> DbxResult<LogicalPlan>;
35}
36
37pub struct QueryOptimizer {
39 rules: Vec<Box<dyn OptimizationRule>>,
40}
41
42impl QueryOptimizer {
43 pub fn new() -> Self {
45 Self {
46 rules: vec![
47 Box::new(SubqueryUnnestingRule), Box::new(PredicatePushdownRule),
49 Box::new(ProjectionPushdownRule),
50 Box::new(ConstantFoldingRule),
51 Box::new(DistributedPushdownRule),
52 Box::new(LimitPushdownRule),
53 ],
54 }
55 }
56
57 pub fn register_rule(&mut self, rule: Box<dyn OptimizationRule>) {
59 self.rules.push(rule);
61 }
62
63 pub fn optimize(&self, plan: LogicalPlan) -> DbxResult<LogicalPlan> {
65 let mut optimized = plan;
66 for rule in &self.rules {
67 optimized = rule.apply(optimized)?;
68 }
69 Ok(optimized)
70 }
71}
72
73impl Default for QueryOptimizer {
74 fn default() -> Self {
75 Self::new()
76 }
77}