mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-09-20 12:49:47 +00:00
Added support for Mysql Backslash escapes (enabled by default) (#844)
This commit is contained in:
parent
00d071286b
commit
04d9f3af2e
2 changed files with 41 additions and 31 deletions
|
@ -1094,16 +1094,11 @@ impl<'a> Tokenizer<'a> {
|
||||||
|
|
||||||
chars.next(); // consume the opening quote
|
chars.next(); // consume the opening quote
|
||||||
|
|
||||||
// slash escaping is specific to MySQL dialect
|
|
||||||
let mut is_escaped = false;
|
|
||||||
while let Some(&ch) = chars.peek() {
|
while let Some(&ch) = chars.peek() {
|
||||||
match ch {
|
match ch {
|
||||||
char if char == quote_style => {
|
char if char == quote_style => {
|
||||||
chars.next(); // consume
|
chars.next(); // consume
|
||||||
if is_escaped {
|
if chars.peek().map(|c| *c == quote_style).unwrap_or(false) {
|
||||||
s.push(ch);
|
|
||||||
is_escaped = false;
|
|
||||||
} else if chars.peek().map(|c| *c == quote_style).unwrap_or(false) {
|
|
||||||
s.push(ch);
|
s.push(ch);
|
||||||
chars.next();
|
chars.next();
|
||||||
} else {
|
} else {
|
||||||
|
@ -1111,12 +1106,28 @@ impl<'a> Tokenizer<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'\\' => {
|
'\\' => {
|
||||||
|
// consume
|
||||||
|
chars.next();
|
||||||
|
// slash escaping is specific to MySQL dialect
|
||||||
if dialect_of!(self is MySqlDialect) {
|
if dialect_of!(self is MySqlDialect) {
|
||||||
is_escaped = !is_escaped;
|
if let Some(next) = chars.peek() {
|
||||||
|
// See https://dev.mysql.com/doc/refman/8.0/en/string-literals.html#character-escape-sequences
|
||||||
|
let n = match next {
|
||||||
|
'\'' | '\"' | '\\' | '%' | '_' => *next,
|
||||||
|
'0' => '\0',
|
||||||
|
'b' => '\u{8}',
|
||||||
|
'n' => '\n',
|
||||||
|
'r' => '\r',
|
||||||
|
't' => '\t',
|
||||||
|
'Z' => '\u{1a}',
|
||||||
|
_ => *next,
|
||||||
|
};
|
||||||
|
s.push(n);
|
||||||
|
chars.next(); // consume next
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
s.push(ch);
|
s.push(ch);
|
||||||
}
|
}
|
||||||
chars.next();
|
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
chars.next(); // consume
|
chars.next(); // consume
|
||||||
|
|
|
@ -518,8 +518,7 @@ fn parse_unterminated_escape() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_escaped_string() {
|
fn parse_escaped_string() {
|
||||||
let sql = r#"SELECT 'I\'m fine'"#;
|
fn assert_mysql_query_value(sql: &str, quoted: &str) {
|
||||||
|
|
||||||
let stmt = mysql().one_statement_parses_to(sql, "");
|
let stmt = mysql().one_statement_parses_to(sql, "");
|
||||||
|
|
||||||
match stmt {
|
match stmt {
|
||||||
|
@ -528,25 +527,25 @@ fn parse_escaped_string() {
|
||||||
let expr = expr_from_projection(only(&value.projection));
|
let expr = expr_from_projection(only(&value.projection));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
*expr,
|
*expr,
|
||||||
Expr::Value(Value::SingleQuotedString("I'm fine".to_string()))
|
Expr::Value(Value::SingleQuotedString(quoted.to_string()))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
},
|
},
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
let sql = r#"SELECT 'I\'m fine'"#;
|
||||||
|
assert_mysql_query_value(sql, "I'm fine");
|
||||||
|
|
||||||
let sql = r#"SELECT 'I''m fine'"#;
|
let sql = r#"SELECT 'I''m fine'"#;
|
||||||
|
assert_mysql_query_value(sql, "I'm fine");
|
||||||
|
|
||||||
let projection = mysql().verified_only_select(sql).projection;
|
let sql = r#"SELECT 'I\"m fine'"#;
|
||||||
let item = projection.get(0).unwrap();
|
assert_mysql_query_value(sql, "I\"m fine");
|
||||||
|
|
||||||
match &item {
|
let sql = r#"SELECT 'Testing: \0 \\ \% \_ \b \n \r \t \Z \a \ '"#;
|
||||||
SelectItem::UnnamedExpr(Expr::Value(value)) => {
|
assert_mysql_query_value(sql, "Testing: \0 \\ % _ \u{8} \n \r \t \u{1a} a ");
|
||||||
assert_eq!(*value, Value::SingleQuotedString("I'm fine".to_string()));
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue