diff --git a/src/database.rs b/src/database.rs index 1b94a63..29fdd77 100644 --- a/src/database.rs +++ b/src/database.rs @@ -56,7 +56,7 @@ impl Database { // println!("{:?}", logical_plan); // logical plan -> physical plan - let mut optimizer = Optimizer::new(); + let optimizer = Optimizer::new(); let physical_plan = optimizer.find_best(logical_plan); // println!("{:?}", physical_plan); diff --git a/src/optimizer/heuristic/graph.rs b/src/optimizer/heuristic/graph.rs index c838e8d..ecf2be0 100644 --- a/src/optimizer/heuristic/graph.rs +++ b/src/optimizer/heuristic/graph.rs @@ -1,16 +1,15 @@ -use petgraph::stable_graph::{StableDiGraph, NodeIndex}; +use petgraph::stable_graph::{NodeIndex, StableDiGraph}; use super::opt_expr::OptExprNodeId; - pub type HepNodeId = NodeIndex; pub struct HepNode { id: HepNodeId, - // plan: + // plan: } pub struct HepGraph { graph: StableDiGraph, root: HepNodeId, -} \ No newline at end of file +} diff --git a/src/optimizer/heuristic/matcher.rs b/src/optimizer/heuristic/matcher.rs index e26caff..0fd9cae 100644 --- a/src/optimizer/heuristic/matcher.rs +++ b/src/optimizer/heuristic/matcher.rs @@ -1,3 +1 @@ -pub struct HepMatcher { - -} \ No newline at end of file +pub struct HepMatcher {} diff --git a/src/optimizer/heuristic/mod.rs b/src/optimizer/heuristic/mod.rs index 323216f..8c3567e 100644 --- a/src/optimizer/heuristic/mod.rs +++ b/src/optimizer/heuristic/mod.rs @@ -1,17 +1,15 @@ use std::sync::Arc; -use crate::planner::logical_plan::{LogicalPlan, self}; +use crate::planner::logical_plan::{self, LogicalPlan}; pub mod batch; -pub mod rule; -pub mod pattern; pub mod graph; pub mod matcher; pub mod opt_expr; +pub mod pattern; +pub mod rule; -pub struct HepOptimizer { - -} +pub struct HepOptimizer {} impl HepOptimizer { // output the optimized logical plan pub fn find_best(&self, logical_plan: LogicalPlan) -> LogicalPlan { @@ -21,6 +19,6 @@ impl HepOptimizer { } impl Default for HepOptimizer { fn default() -> Self { - Self{} + Self {} } -} \ No newline at end of file +} diff --git a/src/optimizer/heuristic/opt_expr.rs b/src/optimizer/heuristic/opt_expr.rs index 2aea5fd..814499c 100644 --- a/src/optimizer/heuristic/opt_expr.rs +++ b/src/optimizer/heuristic/opt_expr.rs @@ -12,4 +12,4 @@ pub enum OptExprNode { pub struct OptExpr { pub root: OptExprNode, pub children: Vec, -} \ No newline at end of file +} diff --git a/src/optimizer/heuristic/pattern.rs b/src/optimizer/heuristic/pattern.rs index 3936569..b4fd839 100644 --- a/src/optimizer/heuristic/pattern.rs +++ b/src/optimizer/heuristic/pattern.rs @@ -11,4 +11,4 @@ pub enum PatternChildrenPredicate { MatchedRecursive, Predicate(Vec), None, -} \ No newline at end of file +} diff --git a/src/optimizer/heuristic/rule.rs b/src/optimizer/heuristic/rule.rs index 1ec36f2..d47a1cd 100644 --- a/src/optimizer/heuristic/rule.rs +++ b/src/optimizer/heuristic/rule.rs @@ -1,8 +1,11 @@ use std::fmt::Debug; -use super::{pattern::Pattern, graph::{HepGraph, HepNodeId}}; +use super::{ + graph::{HepGraph, HepNodeId}, + pattern::Pattern, +}; pub trait Rule: Debug { fn pattern(&self) -> &Pattern; fn apply(&self, node_id: HepNodeId, graph: &mut HepGraph) -> bool; -} \ No newline at end of file +} diff --git a/src/optimizer/mod.rs b/src/optimizer/mod.rs index 06e7355..3b8d77a 100644 --- a/src/optimizer/mod.rs +++ b/src/optimizer/mod.rs @@ -1,14 +1,19 @@ use std::sync::Arc; -use crate::planner::{logical_plan::{LogicalPlan, self}, operator::LogicalOperator}; +use crate::planner::{ + logical_plan::{self, LogicalPlan}, + operator::LogicalOperator, +}; -use self::{physical_plan::PhysicalPlan, heuristic::HepOptimizer, physical_optimizer::PhysicalOptimizer}; +use self::{ + heuristic::HepOptimizer, physical_optimizer::PhysicalOptimizer, physical_plan::PhysicalPlan, +}; +pub mod heuristic; pub mod operator; +pub mod physical_optimizer; pub mod physical_plan; -pub mod heuristic; pub mod rule; -pub mod physical_optimizer; pub struct Optimizer { hep_optimizer: HepOptimizer, @@ -16,110 +21,17 @@ pub struct Optimizer { } impl Optimizer { pub fn new() -> Self { - Self { hep_optimizer: HepOptimizer::default(), physical_optimizer: PhysicalOptimizer {}} + Self { + hep_optimizer: HepOptimizer::default(), + physical_optimizer: PhysicalOptimizer {}, + } } pub fn find_best(&self, logical_plan: LogicalPlan) -> PhysicalPlan { - // find best logical plan + // optimize logical plan let optimized_logical_plan = self.hep_optimizer.find_best(logical_plan); - // TODO find best physical plan - self.physical_optimizer.find_best(Arc::new(optimized_logical_plan)) - - // let physical_node = Self::build_physical_node( - // self.logical_plan.clone(), - // self.logical_plan.children.clone(), - // ); - // TODO 递归 - // Self::build_physical_plan(physical_node, self.logical_plan.clone()) - } - - fn build_physical_plan( - mut physical_plan: PhysicalPlan, - logical_plan: Arc, - ) -> PhysicalPlan { - for logical_child in logical_plan.children.iter() { - let physical_child = - Self::build_physical_node(logical_child.clone(), logical_child.children.clone()); - physical_plan - .children - .push(Arc::new(Self::build_physical_plan( - physical_child, - logical_child.clone(), - ))); - } - physical_plan - } - - fn build_physical_node( - logical_node: Arc, - logical_node_children: Vec>, - ) -> PhysicalPlan { - match logical_node.operator { - LogicalOperator::Dummy => PhysicalPlan::dummy(), - LogicalOperator::CreateTable(ref logic_create_table) => { - PhysicalPlan::new_create_table_node( - &logic_create_table.table_name, - &logic_create_table.schema, - ) - } - LogicalOperator::Insert(ref logic_insert) => { - PhysicalPlan::new_insert_node(&logic_insert.table_name, &logic_insert.columns) - } - LogicalOperator::Values(ref logical_values) => { - PhysicalPlan::new_values_node(&logical_values.columns, &logical_values.tuples) - } - LogicalOperator::Project(ref logical_project) => { - PhysicalPlan::new_project_node(&logical_project.expressions) - } - LogicalOperator::Filter(ref logical_filter) => { - // filter下只有一个子节点 - let child_logical_node = logical_node_children[0].clone(); - let child_physical_node = Self::build_physical_node( - child_logical_node.clone(), - child_logical_node.children.clone(), - ); - PhysicalPlan::new_filter_node( - &logical_filter.predicate, - child_physical_node.operator.clone(), - ) - } - LogicalOperator::Scan(ref logical_table_scan) => PhysicalPlan::new_table_scan_node( - &logical_table_scan.table_oid, - &logical_table_scan.columns, - ), - LogicalOperator::Limit(ref logical_limit) => { - // limit下只有一个子节点 - let child_logical_node = logical_node_children[0].clone(); - let child_physical_node = Self::build_physical_node( - child_logical_node.clone(), - child_logical_node.children.clone(), - ); - PhysicalPlan::new_limit_node( - &logical_limit.limit, - &logical_limit.offset, - child_physical_node.operator.clone(), - ) - } - LogicalOperator::Join(ref logical_join) => { - let left_logical_node = logical_node_children[0].clone(); - let right_logical_node = logical_node_children[1].clone(); - let left_physical_node = Self::build_physical_node( - left_logical_node.clone(), - left_logical_node.children.clone(), - ); - let right_physical_node = Self::build_physical_node( - right_logical_node.clone(), - right_logical_node.children.clone(), - ); - PhysicalPlan::new_nested_loop_join_node( - logical_join.join_type, - logical_join.condition.clone(), - left_physical_node.operator.clone(), - right_physical_node.operator.clone(), - ) - } - _ => unimplemented!(), - } + // optimize physical plan + self.physical_optimizer.find_best(optimized_logical_plan) } } diff --git a/src/optimizer/physical_optimizer.rs b/src/optimizer/physical_optimizer.rs index 5972fbd..cd365ad 100644 --- a/src/optimizer/physical_optimizer.rs +++ b/src/optimizer/physical_optimizer.rs @@ -1,12 +1,18 @@ use std::sync::Arc; -use crate::planner::{logical_plan::LogicalPlan, operator::LogicalOperator}; +use crate::planner::{ + logical_plan::{self, LogicalPlan}, + operator::LogicalOperator, +}; use super::physical_plan::PhysicalPlan; pub struct PhysicalOptimizer {} impl PhysicalOptimizer { - pub fn find_best(&self, logical_plan: Arc) -> PhysicalPlan { + // output optimized physical plan + pub fn find_best(&self, logical_plan: LogicalPlan) -> PhysicalPlan { + // TODO optimization + let logical_plan = Arc::new(logical_plan); let physical_node = Self::build_physical_node(logical_plan.clone(), logical_plan.children.clone()); Self::build_physical_plan(physical_node, logical_plan.clone()) diff --git a/src/optimizer/rule/mod.rs b/src/optimizer/rule/mod.rs index e69de29..8b13789 100644 --- a/src/optimizer/rule/mod.rs +++ b/src/optimizer/rule/mod.rs @@ -0,0 +1 @@ +