diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 4d86dd6a6..6770d8689 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -1027,7 +1027,7 @@ pub enum Expr { /// Pattern expression. pattern: Box, /// Optional escape character. - escape_char: Option, + escape_char: Option>, }, /// `ILIKE` (case-insensitive `LIKE`) ILike { @@ -1041,7 +1041,7 @@ pub enum Expr { /// Pattern expression. pattern: Box, /// Optional escape character. - escape_char: Option, + escape_char: Option>, }, /// `SIMILAR TO` regex SimilarTo { @@ -1052,7 +1052,7 @@ pub enum Expr { /// Pattern expression. pattern: Box, /// Optional escape character. - escape_char: Option, + escape_char: Option>, }, /// MySQL: `RLIKE` regex or `REGEXP` regex RLike { diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 6af0fb776..8e2e57f03 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -4237,9 +4237,11 @@ impl<'a> Parser<'a> { } /// Parse the `ESCAPE CHAR` portion of `LIKE`, `ILIKE`, and `SIMILAR TO` - pub fn parse_escape_char(&mut self) -> Result, ParserError> { + pub fn parse_escape_char(&mut self) -> Result>, ParserError> { if self.parse_keyword(Keyword::ESCAPE) { - Ok(Some(self.parse_value()?)) + Ok(Some(Box::new(self.parse_subexpr( + self.dialect.prec_value(Precedence::Like), + )?))) } else { Ok(None) } diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index 5792cf007..f14b68718 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -2341,7 +2341,9 @@ fn parse_ilike() { pattern: Box::new(Expr::Value( (Value::SingleQuotedString("%a".to_string())).with_empty_span() )), - escape_char: Some(Value::SingleQuotedString('^'.to_string()).with_empty_span()), + escape_char: Some(Box::new(Expr::value( + Value::SingleQuotedString('^'.to_string()).with_empty_span(), + ))), any: false, }, select.selection.unwrap() @@ -2405,7 +2407,9 @@ fn parse_like() { pattern: Box::new(Expr::Value( (Value::SingleQuotedString("%a".to_string())).with_empty_span() )), - escape_char: Some(Value::SingleQuotedString('^'.to_string()).with_empty_span()), + escape_char: Some(Box::new(Expr::value( + Value::SingleQuotedString('^'.to_string()).with_empty_span(), + ))), any: false, }, select.selection.unwrap() @@ -2435,6 +2439,11 @@ fn parse_like() { chk(true); } +#[test] +fn parse_like_escape_expression() { + verified_expr("'a%' LIKE 'a#%' ESCAPE ('' || '#')"); +} + #[test] fn parse_similar_to() { fn chk(negated: bool) { @@ -2468,7 +2477,9 @@ fn parse_similar_to() { pattern: Box::new(Expr::Value( (Value::SingleQuotedString("%a".to_string())).with_empty_span() )), - escape_char: Some(Value::SingleQuotedString('^'.to_string()).with_empty_span()), + escape_char: Some(Box::new(Expr::value( + Value::SingleQuotedString('^'.to_string()).with_empty_span(), + ))), }, select.selection.unwrap() ); @@ -2485,7 +2496,7 @@ fn parse_similar_to() { pattern: Box::new(Expr::Value( (Value::SingleQuotedString("%a".to_string())).with_empty_span() )), - escape_char: Some(Value::Null.with_empty_span()), + escape_char: Some(Box::new(Expr::value(Value::Null.with_empty_span()))), }, select.selection.unwrap() ); @@ -2503,7 +2514,9 @@ fn parse_similar_to() { pattern: Box::new(Expr::Value( (Value::SingleQuotedString("%a".to_string())).with_empty_span() )), - escape_char: Some(Value::SingleQuotedString('^'.to_string()).with_empty_span()), + escape_char: Some(Box::new(Expr::value( + Value::SingleQuotedString('^'.to_string()).with_empty_span(), + ))), })), select.selection.unwrap() );