in datafusion/optimizer/src/simplify_expressions/expr_simplifier.rs [2431:2581]
fn test_simplify_regex() {
// malformed regex
assert_contains!(
try_simplify(regex_match(col("c1"), lit("foo{")))
.unwrap_err()
.to_string(),
"regex parse error"
);
// unsupported cases
assert_no_change(regex_match(col("c1"), lit("foo.*")));
assert_no_change(regex_match(col("c1"), lit("(foo)")));
assert_no_change(regex_match(col("c1"), lit("^foo")));
assert_no_change(regex_match(col("c1"), lit("foo$")));
assert_no_change(regex_match(col("c1"), lit("%")));
assert_no_change(regex_match(col("c1"), lit("_")));
assert_no_change(regex_match(col("c1"), lit("f%o")));
assert_no_change(regex_match(col("c1"), lit("f_o")));
// empty cases
assert_change(regex_match(col("c1"), lit("")), lit(true));
assert_change(regex_not_match(col("c1"), lit("")), lit(false));
assert_change(regex_imatch(col("c1"), lit("")), lit(true));
assert_change(regex_not_imatch(col("c1"), lit("")), lit(false));
// single character
assert_change(regex_match(col("c1"), lit("x")), like(col("c1"), "%x%"));
// single word
assert_change(regex_match(col("c1"), lit("foo")), like(col("c1"), "%foo%"));
// regular expressions that match an exact literal
assert_change(regex_match(col("c1"), lit("^$")), col("c1").eq(lit("")));
assert_change(
regex_not_match(col("c1"), lit("^$")),
col("c1").not_eq(lit("")),
);
assert_change(
regex_match(col("c1"), lit("^foo$")),
col("c1").eq(lit("foo")),
);
assert_change(
regex_not_match(col("c1"), lit("^foo$")),
col("c1").not_eq(lit("foo")),
);
// regular expressions that match exact captured literals
assert_change(
regex_match(col("c1"), lit("^(foo|bar)$")),
col("c1").eq(lit("foo")).or(col("c1").eq(lit("bar"))),
);
assert_change(
regex_not_match(col("c1"), lit("^(foo|bar)$")),
col("c1")
.not_eq(lit("foo"))
.and(col("c1").not_eq(lit("bar"))),
);
assert_change(
regex_match(col("c1"), lit("^(foo)$")),
col("c1").eq(lit("foo")),
);
assert_change(
regex_match(col("c1"), lit("^(foo|bar|baz)$")),
((col("c1").eq(lit("foo"))).or(col("c1").eq(lit("bar"))))
.or(col("c1").eq(lit("baz"))),
);
assert_change(
regex_match(col("c1"), lit("^(foo|bar|baz|qux)$")),
col("c1")
.in_list(vec![lit("foo"), lit("bar"), lit("baz"), lit("qux")], false),
);
assert_change(
regex_match(col("c1"), lit("^(fo_o)$")),
col("c1").eq(lit("fo_o")),
);
assert_change(
regex_match(col("c1"), lit("^(fo_o)$")),
col("c1").eq(lit("fo_o")),
);
assert_change(
regex_match(col("c1"), lit("^(fo_o|ba_r)$")),
col("c1").eq(lit("fo_o")).or(col("c1").eq(lit("ba_r"))),
);
assert_change(
regex_not_match(col("c1"), lit("^(fo_o|ba_r)$")),
col("c1")
.not_eq(lit("fo_o"))
.and(col("c1").not_eq(lit("ba_r"))),
);
assert_change(
regex_match(col("c1"), lit("^(fo_o|ba_r|ba_z)$")),
((col("c1").eq(lit("fo_o"))).or(col("c1").eq(lit("ba_r"))))
.or(col("c1").eq(lit("ba_z"))),
);
assert_change(
regex_match(col("c1"), lit("^(fo_o|ba_r|baz|qu_x)$")),
col("c1").in_list(
vec![lit("fo_o"), lit("ba_r"), lit("baz"), lit("qu_x")],
false,
),
);
// regular expressions that mismatch captured literals
assert_no_change(regex_match(col("c1"), lit("(foo|bar)")));
assert_no_change(regex_match(col("c1"), lit("(foo|bar)*")));
assert_no_change(regex_match(col("c1"), lit("(fo_o|b_ar)")));
assert_no_change(regex_match(col("c1"), lit("(foo|ba_r)*")));
assert_no_change(regex_match(col("c1"), lit("(fo_o|ba_r)*")));
assert_no_change(regex_match(col("c1"), lit("^(foo|bar)*")));
assert_no_change(regex_match(col("c1"), lit("^foo|bar$")));
assert_no_change(regex_match(col("c1"), lit("^(foo)(bar)$")));
assert_no_change(regex_match(col("c1"), lit("^")));
assert_no_change(regex_match(col("c1"), lit("$")));
assert_no_change(regex_match(col("c1"), lit("$^")));
assert_no_change(regex_match(col("c1"), lit("$foo^")));
// OR-chain
assert_change(
regex_match(col("c1"), lit("foo|bar|baz")),
like(col("c1"), "%foo%")
.or(like(col("c1"), "%bar%"))
.or(like(col("c1"), "%baz%")),
);
assert_change(
regex_match(col("c1"), lit("foo|x|baz")),
like(col("c1"), "%foo%")
.or(like(col("c1"), "%x%"))
.or(like(col("c1"), "%baz%")),
);
assert_change(
regex_not_match(col("c1"), lit("foo|bar|baz")),
not_like(col("c1"), "%foo%")
.and(not_like(col("c1"), "%bar%"))
.and(not_like(col("c1"), "%baz%")),
);
// both anchored expressions (translated to equality) and unanchored
assert_change(
regex_match(col("c1"), lit("foo|^x$|baz")),
like(col("c1"), "%foo%")
.or(col("c1").eq(lit("x")))
.or(like(col("c1"), "%baz%")),
);
assert_change(
regex_not_match(col("c1"), lit("foo|^bar$|baz")),
not_like(col("c1"), "%foo%")
.and(col("c1").not_eq(lit("bar")))
.and(not_like(col("c1"), "%baz%")),
);
// Too many patterns (MAX_REGEX_ALTERNATIONS_EXPANSION)
assert_no_change(regex_match(col("c1"), lit("foo|bar|baz|blarg|bozo|etc")));
}