1
- use std :: collections :: HashMap ;
2
-
1
+ use optd_core :: nodes :: PlanNodeOrGroup ;
2
+ use optd_core :: optimizer :: Optimizer ;
3
3
use optd_core:: rules:: { Rule , RuleMatcher } ;
4
- use optd_core:: { nodes:: PlanNode , optimizer:: Optimizer } ;
5
4
6
- use crate :: plan_nodes:: { DfNodeType , DfReprPlanNode , DfReprPlanNode , ListPred , LogicalProjection } ;
5
+ use crate :: plan_nodes:: {
6
+ ArcDfPlanNode , ColumnRefPred , DfNodeType , DfReprPlanNode , DfReprPredNode , LogicalProjection ,
7
+ } ;
7
8
use crate :: rules:: macros:: define_rule;
9
+ use crate :: OptimizerExt ;
8
10
9
11
use super :: project_transpose_common:: ProjectionMapping ;
10
12
@@ -13,20 +15,18 @@ use super::project_transpose_common::ProjectionMapping;
13
15
define_rule ! (
14
16
ProjectMergeRule ,
15
17
apply_projection_merge,
16
- ( Projection , ( Projection , child, [ exprs2 ] ) , [ exprs1 ] )
18
+ ( Projection , ( Projection , child) )
17
19
) ;
18
20
19
21
fn apply_projection_merge (
20
22
_optimizer : & impl Optimizer < DfNodeType > ,
21
- ProjectMergeRulePicks {
22
- child,
23
- exprs1,
24
- exprs2,
25
- } : ProjectMergeRulePicks ,
23
+ binding : ArcDfPlanNode ,
26
24
) -> Vec < PlanNodeOrGroup < DfNodeType > > {
27
- let child = DfReprPlanNode :: from_group ( child. into ( ) ) ;
28
- let exprs1 = ListPred :: from_rel_node ( exprs1. into ( ) ) . unwrap ( ) ;
29
- let exprs2 = ListPred :: from_rel_node ( exprs2. into ( ) ) . unwrap ( ) ;
25
+ let proj1 = LogicalProjection :: from_plan_node ( binding) . unwrap ( ) ;
26
+ let proj2 = LogicalProjection :: from_plan_node ( proj1. child ( ) . unwrap_plan_node ( ) ) . unwrap ( ) ;
27
+ let child = proj2. child ( ) ;
28
+ let exprs1 = proj1. exprs ( ) ;
29
+ let exprs2 = proj2. exprs ( ) ;
30
30
31
31
let Some ( mapping) = ProjectionMapping :: build ( & exprs1) else {
32
32
return vec ! [ ] ;
@@ -36,33 +36,32 @@ fn apply_projection_merge(
36
36
return vec ! [ ] ;
37
37
} ;
38
38
39
- let node: LogicalProjection = LogicalProjection :: new ( child, res_exprs) ;
39
+ let node = LogicalProjection :: new_unchecked ( child, res_exprs) ;
40
40
41
- vec ! [ node. into_rel_node ( ) . as_ref ( ) . clone ( ) ]
41
+ vec ! [ node. into_plan_node ( ) . into ( ) ]
42
42
}
43
43
44
44
// Proj child [identical columns] -> eliminate
45
45
define_rule ! (
46
46
EliminateProjectRule ,
47
47
apply_eliminate_project,
48
- ( Projection , child, [ expr ] )
48
+ ( Projection , child)
49
49
) ;
50
50
51
51
fn apply_eliminate_project (
52
52
optimizer : & impl Optimizer < DfNodeType > ,
53
- EliminateProjectRulePicks { child , expr } : EliminateProjectRulePicks ,
54
- ) -> Vec < RelNode < DfNodeType > > {
55
- let exprs = ExprList :: from_rel_node ( expr . into ( ) ) . unwrap ( ) ;
56
- let child_columns = optimizer
57
- . get_property :: < SchemaPropertyBuilder > ( child . clone ( ) . into ( ) , 0 )
58
- . len ( ) ;
59
- if child_columns != exprs. len ( ) {
53
+ binding : ArcDfPlanNode ,
54
+ ) -> Vec < PlanNodeOrGroup < DfNodeType > > {
55
+ let proj = LogicalProjection :: from_plan_node ( binding ) . unwrap ( ) ;
56
+ let child = proj . child ( ) ;
57
+ let exprs = proj . exprs ( ) ;
58
+ let child_schema = optimizer . get_schema_of ( child . clone ( ) ) ;
59
+ if child_schema . len ( ) != exprs. len ( ) {
60
60
return Vec :: new ( ) ;
61
61
}
62
62
for i in 0 ..exprs. len ( ) {
63
63
let child_expr = exprs. child ( i) ;
64
- if child_expr. typ ( ) == DfNodeType :: ColumnRef {
65
- let child_expr = ColumnRefExpr :: from_rel_node ( child_expr. into_rel_node ( ) ) . unwrap ( ) ;
64
+ if let Some ( child_expr) = ColumnRefPred :: from_pred_node ( child_expr) {
66
65
if child_expr. index ( ) != i {
67
66
return Vec :: new ( ) ;
68
67
}
@@ -77,13 +76,10 @@ fn apply_eliminate_project(
77
76
mod tests {
78
77
use std:: sync:: Arc ;
79
78
80
- use optd_core :: optimizer :: Optimizer ;
79
+ use super :: * ;
81
80
82
81
use crate :: {
83
- plan_nodes:: {
84
- ColumnRefPred , DfNodeType , DfReprPlanNode , ListPred , LogicalProjection , LogicalScan ,
85
- } ,
86
- rules:: ProjectMergeRule ,
82
+ plan_nodes:: { ListPred , LogicalScan } ,
87
83
testing:: new_test_optimizer,
88
84
} ;
89
85
@@ -95,30 +91,30 @@ mod tests {
95
91
let scan = LogicalScan :: new ( "customer" . into ( ) ) ;
96
92
97
93
let top_proj_exprs = ListPred :: new ( vec ! [
98
- ColumnRefPred :: new( 2 ) . into_expr ( ) ,
99
- ColumnRefPred :: new( 0 ) . into_expr ( ) ,
94
+ ColumnRefPred :: new( 2 ) . into_pred_node ( ) ,
95
+ ColumnRefPred :: new( 0 ) . into_pred_node ( ) ,
100
96
] ) ;
101
97
102
98
let bot_proj_exprs = ListPred :: new ( vec ! [
103
- ColumnRefPred :: new( 2 ) . into_expr ( ) ,
104
- ColumnRefPred :: new( 0 ) . into_expr ( ) ,
105
- ColumnRefPred :: new( 4 ) . into_expr ( ) ,
99
+ ColumnRefPred :: new( 2 ) . into_pred_node ( ) ,
100
+ ColumnRefPred :: new( 0 ) . into_pred_node ( ) ,
101
+ ColumnRefPred :: new( 4 ) . into_pred_node ( ) ,
106
102
] ) ;
107
103
108
104
let bot_proj = LogicalProjection :: new ( scan. into_plan_node ( ) , bot_proj_exprs) ;
109
105
let top_proj = LogicalProjection :: new ( bot_proj. into_plan_node ( ) , top_proj_exprs) ;
110
106
111
- let plan = test_optimizer. optimize ( top_proj. into_rel_node ( ) ) . unwrap ( ) ;
107
+ let plan = test_optimizer. optimize ( top_proj. into_plan_node ( ) ) . unwrap ( ) ;
112
108
113
109
let res_proj_exprs = ListPred :: new ( vec ! [
114
- ColumnRefPred :: new( 4 ) . into_expr ( ) ,
115
- ColumnRefPred :: new( 2 ) . into_expr ( ) ,
110
+ ColumnRefPred :: new( 4 ) . into_pred_node ( ) ,
111
+ ColumnRefPred :: new( 2 ) . into_pred_node ( ) ,
116
112
] )
117
- . into_rel_node ( ) ;
113
+ . into_pred_node ( ) ;
118
114
119
115
assert_eq ! ( plan. typ, DfNodeType :: Projection ) ;
120
- assert_eq ! ( plan. child ( 1 ) , res_proj_exprs) ;
121
- assert ! ( matches!( plan. child ( 0 ) . typ, DfNodeType :: Scan ) ) ;
116
+ assert_eq ! ( plan. predicate ( 0 ) , res_proj_exprs) ;
117
+ assert ! ( matches!( plan. child_rel ( 0 ) . typ, DfNodeType :: Scan ) ) ;
122
118
}
123
119
124
120
#[ test]
@@ -129,42 +125,42 @@ mod tests {
129
125
let scan = LogicalScan :: new ( "customer" . into ( ) ) ;
130
126
131
127
let proj_exprs_1 = ListPred :: new ( vec ! [
132
- ColumnRefPred :: new( 2 ) . into_expr ( ) ,
133
- ColumnRefPred :: new( 0 ) . into_expr ( ) ,
134
- ColumnRefPred :: new( 4 ) . into_expr ( ) ,
135
- ColumnRefPred :: new( 3 ) . into_expr ( ) ,
128
+ ColumnRefPred :: new( 2 ) . into_pred_node ( ) ,
129
+ ColumnRefPred :: new( 0 ) . into_pred_node ( ) ,
130
+ ColumnRefPred :: new( 4 ) . into_pred_node ( ) ,
131
+ ColumnRefPred :: new( 3 ) . into_pred_node ( ) ,
136
132
] ) ;
137
133
138
134
let proj_exprs_2 = ListPred :: new ( vec ! [
139
- ColumnRefPred :: new( 1 ) . into_expr ( ) ,
140
- ColumnRefPred :: new( 0 ) . into_expr ( ) ,
141
- ColumnRefPred :: new( 3 ) . into_expr ( ) ,
135
+ ColumnRefPred :: new( 1 ) . into_pred_node ( ) ,
136
+ ColumnRefPred :: new( 0 ) . into_pred_node ( ) ,
137
+ ColumnRefPred :: new( 3 ) . into_pred_node ( ) ,
142
138
] ) ;
143
139
144
140
let proj_exprs_3 = ListPred :: new ( vec ! [
145
- ColumnRefPred :: new( 1 ) . into_expr ( ) ,
146
- ColumnRefPred :: new( 0 ) . into_expr ( ) ,
147
- ColumnRefPred :: new( 2 ) . into_expr ( ) ,
141
+ ColumnRefPred :: new( 1 ) . into_pred_node ( ) ,
142
+ ColumnRefPred :: new( 0 ) . into_pred_node ( ) ,
143
+ ColumnRefPred :: new( 2 ) . into_pred_node ( ) ,
148
144
] ) ;
149
145
150
146
let proj_1 = LogicalProjection :: new ( scan. into_plan_node ( ) , proj_exprs_1) ;
151
147
let proj_2 = LogicalProjection :: new ( proj_1. into_plan_node ( ) , proj_exprs_2) ;
152
148
let proj_3 = LogicalProjection :: new ( proj_2. into_plan_node ( ) , proj_exprs_3) ;
153
149
154
150
// needs to be called twice
155
- let plan = test_optimizer. optimize ( proj_3. into_rel_node ( ) ) . unwrap ( ) ;
151
+ let plan = test_optimizer. optimize ( proj_3. into_plan_node ( ) ) . unwrap ( ) ;
156
152
let plan = test_optimizer. optimize ( plan) . unwrap ( ) ;
157
153
158
154
let res_proj_exprs = ListPred :: new ( vec ! [
159
- ColumnRefPred :: new( 2 ) . into_expr ( ) ,
160
- ColumnRefPred :: new( 0 ) . into_expr ( ) ,
161
- ColumnRefPred :: new( 3 ) . into_expr ( ) ,
155
+ ColumnRefPred :: new( 2 ) . into_pred_node ( ) ,
156
+ ColumnRefPred :: new( 0 ) . into_pred_node ( ) ,
157
+ ColumnRefPred :: new( 3 ) . into_pred_node ( ) ,
162
158
] )
163
- . into_rel_node ( ) ;
159
+ . into_pred_node ( ) ;
164
160
165
161
assert_eq ! ( plan. typ, DfNodeType :: Projection ) ;
166
- assert_eq ! ( plan. child ( 1 ) , res_proj_exprs) ;
167
- assert ! ( matches!( plan. child ( 0 ) . typ, DfNodeType :: Scan ) ) ;
162
+ assert_eq ! ( plan. predicate ( 0 ) , res_proj_exprs) ;
163
+ assert ! ( matches!( plan. child_rel ( 0 ) . typ, DfNodeType :: Scan ) ) ;
168
164
}
169
165
170
166
#[ test]
@@ -175,28 +171,28 @@ mod tests {
175
171
let scan = LogicalScan :: new ( "customer" . into ( ) ) ;
176
172
177
173
let proj_exprs_1 = ListPred :: new ( vec ! [
178
- ColumnRefPred :: new( 2 ) . into_expr ( ) ,
179
- ColumnRefPred :: new( 0 ) . into_expr ( ) ,
180
- ColumnRefPred :: new( 4 ) . into_expr ( ) ,
181
- ColumnRefPred :: new( 3 ) . into_expr ( ) ,
174
+ ColumnRefPred :: new( 2 ) . into_pred_node ( ) ,
175
+ ColumnRefPred :: new( 0 ) . into_pred_node ( ) ,
176
+ ColumnRefPred :: new( 4 ) . into_pred_node ( ) ,
177
+ ColumnRefPred :: new( 3 ) . into_pred_node ( ) ,
182
178
] ) ;
183
179
184
180
let proj_exprs_2 = ListPred :: new ( vec ! [
185
- ColumnRefPred :: new( 1 ) . into_expr ( ) ,
186
- ColumnRefPred :: new( 0 ) . into_expr ( ) ,
187
- ColumnRefPred :: new( 3 ) . into_expr ( ) ,
181
+ ColumnRefPred :: new( 1 ) . into_pred_node ( ) ,
182
+ ColumnRefPred :: new( 0 ) . into_pred_node ( ) ,
183
+ ColumnRefPred :: new( 3 ) . into_pred_node ( ) ,
188
184
] ) ;
189
185
190
186
let proj_exprs_3 = ListPred :: new ( vec ! [
191
- ColumnRefPred :: new( 1 ) . into_expr ( ) ,
192
- ColumnRefPred :: new( 0 ) . into_expr ( ) ,
193
- ColumnRefPred :: new( 2 ) . into_expr ( ) ,
187
+ ColumnRefPred :: new( 1 ) . into_pred_node ( ) ,
188
+ ColumnRefPred :: new( 0 ) . into_pred_node ( ) ,
189
+ ColumnRefPred :: new( 2 ) . into_pred_node ( ) ,
194
190
] ) ;
195
191
196
192
let proj_exprs_4 = ListPred :: new ( vec ! [
197
- ColumnRefPred :: new( 0 ) . into_expr ( ) ,
198
- ColumnRefPred :: new( 1 ) . into_expr ( ) ,
199
- ColumnRefPred :: new( 2 ) . into_expr ( ) ,
193
+ ColumnRefPred :: new( 0 ) . into_pred_node ( ) ,
194
+ ColumnRefPred :: new( 1 ) . into_pred_node ( ) ,
195
+ ColumnRefPred :: new( 2 ) . into_pred_node ( ) ,
200
196
] ) ;
201
197
202
198
let proj_1 = LogicalProjection :: new ( scan. into_plan_node ( ) , proj_exprs_1) ;
@@ -205,19 +201,19 @@ mod tests {
205
201
let proj_4 = LogicalProjection :: new ( proj_3. into_plan_node ( ) , proj_exprs_4) ;
206
202
207
203
// needs to be called three times
208
- let plan = test_optimizer. optimize ( proj_4. into_rel_node ( ) ) . unwrap ( ) ;
204
+ let plan = test_optimizer. optimize ( proj_4. into_plan_node ( ) ) . unwrap ( ) ;
209
205
let plan = test_optimizer. optimize ( plan) . unwrap ( ) ;
210
206
let plan = test_optimizer. optimize ( plan) . unwrap ( ) ;
211
207
212
208
let res_proj_exprs = ListPred :: new ( vec ! [
213
- ColumnRefPred :: new( 2 ) . into_expr ( ) ,
214
- ColumnRefPred :: new( 0 ) . into_expr ( ) ,
215
- ColumnRefPred :: new( 3 ) . into_expr ( ) ,
209
+ ColumnRefPred :: new( 2 ) . into_pred_node ( ) ,
210
+ ColumnRefPred :: new( 0 ) . into_pred_node ( ) ,
211
+ ColumnRefPred :: new( 3 ) . into_pred_node ( ) ,
216
212
] )
217
- . into_rel_node ( ) ;
213
+ . into_pred_node ( ) ;
218
214
219
215
assert_eq ! ( plan. typ, DfNodeType :: Projection ) ;
220
- assert_eq ! ( plan. child ( 1 ) , res_proj_exprs) ;
221
- assert ! ( matches!( plan. child ( 0 ) . typ, DfNodeType :: Scan ) ) ;
216
+ assert_eq ! ( plan. predicate ( 0 ) , res_proj_exprs) ;
217
+ assert ! ( matches!( plan. child_rel ( 0 ) . typ, DfNodeType :: Scan ) ) ;
222
218
}
223
219
}
0 commit comments