Skip to content

Commit d174f5f

Browse files
committed
only handle cases that simplify to equalityu comparisons
1 parent 85f92ef commit d174f5f

1 file changed

Lines changed: 32 additions & 14 deletions

File tree

datafusion/optimizer/src/simplify_expressions/expr_simplifier.rs

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use datafusion_common::{
3434
use datafusion_common::{internal_err, DFSchema, DataFusionError, Result, ScalarValue};
3535
use datafusion_expr::simplify::ExprSimplifyResult;
3636
use 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
};
4040
use 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

Comments
 (0)