@@ -16,12 +16,27 @@ mod implement;
16
16
mod rule_list;
17
17
18
18
use common_exception:: Result ;
19
+ use lazy_static:: lazy_static;
19
20
21
+ use super :: rule:: RuleID ;
20
22
use 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 ;
22
24
use crate :: sql:: optimizer:: rule:: TransformState ;
23
25
use crate :: sql:: optimizer:: SExpr ;
24
26
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
+
25
40
/// A heuristic query optimizer. It will apply specific transformation rules in order and
26
41
/// implement the logical plans with default implementation rules.
27
42
pub struct HeuristicOptimizer {
@@ -30,15 +45,16 @@ pub struct HeuristicOptimizer {
30
45
}
31
46
32
47
impl 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,
36
51
implementor : HeuristicImplementor :: new ( ) ,
37
- } )
52
+ }
38
53
}
39
54
40
55
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) ?;
42
58
Ok ( result)
43
59
}
44
60
@@ -53,24 +69,41 @@ impl HeuristicOptimizer {
53
69
Ok ( result)
54
70
}
55
71
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
+ }
58
88
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 ( ) ;
59
92
for rule in rule_list. iter ( ) {
60
93
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) ?;
66
101
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
+ }
72
105
}
73
106
74
- Ok ( result )
107
+ Ok ( s_expr . clone ( ) )
75
108
}
76
109
}
0 commit comments