@@ -846,7 +846,12 @@ impl<'a> Parser<'a> {
846846 self . expected ( "NULL or NOT NULL after IS" , self . peek_token ( ) )
847847 }
848848 }
849- Keyword :: NOT | Keyword :: IN | Keyword :: BETWEEN | Keyword :: LIKE | Keyword :: ILIKE => {
849+ Keyword :: NOT
850+ | Keyword :: IN
851+ | Keyword :: BETWEEN
852+ | Keyword :: LIKE
853+ | Keyword :: ILIKE
854+ | Keyword :: SIMILAR => {
850855 self . prev_token ( ) ;
851856 // allow backtracking if parsing IN doesn't work
852857 // https://docs.snowflake.com/en/sql-reference/functions/position.html
@@ -865,8 +870,13 @@ impl<'a> Parser<'a> {
865870 Ok ( ( self . parse_like ( expr, true , negated) ?, true ) )
866871 } else if self . parse_keyword ( Keyword :: ILIKE ) {
867872 Ok ( ( self . parse_like ( expr, false , negated) ?, true ) )
873+ } else if self . parse_keywords ( & [ Keyword :: SIMILAR , Keyword :: TO ] ) {
874+ Ok ( ( self . parse_similar ( expr, negated) ?, true ) )
868875 } else {
869- self . expected ( "IN or BETWEEN or [I]LIKE after NOT" , self . peek_token ( ) )
876+ self . expected (
877+ "IN or BETWEEN or [I]LIKE or SIMILAR TO after NOT" ,
878+ self . peek_token ( ) ,
879+ )
870880 }
871881 }
872882 // Can only happen if `get_next_precedence` got out of sync with this function
@@ -951,6 +961,23 @@ impl<'a> Parser<'a> {
951961 } )
952962 }
953963
964+ /// Parses SIMILAR TO <pattern> [ ESCAPE <escape> ]
965+ /// https://www.postgresql.org/docs/9.0/functions-matching.html#FUNCTIONS-SIMILARTO-REGEXP
966+ pub fn parse_similar ( & mut self , expr : Expr , negated : bool ) -> Result < Expr , ParserError > {
967+ let pat = self . parse_expr ( ) ?;
968+ let esc = if self . parse_keyword ( Keyword :: ESCAPE ) {
969+ Some ( self . parse_expr ( ) ?)
970+ } else {
971+ None
972+ } ;
973+ Ok ( Expr :: Similar {
974+ expr : Box :: new ( expr) ,
975+ pat : Box :: new ( pat) ,
976+ negated,
977+ esc : esc. map ( Box :: new) ,
978+ } )
979+ }
980+
954981 /// Parse a postgresql casting style which is in the form of `expr::datatype`
955982 pub fn parse_pg_cast ( & mut self , expr : Expr ) -> Result < Expr , ParserError > {
956983 Ok ( Expr :: Cast {
@@ -998,7 +1025,8 @@ impl<'a> Parser<'a> {
9981025 Token :: Word ( w)
9991026 if w. keyword == Keyword :: LIKE
10001027 || w. keyword == Keyword :: ILIKE
1001- || w. keyword == Keyword :: RLIKE =>
1028+ || w. keyword == Keyword :: RLIKE
1029+ || w. keyword == Keyword :: SIMILAR =>
10021030 {
10031031 Ok ( Self :: BETWEEN_PREC )
10041032 }
0 commit comments