11use std:: collections:: HashMap ;
22use std:: sync:: Arc ;
3+ use std:: vec;
34
45use itertools:: Itertools ;
56use optd_core:: optimizer:: Optimizer ;
@@ -8,8 +9,9 @@ use optd_core::rules::{Rule, RuleMatcher};
89
910use super :: macros:: { define_impl_rule, define_rule} ;
1011use 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 ,
1315} ;
1416use crate :: properties:: schema:: SchemaPropertyBuilder ;
1517
@@ -78,6 +80,44 @@ fn apply_join_commute(
7880 vec ! [ node. as_ref( ) . clone( ) ]
7981}
8082
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+
81121// (A join B) join C -> A join (B join C)
82122define_rule ! (
83123 JoinAssocRule ,
0 commit comments