1
1
use std:: collections:: HashMap ;
2
2
use std:: sync:: Arc ;
3
+ use std:: vec;
3
4
4
5
use itertools:: Itertools ;
5
6
use optd_core:: optimizer:: Optimizer ;
@@ -8,8 +9,9 @@ use optd_core::rules::{Rule, RuleMatcher};
8
9
9
10
use super :: macros:: { define_impl_rule, define_rule} ;
10
11
use crate :: plan_nodes:: {
11
- BinOpExpr , BinOpType , ColumnRefExpr , Expr , ExprList , JoinType , LogicalJoin , LogicalProjection ,
12
- OptRelNode , OptRelNodeTyp , PhysicalHashJoin , PlanNode ,
12
+ BinOpExpr , BinOpType , ColumnRefExpr , ConstantExpr , ConstantType , Expr , ExprList , JoinType ,
13
+ LogicalEmptyRelation , LogicalJoin , LogicalProjection , OptRelNode , OptRelNodeTyp ,
14
+ PhysicalHashJoin , PlanNode ,
13
15
} ;
14
16
use crate :: properties:: schema:: SchemaPropertyBuilder ;
15
17
@@ -78,6 +80,44 @@ fn apply_join_commute(
78
80
vec ! [ node. as_ref( ) . clone( ) ]
79
81
}
80
82
83
+ define_rule ! (
84
+ EliminateJoinRule ,
85
+ apply_eliminate_join,
86
+ ( Join ( JoinType :: Inner ) , left, right, [ cond] )
87
+ ) ;
88
+
89
+ /// Eliminate logical join with constant predicates
90
+ /// True predicates becomes CrossJoin (not yet implemented)
91
+ /// False predicates become EmptyRelation (not yet implemented)
92
+ #[ allow( unused_variables) ]
93
+ fn apply_eliminate_join (
94
+ optimizer : & impl Optimizer < OptRelNodeTyp > ,
95
+ EliminateJoinRulePicks { left, right, cond } : EliminateJoinRulePicks ,
96
+ ) -> Vec < RelNode < OptRelNodeTyp > > {
97
+ if let OptRelNodeTyp :: Constant ( const_type) = cond. typ {
98
+ if const_type == ConstantType :: Bool {
99
+ if let Some ( data) = cond. data {
100
+ if data. as_bool ( ) {
101
+ // change it to cross join if filter is always true
102
+ let node = LogicalJoin :: new (
103
+ PlanNode :: from_group ( left. into ( ) ) ,
104
+ PlanNode :: from_group ( right. into ( ) ) ,
105
+ ConstantExpr :: bool ( true ) . into_expr ( ) ,
106
+ JoinType :: Cross ,
107
+ ) ;
108
+ return vec ! [ node. into_rel_node( ) . as_ref( ) . clone( ) ] ;
109
+ } else {
110
+ // No need to handle schema here, as all exprs in the same group
111
+ // will have same logical properties
112
+ let node = LogicalEmptyRelation :: new ( false ) ;
113
+ return vec ! [ node. into_rel_node( ) . as_ref( ) . clone( ) ] ;
114
+ }
115
+ }
116
+ }
117
+ }
118
+ vec ! [ ]
119
+ }
120
+
81
121
// (A join B) join C -> A join (B join C)
82
122
define_rule ! (
83
123
JoinAssocRule ,
0 commit comments