Ignore escaped LIKE wildcards in MySQL (#1735)

This commit is contained in:
Michael Victor Zink 2025-02-28 22:07:39 -08:00 committed by GitHub
parent ed416548dc
commit a629ddf89b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 89 additions and 15 deletions

View file

@ -10387,15 +10387,8 @@ fn parse_with_recursion_limit() {
#[test]
fn parse_escaped_string_with_unescape() {
fn assert_mysql_query_value(sql: &str, quoted: &str) {
let stmt = TestedDialects::new(vec![
Box::new(MySqlDialect {}),
Box::new(BigQueryDialect {}),
Box::new(SnowflakeDialect {}),
])
.one_statement_parses_to(sql, "");
match stmt {
fn assert_mysql_query_value(dialects: &TestedDialects, sql: &str, quoted: &str) {
match dialects.one_statement_parses_to(sql, "") {
Statement::Query(query) => match *query.body {
SetExpr::Select(value) => {
let expr = expr_from_projection(only(&value.projection));
@ -10411,17 +10404,38 @@ fn parse_escaped_string_with_unescape() {
_ => unreachable!(),
};
}
let escaping_dialects =
&all_dialects_where(|dialect| dialect.supports_string_literal_backslash_escape());
let no_wildcard_exception = &all_dialects_where(|dialect| {
dialect.supports_string_literal_backslash_escape() && !dialect.ignores_wildcard_escapes()
});
let with_wildcard_exception = &all_dialects_where(|dialect| {
dialect.supports_string_literal_backslash_escape() && dialect.ignores_wildcard_escapes()
});
let sql = r"SELECT 'I\'m fine'";
assert_mysql_query_value(sql, "I'm fine");
assert_mysql_query_value(escaping_dialects, sql, "I'm fine");
let sql = r#"SELECT 'I''m fine'"#;
assert_mysql_query_value(sql, "I'm fine");
assert_mysql_query_value(escaping_dialects, sql, "I'm fine");
let sql = r#"SELECT 'I\"m fine'"#;
assert_mysql_query_value(sql, "I\"m fine");
assert_mysql_query_value(escaping_dialects, sql, "I\"m fine");
let sql = r"SELECT 'Testing: \0 \\ \% \_ \b \n \r \t \Z \a \h \ '";
assert_mysql_query_value(sql, "Testing: \0 \\ % _ \u{8} \n \r \t \u{1a} \u{7} h ");
assert_mysql_query_value(
no_wildcard_exception,
sql,
"Testing: \0 \\ % _ \u{8} \n \r \t \u{1a} \u{7} h ",
);
// check MySQL doesn't remove backslash from escaped LIKE wildcards
assert_mysql_query_value(
with_wildcard_exception,
sql,
"Testing: \0 \\ \\% \\_ \u{8} \n \r \t \u{1a} \u{7} h ",
);
}
#[test]

View file

@ -2627,6 +2627,17 @@ fn parse_rlike_and_regexp() {
}
}
#[test]
fn parse_like_with_escape() {
// verify backslash is not stripped for escaped wildcards
mysql().verified_only_select(r#"SELECT 'a\%c' LIKE 'a\%c'"#);
mysql().verified_only_select(r#"SELECT 'a\_c' LIKE 'a\_c'"#);
mysql().verified_only_select(r#"SELECT '%\_\%' LIKE '%\_\%'"#);
mysql().verified_only_select(r#"SELECT '\_\%' LIKE CONCAT('\_', '\%')"#);
mysql().verified_only_select(r#"SELECT 'a%c' LIKE 'a$%c' ESCAPE '$'"#);
mysql().verified_only_select(r#"SELECT 'a_c' LIKE 'a#_c' ESCAPE '#'"#);
}
#[test]
fn parse_kill() {
let stmt = mysql_and_generic().verified_stmt("KILL CONNECTION 5");