Skip to content

Commit 852b4e4

Browse files
yoavcloudayman-sigma
authored andcommitted
Add support for NULL escape char in pattern match searches (apache#1913)
1 parent 7913e2c commit 852b4e4

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
@@ -832,7 +832,7 @@ pub enum Expr {
832832
any: bool,
833833
expr: Box<Expr>,
834834
pattern: Box<Expr>,
835-
escape_char: Option<String>,
835+
escape_char: Option<Value>,
836836
},
837837
/// `ILIKE` (case-insensitive `LIKE`)
838838
ILike {
@@ -842,14 +842,14 @@ pub enum Expr {
842842
any: bool,
843843
expr: Box<Expr>,
844844
pattern: Box<Expr>,
845-
escape_char: Option<String>,
845+
escape_char: Option<Value>,
846846
},
847847
/// SIMILAR TO regex
848848
SimilarTo {
849849
negated: bool,
850850
expr: Box<Expr>,
851851
pattern: Box<Expr>,
852-
escape_char: Option<String>,
852+
escape_char: Option<Value>,
853853
},
854854
/// MySQL: RLIKE regex or REGEXP regex
855855
RLike {
@@ -1522,7 +1522,7 @@ impl fmt::Display for Expr {
15221522
} => match escape_char {
15231523
Some(ch) => write!(
15241524
f,
1525-
"{} {}LIKE {}{} ESCAPE '{}'",
1525+
"{} {}LIKE {}{} ESCAPE {}",
15261526
expr,
15271527
if *negated { "NOT " } else { "" },
15281528
if *any { "ANY " } else { "" },
@@ -1547,7 +1547,7 @@ impl fmt::Display for Expr {
15471547
} => match escape_char {
15481548
Some(ch) => write!(
15491549
f,
1550-
"{} {}ILIKE {}{} ESCAPE '{}'",
1550+
"{} {}ILIKE {}{} ESCAPE {}",
15511551
expr,
15521552
if *negated { "NOT " } else { "" },
15531553
if *any { "ANY" } else { "" },
@@ -1602,7 +1602,7 @@ impl fmt::Display for Expr {
16021602
} => match escape_char {
16031603
Some(ch) => write!(
16041604
f,
1605-
"{} {}SIMILAR TO {} ESCAPE '{}'",
1605+
"{} {}SIMILAR TO {} ESCAPE {}",
16061606
expr,
16071607
if *negated { "NOT " } else { "" },
16081608
pattern,

src/parser/mod.rs

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

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

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)