@@ -16,12 +16,27 @@ mod implement;
1616mod rule_list;
1717
1818use common_exception:: Result ;
19+ use lazy_static:: lazy_static;
1920
21+ use super :: rule:: RuleID ;
2022use crate :: sql:: optimizer:: heuristic:: implement:: HeuristicImplementor ;
21- use crate :: sql:: optimizer:: heuristic:: rule_list:: RuleList ;
23+ pub use crate :: sql:: optimizer:: heuristic:: rule_list:: RuleList ;
2224use crate :: sql:: optimizer:: rule:: TransformState ;
2325use crate :: sql:: optimizer:: SExpr ;
2426
27+ lazy_static ! {
28+ pub static ref DEFAULT_REWRITE_RULES : Vec <RuleID > = vec![
29+ RuleID :: EliminateFilter ,
30+ RuleID :: EliminateEvalScalar ,
31+ RuleID :: EliminateProject ,
32+ RuleID :: MergeFilter ,
33+ RuleID :: MergeEvalScalar ,
34+ RuleID :: MergeProject ,
35+ RuleID :: PushDownFilterEvalScalar ,
36+ RuleID :: PushDownFilterProject ,
37+ ] ;
38+ }
39+
2540/// A heuristic query optimizer. It will apply specific transformation rules in order and
2641/// implement the logical plans with default implementation rules.
2742pub struct HeuristicOptimizer {
@@ -30,15 +45,16 @@ pub struct HeuristicOptimizer {
3045}
3146
3247impl HeuristicOptimizer {
33- pub fn create ( ) -> Result < Self > {
34- Ok ( HeuristicOptimizer {
35- rules : RuleList :: create ( vec ! [ ] ) ? ,
48+ pub fn new ( rules : RuleList ) -> Self {
49+ HeuristicOptimizer {
50+ rules,
3651 implementor : HeuristicImplementor :: new ( ) ,
37- } )
52+ }
3853 }
3954
4055 pub fn optimize ( & mut self , expression : SExpr ) -> Result < SExpr > {
41- let result = self . optimize_expression ( & expression) ?;
56+ let optimized = self . optimize_expression ( & expression) ?;
57+ let result = self . implement_expression ( & optimized) ?;
4258 Ok ( result)
4359 }
4460
@@ -53,24 +69,41 @@ impl HeuristicOptimizer {
5369 Ok ( result)
5470 }
5571
56- fn apply_transform_rules ( & self , s_expr : & SExpr , rule_list : & RuleList ) -> Result < SExpr > {
57- let mut result = s_expr. clone ( ) ;
72+ fn implement_expression ( & self , s_expr : & SExpr ) -> Result < SExpr > {
73+ let mut implemented_children = Vec :: with_capacity ( s_expr. arity ( ) ) ;
74+ for expr in s_expr. children ( ) {
75+ implemented_children. push ( self . implement_expression ( expr) ?) ;
76+ }
77+ let implemented_expr = SExpr :: create ( s_expr. plan ( ) . clone ( ) , implemented_children, None ) ;
78+ // Implement expression with Implementor
79+ let mut state = TransformState :: new ( ) ;
80+ self . implementor . implement ( & implemented_expr, & mut state) ?;
81+ let result = if !state. results ( ) . is_empty ( ) {
82+ state. results ( ) [ 0 ] . clone ( )
83+ } else {
84+ implemented_expr
85+ } ;
86+ Ok ( result)
87+ }
5888
89+ // Return `None` if no rules matched
90+ fn apply_transform_rules ( & self , s_expr : & SExpr , rule_list : & RuleList ) -> Result < SExpr > {
91+ let mut s_expr = s_expr. clone ( ) ;
5992 for rule in rule_list. iter ( ) {
6093 let mut state = TransformState :: new ( ) ;
61- rule. apply ( & result, & mut state) ?;
62- if !state. results ( ) . is_empty ( ) {
63- result = state. results ( ) [ 0 ] . clone ( ) ;
64- }
65- }
94+ if s_expr. match_pattern ( rule. pattern ( ) ) && !s_expr. applied_rule ( & rule. id ( ) ) {
95+ rule. apply ( & s_expr, & mut state) ?;
96+ s_expr. apply_rule ( & rule. id ( ) ) ;
97+ if !state. results ( ) . is_empty ( ) {
98+ // Recursive optimize the result
99+ let result = & state. results ( ) [ 0 ] ;
100+ let optimized_result = self . optimize_expression ( result) ?;
66101
67- // Implement expression with Implementor
68- let mut state = TransformState :: new ( ) ;
69- self . implementor . implement ( s_expr, & mut state) ?;
70- if !state. results ( ) . is_empty ( ) {
71- result = state. results ( ) [ 0 ] . clone ( ) ;
102+ return Ok ( optimized_result) ;
103+ }
104+ }
72105 }
73106
74- Ok ( result )
107+ Ok ( s_expr . clone ( ) )
75108 }
76109}
0 commit comments