mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-07-07 17:04:59 +00:00
Add support for NULL escape char in pattern match searches (#1913)
Some checks are pending
license / Release Audit Tool (RAT) (push) Waiting to run
Rust / codestyle (push) Waiting to run
Rust / lint (push) Waiting to run
Rust / benchmark-lint (push) Waiting to run
Rust / compile (push) Waiting to run
Rust / docs (push) Waiting to run
Rust / compile-no-std (push) Waiting to run
Rust / test (beta) (push) Waiting to run
Rust / test (nightly) (push) Waiting to run
Rust / test (stable) (push) Waiting to run
Some checks are pending
license / Release Audit Tool (RAT) (push) Waiting to run
Rust / codestyle (push) Waiting to run
Rust / lint (push) Waiting to run
Rust / benchmark-lint (push) Waiting to run
Rust / compile (push) Waiting to run
Rust / docs (push) Waiting to run
Rust / compile-no-std (push) Waiting to run
Rust / test (beta) (push) Waiting to run
Rust / test (nightly) (push) Waiting to run
Rust / test (stable) (push) Waiting to run
This commit is contained in:
parent
942d747d89
commit
b0bcc46e22
3 changed files with 29 additions and 12 deletions
|
@ -809,7 +809,7 @@ pub enum Expr {
|
||||||
any: bool,
|
any: bool,
|
||||||
expr: Box<Expr>,
|
expr: Box<Expr>,
|
||||||
pattern: Box<Expr>,
|
pattern: Box<Expr>,
|
||||||
escape_char: Option<String>,
|
escape_char: Option<Value>,
|
||||||
},
|
},
|
||||||
/// `ILIKE` (case-insensitive `LIKE`)
|
/// `ILIKE` (case-insensitive `LIKE`)
|
||||||
ILike {
|
ILike {
|
||||||
|
@ -819,14 +819,14 @@ pub enum Expr {
|
||||||
any: bool,
|
any: bool,
|
||||||
expr: Box<Expr>,
|
expr: Box<Expr>,
|
||||||
pattern: Box<Expr>,
|
pattern: Box<Expr>,
|
||||||
escape_char: Option<String>,
|
escape_char: Option<Value>,
|
||||||
},
|
},
|
||||||
/// SIMILAR TO regex
|
/// SIMILAR TO regex
|
||||||
SimilarTo {
|
SimilarTo {
|
||||||
negated: bool,
|
negated: bool,
|
||||||
expr: Box<Expr>,
|
expr: Box<Expr>,
|
||||||
pattern: Box<Expr>,
|
pattern: Box<Expr>,
|
||||||
escape_char: Option<String>,
|
escape_char: Option<Value>,
|
||||||
},
|
},
|
||||||
/// MySQL: RLIKE regex or REGEXP regex
|
/// MySQL: RLIKE regex or REGEXP regex
|
||||||
RLike {
|
RLike {
|
||||||
|
@ -1488,7 +1488,7 @@ impl fmt::Display for Expr {
|
||||||
} => match escape_char {
|
} => match escape_char {
|
||||||
Some(ch) => write!(
|
Some(ch) => write!(
|
||||||
f,
|
f,
|
||||||
"{} {}LIKE {}{} ESCAPE '{}'",
|
"{} {}LIKE {}{} ESCAPE {}",
|
||||||
expr,
|
expr,
|
||||||
if *negated { "NOT " } else { "" },
|
if *negated { "NOT " } else { "" },
|
||||||
if *any { "ANY " } else { "" },
|
if *any { "ANY " } else { "" },
|
||||||
|
@ -1513,7 +1513,7 @@ impl fmt::Display for Expr {
|
||||||
} => match escape_char {
|
} => match escape_char {
|
||||||
Some(ch) => write!(
|
Some(ch) => write!(
|
||||||
f,
|
f,
|
||||||
"{} {}ILIKE {}{} ESCAPE '{}'",
|
"{} {}ILIKE {}{} ESCAPE {}",
|
||||||
expr,
|
expr,
|
||||||
if *negated { "NOT " } else { "" },
|
if *negated { "NOT " } else { "" },
|
||||||
if *any { "ANY" } else { "" },
|
if *any { "ANY" } else { "" },
|
||||||
|
@ -1568,7 +1568,7 @@ impl fmt::Display for Expr {
|
||||||
} => match escape_char {
|
} => match escape_char {
|
||||||
Some(ch) => write!(
|
Some(ch) => write!(
|
||||||
f,
|
f,
|
||||||
"{} {}SIMILAR TO {} ESCAPE '{}'",
|
"{} {}SIMILAR TO {} ESCAPE {}",
|
||||||
expr,
|
expr,
|
||||||
if *negated { "NOT " } else { "" },
|
if *negated { "NOT " } else { "" },
|
||||||
pattern,
|
pattern,
|
||||||
|
|
|
@ -3654,9 +3654,9 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse the `ESCAPE CHAR` portion of `LIKE`, `ILIKE`, and `SIMILAR TO`
|
/// Parse the `ESCAPE CHAR` portion of `LIKE`, `ILIKE`, and `SIMILAR TO`
|
||||||
pub fn parse_escape_char(&mut self) -> Result<Option<String>, ParserError> {
|
pub fn parse_escape_char(&mut self) -> Result<Option<Value>, ParserError> {
|
||||||
if self.parse_keyword(Keyword::ESCAPE) {
|
if self.parse_keyword(Keyword::ESCAPE) {
|
||||||
Ok(Some(self.parse_literal_string()?))
|
Ok(Some(self.parse_value()?.into()))
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2040,7 +2040,7 @@ fn parse_ilike() {
|
||||||
pattern: Box::new(Expr::Value(
|
pattern: Box::new(Expr::Value(
|
||||||
(Value::SingleQuotedString("%a".to_string())).with_empty_span()
|
(Value::SingleQuotedString("%a".to_string())).with_empty_span()
|
||||||
)),
|
)),
|
||||||
escape_char: Some('^'.to_string()),
|
escape_char: Some(Value::SingleQuotedString('^'.to_string())),
|
||||||
any: false,
|
any: false,
|
||||||
},
|
},
|
||||||
select.selection.unwrap()
|
select.selection.unwrap()
|
||||||
|
@ -2104,7 +2104,7 @@ fn parse_like() {
|
||||||
pattern: Box::new(Expr::Value(
|
pattern: Box::new(Expr::Value(
|
||||||
(Value::SingleQuotedString("%a".to_string())).with_empty_span()
|
(Value::SingleQuotedString("%a".to_string())).with_empty_span()
|
||||||
)),
|
)),
|
||||||
escape_char: Some('^'.to_string()),
|
escape_char: Some(Value::SingleQuotedString('^'.to_string())),
|
||||||
any: false,
|
any: false,
|
||||||
},
|
},
|
||||||
select.selection.unwrap()
|
select.selection.unwrap()
|
||||||
|
@ -2167,7 +2167,24 @@ fn parse_similar_to() {
|
||||||
pattern: Box::new(Expr::Value(
|
pattern: Box::new(Expr::Value(
|
||||||
(Value::SingleQuotedString("%a".to_string())).with_empty_span()
|
(Value::SingleQuotedString("%a".to_string())).with_empty_span()
|
||||||
)),
|
)),
|
||||||
escape_char: Some('^'.to_string()),
|
escape_char: Some(Value::SingleQuotedString('^'.to_string())),
|
||||||
|
},
|
||||||
|
select.selection.unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
|
let sql = &format!(
|
||||||
|
"SELECT * FROM customers WHERE name {}SIMILAR TO '%a' ESCAPE NULL",
|
||||||
|
if negated { "NOT " } else { "" }
|
||||||
|
);
|
||||||
|
let select = verified_only_select(sql);
|
||||||
|
assert_eq!(
|
||||||
|
Expr::SimilarTo {
|
||||||
|
expr: Box::new(Expr::Identifier(Ident::new("name"))),
|
||||||
|
negated,
|
||||||
|
pattern: Box::new(Expr::Value(
|
||||||
|
(Value::SingleQuotedString("%a".to_string())).with_empty_span()
|
||||||
|
)),
|
||||||
|
escape_char: Some(Value::Null),
|
||||||
},
|
},
|
||||||
select.selection.unwrap()
|
select.selection.unwrap()
|
||||||
);
|
);
|
||||||
|
@ -2185,7 +2202,7 @@ fn parse_similar_to() {
|
||||||
pattern: Box::new(Expr::Value(
|
pattern: Box::new(Expr::Value(
|
||||||
(Value::SingleQuotedString("%a".to_string())).with_empty_span()
|
(Value::SingleQuotedString("%a".to_string())).with_empty_span()
|
||||||
)),
|
)),
|
||||||
escape_char: Some('^'.to_string()),
|
escape_char: Some(Value::SingleQuotedString('^'.to_string())),
|
||||||
})),
|
})),
|
||||||
select.selection.unwrap()
|
select.selection.unwrap()
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue