Skip to content

Commit 1ed1904

Browse files
committed
Fix ILIKE expression support in SQL unparser
1 parent bfde649 commit 1ed1904

2 files changed

Lines changed: 93 additions & 15 deletions

File tree

datafusion/sql/src/unparser/expr.rs

Lines changed: 66 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -261,26 +261,57 @@ impl Unparser<'_> {
261261
uses_odbc_syntax: false,
262262
}))
263263
}
264-
Expr::SimilarTo(Like {
264+
Expr::Like(Like {
265265
negated,
266266
expr,
267267
pattern,
268268
escape_char,
269-
case_insensitive: _,
270-
})
271-
| Expr::Like(Like {
269+
case_insensitive,
270+
}) => {
271+
if *case_insensitive {
272+
Ok(ast::Expr::ILike {
273+
negated: *negated,
274+
expr: Box::new(self.expr_to_sql_inner(expr)?),
275+
pattern: Box::new(self.expr_to_sql_inner(pattern)?),
276+
escape_char: escape_char.map(|c| c.to_string()),
277+
any: false,
278+
})
279+
} else {
280+
Ok(ast::Expr::Like {
281+
negated: *negated,
282+
expr: Box::new(self.expr_to_sql_inner(expr)?),
283+
pattern: Box::new(self.expr_to_sql_inner(pattern)?),
284+
escape_char: escape_char.map(|c| c.to_string()),
285+
any: false,
286+
})
287+
}
288+
}
289+
Expr::SimilarTo(Like {
272290
negated,
273291
expr,
274292
pattern,
275293
escape_char,
276-
case_insensitive: _,
277-
}) => Ok(ast::Expr::Like {
278-
negated: *negated,
279-
expr: Box::new(self.expr_to_sql_inner(expr)?),
280-
pattern: Box::new(self.expr_to_sql_inner(pattern)?),
281-
escape_char: escape_char.map(|c| c.to_string()),
282-
any: false,
283-
}),
294+
case_insensitive,
295+
}) => {
296+
if *case_insensitive {
297+
Ok(ast::Expr::ILike {
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+
} else {
305+
Ok(ast::Expr::Like {
306+
negated: *negated,
307+
expr: Box::new(self.expr_to_sql_inner(expr)?),
308+
pattern: Box::new(self.expr_to_sql_inner(pattern)?),
309+
escape_char: escape_char.map(|c| c.to_string()),
310+
any: false,
311+
})
312+
}
313+
}
314+
284315
Expr::AggregateFunction(agg) => {
285316
let func_name = agg.func.name();
286317

@@ -970,7 +1001,7 @@ impl Unparser<'_> {
9701001
DataType::Timestamp(unit, _) => unit,
9711002
_ => return Err(internal_datafusion_err!("Expected Timestamp, got {:?}", T::DATA_TYPE)),
9721003
};
973-
1004+
9741005
Ok(ast::Expr::Cast {
9751006
kind: ast::CastKind::Cast,
9761007
expr: Box::new(ast::Expr::Value(SingleQuotedString(ts))),
@@ -1797,7 +1828,7 @@ mod tests {
17971828
expr: Box::new(col("a")),
17981829
pattern: Box::new(lit("foo")),
17991830
escape_char: Some('o'),
1800-
case_insensitive: true,
1831+
case_insensitive: false,
18011832
}),
18021833
r#"a NOT LIKE 'foo' ESCAPE 'o'"#,
18031834
),
@@ -1807,10 +1838,30 @@ mod tests {
18071838
expr: Box::new(col("a")),
18081839
pattern: Box::new(lit("foo")),
18091840
escape_char: Some('o'),
1810-
case_insensitive: true,
1841+
case_insensitive: false,
18111842
}),
18121843
r#"a LIKE 'foo' ESCAPE 'o'"#,
18131844
),
1845+
(
1846+
Expr::Like(Like {
1847+
negated: true,
1848+
expr: Box::new(col("a")),
1849+
pattern: Box::new(lit("foo")),
1850+
escape_char: Some('o'),
1851+
case_insensitive: true,
1852+
}),
1853+
r#"a NOT ILIKE 'foo' ESCAPE 'o'"#,
1854+
),
1855+
(
1856+
Expr::SimilarTo(Like {
1857+
negated: false,
1858+
expr: Box::new(col("a")),
1859+
pattern: Box::new(lit("foo")),
1860+
escape_char: Some('o'),
1861+
case_insensitive: true,
1862+
}),
1863+
r#"a ILIKE 'foo' ESCAPE 'o'"#,
1864+
),
18141865
(
18151866
Expr::Literal(ScalarValue::Date64(Some(0))),
18161867
r#"CAST('1970-01-01 00:00:00' AS DATETIME)"#,

datafusion/sql/tests/cases/plan_to_sql.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1533,6 +1533,33 @@ 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+
15361563
#[test]
15371564
fn test_join_with_no_conditions() {
15381565
sql_round_trip(

0 commit comments

Comments
 (0)