Skip to content

Commit e0fd892

Browse files
authored
Fix ILIKE expression support in SQL unparser (apache#15820)
* Fix ILIKE expression support in SQL unparser (#76) * update tests
1 parent f85535b commit e0fd892

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 {
@@ -1866,10 +1885,20 @@ mod tests {
18661885
expr: Box::new(col("a")),
18671886
pattern: Box::new(lit("foo")),
18681887
escape_char: Some('o'),
1869-
case_insensitive: true,
1888+
case_insensitive: false,
18701889
}),
18711890
r#"a NOT LIKE 'foo' ESCAPE 'o'"#,
18721891
),
1892+
(
1893+
Expr::Like(Like {
1894+
negated: true,
1895+
expr: Box::new(col("a")),
1896+
pattern: Box::new(lit("foo")),
1897+
escape_char: Some('o'),
1898+
case_insensitive: true,
1899+
}),
1900+
r#"a NOT ILIKE 'foo' ESCAPE 'o'"#,
1901+
),
18731902
(
18741903
Expr::SimilarTo(Like {
18751904
negated: false,

datafusion/sql/tests/cases/plan_to_sql.rs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2432,3 +2432,87 @@ fn test_unparse_left_semi_join_with_table_scan_projection() -> Result<()> {
24322432
);
24332433
Ok(())
24342434
}
2435+
2436+
#[test]
2437+
fn test_like_filter() {
2438+
let statement = generate_round_trip_statement(
2439+
GenericDialect {},
2440+
r#"SELECT first_name FROM person WHERE first_name LIKE '%John%'"#,
2441+
);
2442+
assert_snapshot!(
2443+
statement,
2444+
@"SELECT person.first_name FROM person WHERE person.first_name LIKE '%John%'"
2445+
);
2446+
}
2447+
2448+
#[test]
2449+
fn test_ilike_filter() {
2450+
let statement = generate_round_trip_statement(
2451+
GenericDialect {},
2452+
r#"SELECT first_name FROM person WHERE first_name ILIKE '%john%'"#,
2453+
);
2454+
assert_snapshot!(
2455+
statement,
2456+
@"SELECT person.first_name FROM person WHERE person.first_name ILIKE '%john%'"
2457+
);
2458+
}
2459+
2460+
#[test]
2461+
fn test_not_like_filter() {
2462+
let statement = generate_round_trip_statement(
2463+
GenericDialect {},
2464+
r#"SELECT first_name FROM person WHERE first_name NOT LIKE 'A%'"#,
2465+
);
2466+
assert_snapshot!(
2467+
statement,
2468+
@"SELECT person.first_name FROM person WHERE person.first_name NOT LIKE 'A%'"
2469+
);
2470+
}
2471+
2472+
#[test]
2473+
fn test_not_ilike_filter() {
2474+
let statement = generate_round_trip_statement(
2475+
GenericDialect {},
2476+
r#"SELECT first_name FROM person WHERE first_name NOT ILIKE 'a%'"#,
2477+
);
2478+
assert_snapshot!(
2479+
statement,
2480+
@"SELECT person.first_name FROM person WHERE person.first_name NOT ILIKE 'a%'"
2481+
);
2482+
}
2483+
2484+
#[test]
2485+
fn test_like_filter_with_escape() {
2486+
let statement = generate_round_trip_statement(
2487+
GenericDialect {},
2488+
r#"SELECT first_name FROM person WHERE first_name LIKE 'A!_%' ESCAPE '!'"#,
2489+
);
2490+
assert_snapshot!(
2491+
statement,
2492+
@"SELECT person.first_name FROM person WHERE person.first_name LIKE 'A!_%' ESCAPE '!'"
2493+
);
2494+
}
2495+
2496+
#[test]
2497+
fn test_not_like_filter_with_escape() {
2498+
let statement = generate_round_trip_statement(
2499+
GenericDialect {},
2500+
r#"SELECT first_name FROM person WHERE first_name NOT LIKE 'A!_%' ESCAPE '!'"#,
2501+
);
2502+
assert_snapshot!(
2503+
statement,
2504+
@"SELECT person.first_name FROM person WHERE person.first_name NOT LIKE 'A!_%' ESCAPE '!'"
2505+
);
2506+
}
2507+
2508+
#[test]
2509+
fn test_not_ilike_filter_with_escape() {
2510+
let statement = generate_round_trip_statement(
2511+
GenericDialect {},
2512+
r#"SELECT first_name FROM person WHERE first_name NOT ILIKE 'A!_%' ESCAPE '!'"#,
2513+
);
2514+
assert_snapshot!(
2515+
statement,
2516+
@"SELECT person.first_name FROM person WHERE person.first_name NOT ILIKE 'A!_%' ESCAPE '!'"
2517+
);
2518+
}

0 commit comments

Comments
 (0)