Skip to content

Commit fb979bf

Browse files
committed
Fix ILIKE expression support in SQL unparser (apache#76)
* Fix ILIKE expression support in SQL unparser * fix pattern matching order and adjust tests * add LIKE/ILIKE + ESCAPE <char> tests
1 parent d4bc1c1 commit fb979bf

2 files changed

Lines changed: 90 additions & 8 deletions

File tree

datafusion/sql/src/unparser/expr.rs

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -307,19 +307,36 @@ impl Unparser<'_> {
307307
pattern,
308308
escape_char,
309309
case_insensitive: _,
310-
})
311-
| Expr::Like(Like {
312-
negated,
313-
expr,
314-
pattern,
315-
escape_char,
316-
case_insensitive: _,
317310
}) => Ok(ast::Expr::Like {
318311
negated: *negated,
319312
expr: Box::new(self.expr_to_sql_inner(expr)?),
320313
pattern: Box::new(self.expr_to_sql_inner(pattern)?),
321314
escape_char: escape_char.map(|c| c.to_string()),
322315
}),
316+
Expr::Like(Like {
317+
negated,
318+
expr,
319+
pattern,
320+
escape_char,
321+
case_insensitive,
322+
}) => {
323+
if *case_insensitive {
324+
Ok(ast::Expr::ILike {
325+
negated: *negated,
326+
expr: Box::new(self.expr_to_sql_inner(expr)?),
327+
pattern: Box::new(self.expr_to_sql_inner(pattern)?),
328+
escape_char: escape_char.map(|c| c.to_string()),
329+
})
330+
} else {
331+
Ok(ast::Expr::Like {
332+
negated: *negated,
333+
expr: Box::new(self.expr_to_sql_inner(expr)?),
334+
pattern: Box::new(self.expr_to_sql_inner(pattern)?),
335+
escape_char: escape_char.map(|c| c.to_string()),
336+
})
337+
}
338+
}
339+
323340
Expr::AggregateFunction(agg) => {
324341
let func_name = agg.func.name();
325342

@@ -1692,10 +1709,30 @@ mod tests {
16921709
expr: Box::new(col("a")),
16931710
pattern: Box::new(lit("foo")),
16941711
escape_char: Some('o'),
1695-
case_insensitive: true,
1712+
case_insensitive: false,
16961713
}),
16971714
r#"a NOT LIKE 'foo' ESCAPE 'o'"#,
16981715
),
1716+
(
1717+
Expr::Like(Like {
1718+
negated: true,
1719+
expr: Box::new(col("a")),
1720+
pattern: Box::new(lit("foo")),
1721+
escape_char: Some('o'),
1722+
case_insensitive: true,
1723+
}),
1724+
r#"a NOT ILIKE 'foo' ESCAPE 'o'"#,
1725+
),
1726+
(
1727+
Expr::SimilarTo(Like {
1728+
negated: false,
1729+
expr: Box::new(col("a")),
1730+
pattern: Box::new(lit("foo")),
1731+
escape_char: Some('o'),
1732+
case_insensitive: false,
1733+
}),
1734+
r#"a LIKE 'foo' ESCAPE 'o'"#,
1735+
),
16991736
(
17001737
Expr::SimilarTo(Like {
17011738
negated: false,

datafusion/sql/tests/cases/plan_to_sql.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -873,3 +873,48 @@ fn test_with_offset0() {
873873
fn test_with_offset95() {
874874
sql_round_trip(MySqlDialect {}, "select 1 offset 95", "SELECT 1 OFFSET 95");
875875
}
876+
877+
#[test]
878+
fn test_like_filters() {
879+
sql_round_trip(
880+
GenericDialect {},
881+
r#"SELECT * FROM person WHERE first_name LIKE '%John%'"#,
882+
r#"SELECT * FROM person WHERE person.first_name LIKE '%John%'"#,
883+
);
884+
885+
sql_round_trip(
886+
GenericDialect {},
887+
r#"SELECT * FROM person WHERE first_name ILIKE '%john%'"#,
888+
r#"SELECT * FROM person WHERE person.first_name ILIKE '%john%'"#,
889+
);
890+
891+
sql_round_trip(
892+
GenericDialect {},
893+
r#"SELECT * FROM person WHERE first_name NOT LIKE 'A%'"#,
894+
r#"SELECT * FROM person WHERE person.first_name NOT LIKE 'A%'"#,
895+
);
896+
897+
sql_round_trip(
898+
GenericDialect {},
899+
r#"SELECT * FROM person WHERE first_name NOT ILIKE 'a%'"#,
900+
r#"SELECT * FROM person WHERE person.first_name NOT ILIKE 'a%'"#,
901+
);
902+
903+
sql_round_trip(
904+
GenericDialect {},
905+
r#"SELECT * FROM person WHERE first_name LIKE 'A!_%' ESCAPE '!'"#,
906+
r#"SELECT * FROM person WHERE person.first_name LIKE 'A!_%' ESCAPE '!'"#,
907+
);
908+
909+
sql_round_trip(
910+
GenericDialect {},
911+
r#"SELECT * FROM person WHERE first_name NOT LIKE 'A!_%' ESCAPE '!'"#,
912+
r#"SELECT * FROM person WHERE person.first_name NOT LIKE 'A!_%' ESCAPE '!'"#,
913+
);
914+
915+
sql_round_trip(
916+
GenericDialect {},
917+
r#"SELECT * FROM person WHERE first_name NOT ILIKE 'A!_%' ESCAPE '!'"#,
918+
r#"SELECT * FROM person WHERE person.first_name NOT ILIKE 'A!_%' ESCAPE '!'"#,
919+
);
920+
}

0 commit comments

Comments
 (0)