Skip to content

Commit ed6edf1

Browse files
ewgeniussgrebnov
authored andcommitted
Fix ILIKE expression support in SQL unparser (apache#15820)
* Fix ILIKE expression support in SQL unparser (#76) * update tests
1 parent 0b717a5 commit ed6edf1

File tree

2 files changed

+121
-8
lines changed

2 files changed

+121
-8
lines changed

datafusion/sql/src/unparser/expr.rs

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -273,20 +273,39 @@ impl Unparser<'_> {
273273
pattern,
274274
escape_char,
275275
case_insensitive: _,
276-
})
277-
| Expr::Like(Like {
278-
negated,
279-
expr,
280-
pattern,
281-
escape_char,
282-
case_insensitive: _,
283276
}) => Ok(ast::Expr::Like {
284277
negated: *negated,
285278
expr: Box::new(self.expr_to_sql_inner(expr)?),
286279
pattern: Box::new(self.expr_to_sql_inner(pattern)?),
287280
escape_char: escape_char.map(|c| c.to_string()),
288281
any: false,
289282
}),
283+
Expr::Like(Like {
284+
negated,
285+
expr,
286+
pattern,
287+
escape_char,
288+
case_insensitive,
289+
}) => {
290+
if *case_insensitive {
291+
Ok(ast::Expr::ILike {
292+
negated: *negated,
293+
expr: Box::new(self.expr_to_sql_inner(expr)?),
294+
pattern: Box::new(self.expr_to_sql_inner(pattern)?),
295+
escape_char: escape_char.map(|c| c.to_string()),
296+
any: false,
297+
})
298+
} else {
299+
Ok(ast::Expr::Like {
300+
negated: *negated,
301+
expr: Box::new(self.expr_to_sql_inner(expr)?),
302+
pattern: Box::new(self.expr_to_sql_inner(pattern)?),
303+
escape_char: escape_char.map(|c| c.to_string()),
304+
any: false,
305+
})
306+
}
307+
}
308+
290309
Expr::AggregateFunction(agg) => {
291310
let func_name = agg.func.name();
292311
let AggregateFunctionParams {
@@ -1855,10 +1874,20 @@ mod tests {
18551874
expr: Box::new(col("a")),
18561875
pattern: Box::new(lit("foo")),
18571876
escape_char: Some('o'),
1858-
case_insensitive: true,
1877+
case_insensitive: false,
18591878
}),
18601879
r#"a NOT LIKE 'foo' ESCAPE 'o'"#,
18611880
),
1881+
(
1882+
Expr::Like(Like {
1883+
negated: true,
1884+
expr: Box::new(col("a")),
1885+
pattern: Box::new(lit("foo")),
1886+
escape_char: Some('o'),
1887+
case_insensitive: true,
1888+
}),
1889+
r#"a NOT ILIKE 'foo' ESCAPE 'o'"#,
1890+
),
18621891
(
18631892
Expr::SimilarTo(Like {
18641893
negated: false,

datafusion/sql/tests/cases/plan_to_sql.rs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2505,3 +2505,87 @@ fn test_unparse_left_semi_join_with_table_scan_projection() -> Result<()> {
25052505
);
25062506
Ok(())
25072507
}
2508+
2509+
#[test]
2510+
fn test_like_filter() {
2511+
let statement = generate_round_trip_statement(
2512+
GenericDialect {},
2513+
r#"SELECT first_name FROM person WHERE first_name LIKE '%John%'"#,
2514+
);
2515+
assert_snapshot!(
2516+
statement,
2517+
@"SELECT person.first_name FROM person WHERE person.first_name LIKE '%John%'"
2518+
);
2519+
}
2520+
2521+
#[test]
2522+
fn test_ilike_filter() {
2523+
let statement = generate_round_trip_statement(
2524+
GenericDialect {},
2525+
r#"SELECT first_name FROM person WHERE first_name ILIKE '%john%'"#,
2526+
);
2527+
assert_snapshot!(
2528+
statement,
2529+
@"SELECT person.first_name FROM person WHERE person.first_name ILIKE '%john%'"
2530+
);
2531+
}
2532+
2533+
#[test]
2534+
fn test_not_like_filter() {
2535+
let statement = generate_round_trip_statement(
2536+
GenericDialect {},
2537+
r#"SELECT first_name FROM person WHERE first_name NOT LIKE 'A%'"#,
2538+
);
2539+
assert_snapshot!(
2540+
statement,
2541+
@"SELECT person.first_name FROM person WHERE person.first_name NOT LIKE 'A%'"
2542+
);
2543+
}
2544+
2545+
#[test]
2546+
fn test_not_ilike_filter() {
2547+
let statement = generate_round_trip_statement(
2548+
GenericDialect {},
2549+
r#"SELECT first_name FROM person WHERE first_name NOT ILIKE 'a%'"#,
2550+
);
2551+
assert_snapshot!(
2552+
statement,
2553+
@"SELECT person.first_name FROM person WHERE person.first_name NOT ILIKE 'a%'"
2554+
);
2555+
}
2556+
2557+
#[test]
2558+
fn test_like_filter_with_escape() {
2559+
let statement = generate_round_trip_statement(
2560+
GenericDialect {},
2561+
r#"SELECT first_name FROM person WHERE first_name LIKE 'A!_%' ESCAPE '!'"#,
2562+
);
2563+
assert_snapshot!(
2564+
statement,
2565+
@"SELECT person.first_name FROM person WHERE person.first_name LIKE 'A!_%' ESCAPE '!'"
2566+
);
2567+
}
2568+
2569+
#[test]
2570+
fn test_not_like_filter_with_escape() {
2571+
let statement = generate_round_trip_statement(
2572+
GenericDialect {},
2573+
r#"SELECT first_name FROM person WHERE first_name NOT LIKE 'A!_%' ESCAPE '!'"#,
2574+
);
2575+
assert_snapshot!(
2576+
statement,
2577+
@"SELECT person.first_name FROM person WHERE person.first_name NOT LIKE 'A!_%' ESCAPE '!'"
2578+
);
2579+
}
2580+
2581+
#[test]
2582+
fn test_not_ilike_filter_with_escape() {
2583+
let statement = generate_round_trip_statement(
2584+
GenericDialect {},
2585+
r#"SELECT first_name FROM person WHERE first_name NOT ILIKE 'A!_%' ESCAPE '!'"#,
2586+
);
2587+
assert_snapshot!(
2588+
statement,
2589+
@"SELECT person.first_name FROM person WHERE person.first_name NOT ILIKE 'A!_%' ESCAPE '!'"
2590+
);
2591+
}

0 commit comments

Comments
 (0)