diff --git a/datafusion/sql/src/unparser/expr.rs b/datafusion/sql/src/unparser/expr.rs index 1826ef340faf..4c4aeb472b9c 100644 --- a/datafusion/sql/src/unparser/expr.rs +++ b/datafusion/sql/src/unparser/expr.rs @@ -267,13 +267,6 @@ impl Unparser<'_> { pattern, escape_char, case_insensitive: _, - }) - | Expr::Like(Like { - negated, - expr, - pattern, - escape_char, - case_insensitive: _, }) => Ok(ast::Expr::Like { negated: *negated, expr: Box::new(self.expr_to_sql_inner(expr)?), @@ -281,6 +274,32 @@ impl Unparser<'_> { escape_char: escape_char.map(|c| c.to_string()), any: false, }), + Expr::Like(Like { + negated, + expr, + pattern, + escape_char, + case_insensitive, + }) => { + if *case_insensitive { + Ok(ast::Expr::ILike { + negated: *negated, + expr: Box::new(self.expr_to_sql_inner(expr)?), + pattern: Box::new(self.expr_to_sql_inner(pattern)?), + escape_char: escape_char.map(|c| c.to_string()), + any: false, + }) + } else { + Ok(ast::Expr::Like { + negated: *negated, + expr: Box::new(self.expr_to_sql_inner(expr)?), + pattern: Box::new(self.expr_to_sql_inner(pattern)?), + escape_char: escape_char.map(|c| c.to_string()), + any: false, + }) + } + } + Expr::AggregateFunction(agg) => { let func_name = agg.func.name(); @@ -970,7 +989,7 @@ impl Unparser<'_> { DataType::Timestamp(unit, _) => unit, _ => return Err(internal_datafusion_err!("Expected Timestamp, got {:?}", T::DATA_TYPE)), }; - + Ok(ast::Expr::Cast { kind: ast::CastKind::Cast, expr: Box::new(ast::Expr::Value(SingleQuotedString(ts))), @@ -1797,10 +1816,30 @@ mod tests { expr: Box::new(col("a")), pattern: Box::new(lit("foo")), escape_char: Some('o'), - case_insensitive: true, + case_insensitive: false, }), r#"a NOT LIKE 'foo' ESCAPE 'o'"#, ), + ( + Expr::Like(Like { + negated: true, + expr: Box::new(col("a")), + pattern: Box::new(lit("foo")), + escape_char: Some('o'), + case_insensitive: true, + }), + r#"a NOT ILIKE 'foo' ESCAPE 'o'"#, + ), + ( + Expr::SimilarTo(Like { + negated: false, + expr: Box::new(col("a")), + pattern: Box::new(lit("foo")), + escape_char: Some('o'), + case_insensitive: false, + }), + r#"a LIKE 'foo' ESCAPE 'o'"#, + ), ( Expr::SimilarTo(Like { negated: false, diff --git a/datafusion/sql/tests/cases/plan_to_sql.rs b/datafusion/sql/tests/cases/plan_to_sql.rs index c7da91df50f3..729c51dd643e 100644 --- a/datafusion/sql/tests/cases/plan_to_sql.rs +++ b/datafusion/sql/tests/cases/plan_to_sql.rs @@ -1533,6 +1533,51 @@ fn test_unnest_to_sql() { ); } +#[test] +fn test_like_filters() { + sql_round_trip( + GenericDialect {}, + r#"SELECT * FROM person WHERE first_name LIKE '%John%'"#, + r#"SELECT * FROM person WHERE person.first_name LIKE '%John%'"#, + ); + + sql_round_trip( + GenericDialect {}, + r#"SELECT * FROM person WHERE first_name ILIKE '%john%'"#, + r#"SELECT * FROM person WHERE person.first_name ILIKE '%john%'"#, + ); + + sql_round_trip( + GenericDialect {}, + r#"SELECT * FROM person WHERE first_name NOT LIKE 'A%'"#, + r#"SELECT * FROM person WHERE person.first_name NOT LIKE 'A%'"#, + ); + + sql_round_trip( + GenericDialect {}, + r#"SELECT * FROM person WHERE first_name NOT ILIKE 'a%'"#, + r#"SELECT * FROM person WHERE person.first_name NOT ILIKE 'a%'"#, + ); + + sql_round_trip( + GenericDialect {}, + r#"SELECT * FROM person WHERE first_name LIKE 'A!_%' ESCAPE '!'"#, + r#"SELECT * FROM person WHERE person.first_name LIKE 'A!_%' ESCAPE '!'"#, + ); + + sql_round_trip( + GenericDialect {}, + r#"SELECT * FROM person WHERE first_name NOT LIKE 'A!_%' ESCAPE '!'"#, + r#"SELECT * FROM person WHERE person.first_name NOT LIKE 'A!_%' ESCAPE '!'"#, + ); + + sql_round_trip( + GenericDialect {}, + r#"SELECT * FROM person WHERE first_name NOT ILIKE 'A!_%' ESCAPE '!'"#, + r#"SELECT * FROM person WHERE person.first_name NOT ILIKE 'A!_%' ESCAPE '!'"#, + ); +} + #[test] fn test_join_with_no_conditions() { sql_round_trip(