mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-11-11 19:43:47 +00:00
fix: mysql backslash escaping (#373)
* fix: mysql backslash escaping * fixes
This commit is contained in:
parent
60ad78dafc
commit
ea0eb1be61
5 changed files with 67 additions and 6 deletions
|
|
@ -11,7 +11,6 @@
|
|||
// limitations under the License.
|
||||
|
||||
//! SQL Abstract Syntax Tree (AST) types
|
||||
|
||||
mod data_type;
|
||||
mod ddl;
|
||||
mod operator;
|
||||
|
|
@ -1874,6 +1873,7 @@ pub enum HiveRowFormat {
|
|||
DELIMITED,
|
||||
}
|
||||
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ pub use self::sqlite::SQLiteDialect;
|
|||
pub use crate::keywords;
|
||||
|
||||
/// `dialect_of!(parser is SQLiteDialect | GenericDialect)` evaluates
|
||||
/// to `true` iff `parser.dialect` is one of the `Dialect`s specified.
|
||||
/// to `true` if `parser.dialect` is one of the `Dialect`s specified.
|
||||
macro_rules! dialect_of {
|
||||
( $parsed_dialect: ident is $($dialect_type: ty)|+ ) => {
|
||||
($($parsed_dialect.dialect.is::<$dialect_type>())||+)
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@ use core::str::Chars;
|
|||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::dialect::Dialect;
|
||||
use crate::dialect::SnowflakeDialect;
|
||||
use crate::dialect::{Dialect, MySqlDialect};
|
||||
use crate::keywords::{Keyword, ALL_KEYWORDS, ALL_KEYWORDS_INDEX};
|
||||
|
||||
/// SQL Token enumeration
|
||||
|
|
@ -411,6 +411,7 @@ impl<'a> Tokenizer<'a> {
|
|||
// string
|
||||
'\'' => {
|
||||
let s = self.tokenize_single_quoted_string(chars)?;
|
||||
|
||||
Ok(Some(Token::SingleQuotedString(s)))
|
||||
}
|
||||
// delimited (quoted) identifier
|
||||
|
|
@ -636,18 +637,31 @@ impl<'a> Tokenizer<'a> {
|
|||
) -> Result<String, TokenizerError> {
|
||||
let mut s = String::new();
|
||||
chars.next(); // consume the opening quote
|
||||
|
||||
// slash escaping is specific to MySQL dialect
|
||||
let mut is_escaped = false;
|
||||
while let Some(&ch) = chars.peek() {
|
||||
match ch {
|
||||
'\'' => {
|
||||
chars.next(); // consume
|
||||
let escaped_quote = chars.peek().map(|c| *c == '\'').unwrap_or(false);
|
||||
if escaped_quote {
|
||||
s.push('\'');
|
||||
if is_escaped {
|
||||
s.push(ch);
|
||||
is_escaped = false;
|
||||
} else if chars.peek().map(|c| *c == '\'').unwrap_or(false) {
|
||||
s.push(ch);
|
||||
chars.next();
|
||||
} else {
|
||||
return Ok(s);
|
||||
}
|
||||
}
|
||||
'\\' => {
|
||||
if dialect_of!(self is MySqlDialect) {
|
||||
is_escaped = !is_escaped;
|
||||
} else {
|
||||
s.push(ch);
|
||||
}
|
||||
chars.next();
|
||||
}
|
||||
_ => {
|
||||
chars.next(); // consume
|
||||
s.push(ch);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue