Skip to content

Commit c118e72

Browse files
ewgeniusphillipleblanc
authored andcommitted
Fix ILIKE expression support in SQL unparser (#76)
* Fix ILIKE expression support in SQL unparser * fix pattern matching order and adjust tests * add LIKE/ILIKE + ESCAPE <char> tests UPSTREAM NOTE: This was upstreamed in apache#15820 and will be in DF 48
1 parent a622b02 commit c118e72

File tree

2 files changed

+92
-8
lines changed

2 files changed

+92
-8
lines changed

datafusion/sql/src/unparser/expr.rs

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -271,20 +271,39 @@ impl Unparser<'_> {
271271
pattern,
272272
escape_char,
273273
case_insensitive: _,
274-
})
275-
| Expr::Like(Like {
276-
negated,
277-
expr,
278-
pattern,
279-
escape_char,
280-
case_insensitive: _,
281274
}) => Ok(ast::Expr::Like {
282275
negated: *negated,
283276
expr: Box::new(self.expr_to_sql_inner(expr)?),
284277
pattern: Box::new(self.expr_to_sql_inner(pattern)?),
285278
escape_char: escape_char.map(|c| c.to_string()),
286279
any: false,
287280
}),
281+
Expr::Like(Like {
282+
negated,
283+
expr,
284+
pattern,
285+
escape_char,
286+
case_insensitive,
287+
}) => {
288+
if *case_insensitive {
289+
Ok(ast::Expr::ILike {
290+
negated: *negated,
291+
expr: Box::new(self.expr_to_sql_inner(expr)?),
292+
pattern: Box::new(self.expr_to_sql_inner(pattern)?),
293+
escape_char: escape_char.map(|c| c.to_string()),
294+
any: false,
295+
})
296+
} else {
297+
Ok(ast::Expr::Like {
298+
negated: *negated,
299+
expr: Box::new(self.expr_to_sql_inner(expr)?),
300+
pattern: Box::new(self.expr_to_sql_inner(pattern)?),
301+
escape_char: escape_char.map(|c| c.to_string()),
302+
any: false,
303+
})
304+
}
305+
}
306+
288307
Expr::AggregateFunction(agg) => {
289308
let func_name = agg.func.name();
290309
let AggregateFunctionParams {
@@ -1813,10 +1832,30 @@ mod tests {
18131832
expr: Box::new(col("a")),
18141833
pattern: Box::new(lit("foo")),
18151834
escape_char: Some('o'),
1816-
case_insensitive: true,
1835+
case_insensitive: false,
18171836
}),
18181837
r#"a NOT LIKE 'foo' ESCAPE 'o'"#,
18191838
),
1839+
(
1840+
Expr::Like(Like {
1841+
negated: true,
1842+
expr: Box::new(col("a")),
1843+
pattern: Box::new(lit("foo")),
1844+
escape_char: Some('o'),
1845+
case_insensitive: true,
1846+
}),
1847+
r#"a NOT ILIKE 'foo' ESCAPE 'o'"#,
1848+
),
1849+
(
1850+
Expr::SimilarTo(Like {
1851+
negated: false,
1852+
expr: Box::new(col("a")),
1853+
pattern: Box::new(lit("foo")),
1854+
escape_char: Some('o'),
1855+
case_insensitive: false,
1856+
}),
1857+
r#"a LIKE 'foo' ESCAPE 'o'"#,
1858+
),
18201859
(
18211860
Expr::SimilarTo(Like {
18221861
negated: false,

datafusion/sql/tests/cases/plan_to_sql.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1533,6 +1533,51 @@ fn test_unnest_to_sql() {
15331533
);
15341534
}
15351535

1536+
#[test]
1537+
fn test_like_filters() {
1538+
sql_round_trip(
1539+
GenericDialect {},
1540+
r#"SELECT * FROM person WHERE first_name LIKE '%John%'"#,
1541+
r#"SELECT * FROM person WHERE person.first_name LIKE '%John%'"#,
1542+
);
1543+
1544+
sql_round_trip(
1545+
GenericDialect {},
1546+
r#"SELECT * FROM person WHERE first_name ILIKE '%john%'"#,
1547+
r#"SELECT * FROM person WHERE person.first_name ILIKE '%john%'"#,
1548+
);
1549+
1550+
sql_round_trip(
1551+
GenericDialect {},
1552+
r#"SELECT * FROM person WHERE first_name NOT LIKE 'A%'"#,
1553+
r#"SELECT * FROM person WHERE person.first_name NOT LIKE 'A%'"#,
1554+
);
1555+
1556+
sql_round_trip(
1557+
GenericDialect {},
1558+
r#"SELECT * FROM person WHERE first_name NOT ILIKE 'a%'"#,
1559+
r#"SELECT * FROM person WHERE person.first_name NOT ILIKE 'a%'"#,
1560+
);
1561+
1562+
sql_round_trip(
1563+
GenericDialect {},
1564+
r#"SELECT * FROM person WHERE first_name LIKE 'A!_%' ESCAPE '!'"#,
1565+
r#"SELECT * FROM person WHERE person.first_name LIKE 'A!_%' ESCAPE '!'"#,
1566+
);
1567+
1568+
sql_round_trip(
1569+
GenericDialect {},
1570+
r#"SELECT * FROM person WHERE first_name NOT LIKE 'A!_%' ESCAPE '!'"#,
1571+
r#"SELECT * FROM person WHERE person.first_name NOT LIKE 'A!_%' ESCAPE '!'"#,
1572+
);
1573+
1574+
sql_round_trip(
1575+
GenericDialect {},
1576+
r#"SELECT * FROM person WHERE first_name NOT ILIKE 'A!_%' ESCAPE '!'"#,
1577+
r#"SELECT * FROM person WHERE person.first_name NOT ILIKE 'A!_%' ESCAPE '!'"#,
1578+
);
1579+
}
1580+
15361581
#[test]
15371582
fn test_join_with_no_conditions() {
15381583
sql_round_trip(

0 commit comments

Comments
 (0)