Skip to content

Commit b0bcc46

Browse files
authored
Add support for NULL escape char in pattern match searches (#1913)
1 parent 942d747 commit b0bcc46

File tree

3 files changed

+29
-12
lines changed

3 files changed

+29
-12
lines changed

src/ast/mod.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -809,7 +809,7 @@ pub enum Expr {
809809
any: bool,
810810
expr: Box<Expr>,
811811
pattern: Box<Expr>,
812-
escape_char: Option<String>,
812+
escape_char: Option<Value>,
813813
},
814814
/// `ILIKE` (case-insensitive `LIKE`)
815815
ILike {
@@ -819,14 +819,14 @@ pub enum Expr {
819819
any: bool,
820820
expr: Box<Expr>,
821821
pattern: Box<Expr>,
822-
escape_char: Option<String>,
822+
escape_char: Option<Value>,
823823
},
824824
/// SIMILAR TO regex
825825
SimilarTo {
826826
negated: bool,
827827
expr: Box<Expr>,
828828
pattern: Box<Expr>,
829-
escape_char: Option<String>,
829+
escape_char: Option<Value>,
830830
},
831831
/// MySQL: RLIKE regex or REGEXP regex
832832
RLike {
@@ -1488,7 +1488,7 @@ impl fmt::Display for Expr {
14881488
} => match escape_char {
14891489
Some(ch) => write!(
14901490
f,
1491-
"{} {}LIKE {}{} ESCAPE '{}'",
1491+
"{} {}LIKE {}{} ESCAPE {}",
14921492
expr,
14931493
if *negated { "NOT " } else { "" },
14941494
if *any { "ANY " } else { "" },
@@ -1513,7 +1513,7 @@ impl fmt::Display for Expr {
15131513
} => match escape_char {
15141514
Some(ch) => write!(
15151515
f,
1516-
"{} {}ILIKE {}{} ESCAPE '{}'",
1516+
"{} {}ILIKE {}{} ESCAPE {}",
15171517
expr,
15181518
if *negated { "NOT " } else { "" },
15191519
if *any { "ANY" } else { "" },
@@ -1568,7 +1568,7 @@ impl fmt::Display for Expr {
15681568
} => match escape_char {
15691569
Some(ch) => write!(
15701570
f,
1571-
"{} {}SIMILAR TO {} ESCAPE '{}'",
1571+
"{} {}SIMILAR TO {} ESCAPE {}",
15721572
expr,
15731573
if *negated { "NOT " } else { "" },
15741574
pattern,

src/parser/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3654,9 +3654,9 @@ impl<'a> Parser<'a> {
36543654
}
36553655

36563656
/// Parse the `ESCAPE CHAR` portion of `LIKE`, `ILIKE`, and `SIMILAR TO`
3657-
pub fn parse_escape_char(&mut self) -> Result<Option<String>, ParserError> {
3657+
pub fn parse_escape_char(&mut self) -> Result<Option<Value>, ParserError> {
36583658
if self.parse_keyword(Keyword::ESCAPE) {
3659-
Ok(Some(self.parse_literal_string()?))
3659+
Ok(Some(self.parse_value()?.into()))
36603660
} else {
36613661
Ok(None)
36623662
}

tests/sqlparser_common.rs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2040,7 +2040,7 @@ fn parse_ilike() {
20402040
pattern: Box::new(Expr::Value(
20412041
(Value::SingleQuotedString("%a".to_string())).with_empty_span()
20422042
)),
2043-
escape_char: Some('^'.to_string()),
2043+
escape_char: Some(Value::SingleQuotedString('^'.to_string())),
20442044
any: false,
20452045
},
20462046
select.selection.unwrap()
@@ -2104,7 +2104,7 @@ fn parse_like() {
21042104
pattern: Box::new(Expr::Value(
21052105
(Value::SingleQuotedString("%a".to_string())).with_empty_span()
21062106
)),
2107-
escape_char: Some('^'.to_string()),
2107+
escape_char: Some(Value::SingleQuotedString('^'.to_string())),
21082108
any: false,
21092109
},
21102110
select.selection.unwrap()
@@ -2167,7 +2167,24 @@ fn parse_similar_to() {
21672167
pattern: Box::new(Expr::Value(
21682168
(Value::SingleQuotedString("%a".to_string())).with_empty_span()
21692169
)),
2170-
escape_char: Some('^'.to_string()),
2170+
escape_char: Some(Value::SingleQuotedString('^'.to_string())),
2171+
},
2172+
select.selection.unwrap()
2173+
);
2174+
2175+
let sql = &format!(
2176+
"SELECT * FROM customers WHERE name {}SIMILAR TO '%a' ESCAPE NULL",
2177+
if negated { "NOT " } else { "" }
2178+
);
2179+
let select = verified_only_select(sql);
2180+
assert_eq!(
2181+
Expr::SimilarTo {
2182+
expr: Box::new(Expr::Identifier(Ident::new("name"))),
2183+
negated,
2184+
pattern: Box::new(Expr::Value(
2185+
(Value::SingleQuotedString("%a".to_string())).with_empty_span()
2186+
)),
2187+
escape_char: Some(Value::Null),
21712188
},
21722189
select.selection.unwrap()
21732190
);
@@ -2185,7 +2202,7 @@ fn parse_similar_to() {
21852202
pattern: Box::new(Expr::Value(
21862203
(Value::SingleQuotedString("%a".to_string())).with_empty_span()
21872204
)),
2188-
escape_char: Some('^'.to_string()),
2205+
escape_char: Some(Value::SingleQuotedString('^'.to_string())),
21892206
})),
21902207
select.selection.unwrap()
21912208
);

0 commit comments

Comments
 (0)