1717
1818//! Expression simplification optimizer.
1919//! Rewrites expressions using equivalence rules and the egg optimization library
20+ use std:: fmt:: Display ;
21+ use std:: str:: FromStr ;
2022use std:: vec;
21-
23+ use arrow:: datatypes:: DataType ;
24+ use log:: debug;
25+ use crate :: error:: DataFusionError ;
2226use crate :: {
2327 logical_plan:: LogicalPlan , optimizer:: optimizer:: OptimizerRule , scalar:: ScalarValue ,
2428} ;
@@ -43,7 +47,6 @@ fn rules() -> Vec<Rewrite<TokomakExpr, ()>> {
4347 return vec ! [
4448 rw!( "commute-add" ; "(+ ?x ?y)" => "(+ ?y ?x)" ) ,
4549 rw!( "commute-mul" ; "(* ?x ?y)" => "(* ?y ?x)" ) ,
46- rw!( "commute-eq" ; "(= ?x ?y)" => "(= ?y ?x)" ) ,
4750 rw!( "commute-and" ; "(and ?x ?y)" => "(and ?y ?x)" ) ,
4851 rw!( "commute-or" ; "(or ?x ?y)" => "(or ?y ?x)" ) ,
4952 rw!( "commute-eq" ; "(= ?x ?y)" => "(= ?y ?x)" ) ,
@@ -70,6 +73,32 @@ fn rules() -> Vec<Rewrite<TokomakExpr, ()>> {
7073 ] ;
7174}
7275
76+ define_language ! {
77+ enum TokomakDataType {
78+ "date32" = Date32 ,
79+ "date64" = Date64 ,
80+ }
81+ }
82+
83+ impl Display for TokomakDataType {
84+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
85+ f. write_fmt ( format_args ! ( "{:?}" , self ) )
86+ }
87+ }
88+
89+
90+ impl FromStr for TokomakDataType {
91+ type Err = DataFusionError ;
92+
93+ fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
94+ match s {
95+ "date32" => Ok ( TokomakDataType :: Date32 ) ,
96+ "date64" => Ok ( TokomakDataType :: Date64 ) ,
97+ _ => Err ( DataFusionError :: Internal ( "Parsing string as TokomakDataType failed" . to_string ( ) ) )
98+ }
99+ }
100+ }
101+
73102define_language ! {
74103 /// Supported expressions in ExprSimplifier
75104 enum TokomakExpr {
@@ -102,6 +131,9 @@ define_language! {
102131 Date64 ( i64 ) ,
103132 LargeUtf8 ( String ) ,
104133 Column ( Symbol ) ,
134+ // cast id as expr. Type is encoded as symbol
135+ "cast" = Cast ( [ Id ; 2 ] ) ,
136+ Type ( TokomakDataType ) ,
105137 }
106138}
107139
@@ -180,8 +212,30 @@ fn to_tokomak_expr(rec_expr: &mut RecExpr<TokomakExpr>, expr: Expr) -> Option<Id
180212 }
181213 }
182214
215+ Expr :: Cast {
216+ expr,
217+ data_type
218+ } => {
219+ let ty = match data_type {
220+ DataType :: Date32 => TokomakDataType :: Date32 ,
221+ DataType :: Date64 => TokomakDataType :: Date64 ,
222+ _ => {
223+ debug ! ( "Datetype not yet supported for Cast in tokomak optimizer {:?}" , data_type) ;
224+
225+ return None ;
226+ }
227+ } ;
228+ let e = to_tokomak_expr ( rec_expr, * expr) ?;
229+ let t = rec_expr. add ( TokomakExpr :: Type ( ty) ) ;
230+
231+ Some ( rec_expr. add ( TokomakExpr :: Cast ( [ e, t] ) ) )
232+ }
233+
183234 // not yet supported
184- _ => None ,
235+ e => {
236+ debug ! ( "Expression not yet supported in tokomak optimizer {:?}" , e) ;
237+ None
238+ } ,
185239 }
186240}
187241
@@ -390,6 +444,23 @@ fn to_exprs(rec_expr: &RecExpr<TokomakExpr>, id: Id) -> Expr {
390444 TokomakExpr :: Bool ( b) => Expr :: Literal ( ScalarValue :: Boolean ( Some ( b) ) ) ,
391445 TokomakExpr :: Date32 ( b) => Expr :: Literal ( ScalarValue :: Date32 ( Some ( b) ) ) ,
392446 TokomakExpr :: Date64 ( b) => Expr :: Literal ( ScalarValue :: Date64 ( Some ( b) ) ) ,
447+ TokomakExpr :: Cast ( [ e, ty] ) => {
448+ let l = to_exprs ( & rec_expr, e) ;
449+ let index: usize = ty. into ( ) ;
450+ let dt = match & refs[ index] {
451+ TokomakExpr :: Type ( s) => s,
452+ _ => panic ! ( "Second argument of cast should be type" )
453+ } ;
454+ let dt = match dt {
455+ TokomakDataType :: Date32 => DataType :: Date32 ,
456+ TokomakDataType :: Date64 => DataType :: Date64 ,
457+ } ;
458+
459+ Expr :: Cast { expr : Box :: new ( l) , data_type : dt}
460+ }
461+ TokomakExpr :: Type ( _) => {
462+ panic ! ( "Type should only be part of expression" )
463+ }
393464 }
394465}
395466
0 commit comments