1
- use std:: collections:: { HashMap , HashSet } ;
2
- use std:: sync:: Arc ;
1
+ use std:: collections:: HashSet ;
3
2
4
- use itertools:: Itertools ;
3
+ use optd_core:: nodes:: PlanNodeOrGroup ;
4
+ use optd_core:: optimizer:: Optimizer ;
5
5
use optd_core:: rules:: { Rule , RuleMatcher } ;
6
- use optd_core:: { nodes:: PlanNode , optimizer:: Optimizer } ;
7
6
8
7
use crate :: plan_nodes:: {
9
- DfNodeType , DfReprPlanNode , DfReprPlanNode , Expr , ListPred , LogicalAgg , LogicalSort ,
10
- SortOrderPred , SortOrderType ,
8
+ ArcDfPlanNode , DfNodeType , DfReprPlanNode , DfReprPredNode , ListPred , LogicalAgg , LogicalSort ,
9
+ SortOrderPred ,
11
10
} ;
12
11
13
12
use super :: macros:: define_rule;
14
13
15
14
define_rule ! (
16
15
EliminateDuplicatedSortExprRule ,
17
16
apply_eliminate_duplicated_sort_expr,
18
- ( Sort , child, [ exprs ] )
17
+ ( Sort , child)
19
18
) ;
20
19
21
20
/// Removes duplicate sort expressions
@@ -29,54 +28,37 @@ define_rule!(
29
28
/// order by id desc, name
30
29
fn apply_eliminate_duplicated_sort_expr (
31
30
_optimizer : & impl Optimizer < DfNodeType > ,
32
- EliminateDuplicatedSortExprRulePicks { child , exprs } : EliminateDuplicatedSortExprRulePicks ,
31
+ binding : ArcDfPlanNode ,
33
32
) -> Vec < PlanNodeOrGroup < DfNodeType > > {
34
- let sort_keys: Vec < Expr > = exprs
35
- . children
36
- . iter ( )
37
- . map ( |x| Expr :: from_rel_node ( x. clone ( ) ) . unwrap ( ) )
38
- . collect_vec ( ) ;
33
+ let sort = LogicalSort :: from_plan_node ( binding) . unwrap ( ) ;
34
+ let exprs = sort. exprs ( ) ;
35
+ let sort_keys = exprs. to_vec ( ) . into_iter ( ) ;
39
36
40
- let normalized_sort_keys: Vec < Arc < PlanNode < DfNodeType > > > = exprs
41
- . children
42
- . iter ( )
43
- . map ( |x| match x. typ {
44
- DfNodeType :: SortOrder ( _) => SortOrderPred :: new (
45
- SortOrderType :: Asc ,
46
- SortOrderPred :: from_rel_node ( x. clone ( ) ) . unwrap ( ) . child ( ) ,
47
- )
48
- . into_rel_node ( ) ,
49
- _ => x. clone ( ) ,
50
- } )
51
- . collect_vec ( ) ;
37
+ let mut dedup_expr = Vec :: new ( ) ;
38
+ let mut dedup_set = HashSet :: new ( ) ;
39
+ let mut deduped = false ;
52
40
53
- let mut dedup_expr: Vec < Expr > = Vec :: new ( ) ;
54
- let mut dedup_set: HashSet < Arc < PlanNode < DfNodeType > > > = HashSet :: new ( ) ;
55
-
56
- sort_keys
57
- . iter ( )
58
- . zip ( normalized_sort_keys. iter ( ) )
59
- . for_each ( |( expr, normalized_expr) | {
60
- if !dedup_set. contains ( normalized_expr) {
61
- dedup_expr. push ( expr. clone ( ) ) ;
62
- dedup_set. insert ( normalized_expr. to_owned ( ) ) ;
63
- }
64
- } ) ;
41
+ for sort_key in sort_keys {
42
+ let sort_expr = SortOrderPred :: from_pred_node ( sort_key. clone ( ) ) . unwrap ( ) ;
43
+ if !dedup_set. contains ( & sort_expr. child ( ) ) {
44
+ dedup_expr. push ( sort_key. clone ( ) ) ;
45
+ dedup_set. insert ( sort_expr. child ( ) . clone ( ) ) ;
46
+ } else {
47
+ deduped = true ;
48
+ }
49
+ }
65
50
66
- if dedup_expr. len ( ) != sort_keys. len ( ) {
67
- let node = LogicalSort :: new (
68
- DfReprPlanNode :: from_group ( child. into ( ) ) ,
69
- ListPred :: new ( dedup_expr) ,
70
- ) ;
71
- return vec ! [ node. into_rel_node( ) . as_ref( ) . clone( ) ] ;
51
+ if deduped {
52
+ let node = LogicalSort :: new_unchecked ( sort. child ( ) , ListPred :: new ( dedup_expr) ) ;
53
+ return vec ! [ node. into_plan_node( ) . into( ) ] ;
72
54
}
73
55
vec ! [ ]
74
56
}
75
57
76
58
define_rule ! (
77
59
EliminateDuplicatedAggExprRule ,
78
60
apply_eliminate_duplicated_agg_expr,
79
- ( Agg , child, exprs , [ groups ] )
61
+ ( Agg , child)
80
62
) ;
81
63
82
64
/// Removes duplicate group by expressions
@@ -88,30 +70,31 @@ define_rule!(
88
70
/// select *
89
71
/// from t1
90
72
/// group by id, name
73
+ ///
74
+ /// TODO: if projection refers to the column, we need to update the projection
91
75
fn apply_eliminate_duplicated_agg_expr (
92
76
_optimizer : & impl Optimizer < DfNodeType > ,
93
- EliminateDuplicatedAggExprRulePicks {
94
- child,
95
- exprs,
96
- groups,
97
- } : EliminateDuplicatedAggExprRulePicks ,
77
+ binding : ArcDfPlanNode ,
98
78
) -> Vec < PlanNodeOrGroup < DfNodeType > > {
99
- let mut dedup_expr: Vec < Expr > = Vec :: new ( ) ;
100
- let mut dedup_set: HashSet < Arc < PlanNode < DfNodeType > > > = HashSet :: new ( ) ;
101
- groups. children . iter ( ) . for_each ( |expr| {
102
- if !dedup_set. contains ( expr) {
103
- dedup_expr. push ( Expr :: from_rel_node ( expr. clone ( ) ) . unwrap ( ) ) ;
104
- dedup_set. insert ( expr. clone ( ) ) ;
79
+ let agg = LogicalAgg :: from_plan_node ( binding) . unwrap ( ) ;
80
+ let groups = agg. groups ( ) . to_vec ( ) ;
81
+
82
+ let mut dedup_expr = Vec :: new ( ) ;
83
+ let mut dedup_set = HashSet :: new ( ) ;
84
+ let mut deduped = false ;
85
+
86
+ for group in groups {
87
+ if !dedup_set. contains ( & group) {
88
+ dedup_expr. push ( group. clone ( ) ) ;
89
+ dedup_set. insert ( group. clone ( ) ) ;
90
+ } else {
91
+ deduped = true ;
105
92
}
106
- } ) ;
93
+ }
107
94
108
- if dedup_expr. len ( ) != groups. children . len ( ) {
109
- let node = LogicalAgg :: new (
110
- DfReprPlanNode :: from_group ( child. into ( ) ) ,
111
- ListPred :: from_group ( exprs. into ( ) ) ,
112
- ListPred :: new ( dedup_expr) ,
113
- ) ;
114
- return vec ! [ node. into_rel_node( ) . as_ref( ) . clone( ) ] ;
95
+ if deduped {
96
+ let node = LogicalAgg :: new_unchecked ( agg. child ( ) , agg. exprs ( ) , ListPred :: new ( dedup_expr) ) ;
97
+ return vec ! [ node. into_plan_node( ) . into( ) ] ;
115
98
}
116
99
vec ! [ ]
117
100
}
0 commit comments