@@ -34,7 +34,7 @@ use datafusion_common::{
3434use datafusion_common:: { internal_err, DFSchema , DataFusionError , Result , ScalarValue } ;
3535use datafusion_expr:: simplify:: ExprSimplifyResult ;
3636use datafusion_expr:: {
37- and, lit, or, BinaryExpr , Case , ColumnarValue , Expr , Like , Operator , Volatility ,
37+ and, lit, or, BinaryExpr , Case , ColumnarValue , Expr , Operator , Volatility ,
3838 WindowFunctionDefinition ,
3939} ;
4040use datafusion_expr:: { expr:: ScalarFunction , interval_arithmetic:: NullableInterval } ;
@@ -1470,19 +1470,27 @@ impl<'a, S: SimplifyInfo> TreeNodeRewriter for Simplifier<'a, S> {
14701470 } ) => Transformed :: yes ( simplify_regex_expr ( left, op, right) ?) ,
14711471
14721472 // Rules for Like
1473- Expr :: Like ( Like {
1474- expr,
1475- pattern,
1476- negated,
1477- escape_char : _,
1478- case_insensitive : _,
1479- } ) if !is_null ( & expr)
1480- && matches ! (
1481- pattern. as_ref( ) ,
1482- Expr :: Literal ( ScalarValue :: Utf8 ( Some ( pattern_str) ) ) if pattern_str == "%"
1483- ) =>
1484- {
1485- Transformed :: yes ( lit ( !negated) )
1473+ Expr :: Like ( ref like_expr) => {
1474+ if let Expr :: Literal ( ScalarValue :: Utf8 ( Some ( pattern_str) ) ) = like_expr. pattern . as_ref ( ) {
1475+ if !is_null ( & like_expr. expr ) && pattern_str == "%" {
1476+ Transformed :: yes ( lit ( !like_expr. negated ) )
1477+ } else if !pattern_str. contains ( [ '%' , '_' ] . as_ref ( ) ) {
1478+ // If the pattern does not contain any wildcards, we can simplify the like expression to an equality expression
1479+ Transformed :: yes (
1480+ Expr :: BinaryExpr (
1481+ BinaryExpr {
1482+ left : like_expr. expr . clone ( ) ,
1483+ op : if like_expr. negated { NotEq } else { Eq } ,
1484+ right : like_expr. pattern . clone ( ) ,
1485+ }
1486+ )
1487+ )
1488+ } else {
1489+ Transformed :: no ( expr)
1490+ }
1491+ } else {
1492+ Transformed :: no ( expr)
1493+ }
14861494 }
14871495
14881496 // a is not null/unknown --> true (if a is not nullable)
@@ -3632,6 +3640,16 @@ mod tests {
36323640
36333641 let expr = not_ilike ( null, "%" ) ;
36343642 assert_eq ! ( simplify( expr) , lit_bool_null( ) ) ;
3643+
3644+ // test cases that get converted to equality
3645+ let expr = like ( col ( "c1" ) , "a" ) ;
3646+ assert_eq ! ( simplify( expr) , col( "c1" ) . eq( lit( "a" ) ) ) ;
3647+ let expr = not_like ( col ( "c1" ) , "a" ) ;
3648+ assert_eq ! ( simplify( expr) , col( "c1" ) . not_eq( lit( "a" ) ) ) ;
3649+ let expr = like ( col ( "c1" ) , "a_" ) ;
3650+ assert_eq ! ( simplify( expr) , col( "c1" ) . like( lit( "a_" ) ) ) ;
3651+ let expr = not_like ( col ( "c1" ) , "a_" ) ;
3652+ assert_eq ! ( simplify( expr) , col( "c1" ) . not_like( lit( "a_" ) ) ) ;
36353653 }
36363654
36373655 #[ test]
0 commit comments