@@ -109,8 +109,14 @@ pub enum Token {
109109 RArrow ,
110110 /// Sharp `#` used for PostgreSQL Bitwise XOR operator
111111 Sharp ,
112- /// Tilde `~` used for PostgreSQL Bitwise NOT operator
112+ /// Tilde `~` used for PostgreSQL Bitwise NOT operator or case sensitive match regular expression operator
113113 Tilde ,
114+ /// `~*` , a case insensitive match regular expression operator in PostgreSQL
115+ TildeAsterisk ,
116+ /// `!~` , a case sensitive not match regular expression operator in PostgreSQL
117+ ExclamationMarkTilde ,
118+ /// `!~*` , a case insensitive not match regular expression operator in PostgreSQL
119+ ExclamationMarkTildeAsterisk ,
114120 /// `<<`, a bitwise shift left operator in PostgreSQL
115121 ShiftLeft ,
116122 /// `>>`, a bitwise shift right operator in PostgreSQL
@@ -172,6 +178,9 @@ impl fmt::Display for Token {
172178 Token :: ExclamationMark => f. write_str ( "!" ) ,
173179 Token :: DoubleExclamationMark => f. write_str ( "!!" ) ,
174180 Token :: Tilde => f. write_str ( "~" ) ,
181+ Token :: TildeAsterisk => f. write_str ( "~*" ) ,
182+ Token :: ExclamationMarkTilde => f. write_str ( "!~" ) ,
183+ Token :: ExclamationMarkTildeAsterisk => f. write_str ( "!~*" ) ,
175184 Token :: AtSign => f. write_str ( "@" ) ,
176185 Token :: ShiftLeft => f. write_str ( "<<" ) ,
177186 Token :: ShiftRight => f. write_str ( ">>" ) ,
@@ -489,6 +498,14 @@ impl<'a> Tokenizer<'a> {
489498 match chars. peek ( ) {
490499 Some ( '=' ) => self . consume_and_return ( chars, Token :: Neq ) ,
491500 Some ( '!' ) => self . consume_and_return ( chars, Token :: DoubleExclamationMark ) ,
501+ Some ( '~' ) => {
502+ chars. next ( ) ;
503+ match chars. peek ( ) {
504+ Some ( '*' ) => self
505+ . consume_and_return ( chars, Token :: ExclamationMarkTildeAsterisk ) ,
506+ _ => Ok ( Some ( Token :: ExclamationMarkTilde ) ) ,
507+ }
508+ }
492509 _ => Ok ( Some ( Token :: ExclamationMark ) ) ,
493510 }
494511 }
@@ -538,7 +555,13 @@ impl<'a> Tokenizer<'a> {
538555 comment,
539556 } ) ) )
540557 }
541- '~' => self . consume_and_return ( chars, Token :: Tilde ) ,
558+ '~' => {
559+ chars. next ( ) ; // consume
560+ match chars. peek ( ) {
561+ Some ( '*' ) => self . consume_and_return ( chars, Token :: TildeAsterisk ) ,
562+ _ => Ok ( Some ( Token :: Tilde ) ) ,
563+ }
564+ }
542565 '#' => self . consume_and_return ( chars, Token :: Sharp ) ,
543566 '@' => self . consume_and_return ( chars, Token :: AtSign ) ,
544567 other => self . consume_and_return ( chars, Token :: Char ( other) ) ,
@@ -1114,6 +1137,45 @@ mod tests {
11141137 compare ( expected, tokens) ;
11151138 }
11161139
1140+ #[ test]
1141+ fn tokenize_pg_regex_match ( ) {
1142+ let sql = "SELECT col ~ '^a', col ~* '^a', col !~ '^a', col !~* '^a'" ;
1143+ let dialect = GenericDialect { } ;
1144+ let mut tokenizer = Tokenizer :: new ( & dialect, sql) ;
1145+ let tokens = tokenizer. tokenize ( ) . unwrap ( ) ;
1146+ let expected = vec ! [
1147+ Token :: make_keyword( "SELECT" ) ,
1148+ Token :: Whitespace ( Whitespace :: Space ) ,
1149+ Token :: make_word( "col" , None ) ,
1150+ Token :: Whitespace ( Whitespace :: Space ) ,
1151+ Token :: Tilde ,
1152+ Token :: Whitespace ( Whitespace :: Space ) ,
1153+ Token :: SingleQuotedString ( "^a" . into( ) ) ,
1154+ Token :: Comma ,
1155+ Token :: Whitespace ( Whitespace :: Space ) ,
1156+ Token :: make_word( "col" , None ) ,
1157+ Token :: Whitespace ( Whitespace :: Space ) ,
1158+ Token :: TildeAsterisk ,
1159+ Token :: Whitespace ( Whitespace :: Space ) ,
1160+ Token :: SingleQuotedString ( "^a" . into( ) ) ,
1161+ Token :: Comma ,
1162+ Token :: Whitespace ( Whitespace :: Space ) ,
1163+ Token :: make_word( "col" , None ) ,
1164+ Token :: Whitespace ( Whitespace :: Space ) ,
1165+ Token :: ExclamationMarkTilde ,
1166+ Token :: Whitespace ( Whitespace :: Space ) ,
1167+ Token :: SingleQuotedString ( "^a" . into( ) ) ,
1168+ Token :: Comma ,
1169+ Token :: Whitespace ( Whitespace :: Space ) ,
1170+ Token :: make_word( "col" , None ) ,
1171+ Token :: Whitespace ( Whitespace :: Space ) ,
1172+ Token :: ExclamationMarkTildeAsterisk ,
1173+ Token :: Whitespace ( Whitespace :: Space ) ,
1174+ Token :: SingleQuotedString ( "^a" . into( ) ) ,
1175+ ] ;
1176+ compare ( expected, tokens) ;
1177+ }
1178+
11171179 fn compare ( expected : Vec < Token > , actual : Vec < Token > ) {
11181180 //println!("------------------------------");
11191181 //println!("tokens = {:?}", actual);
0 commit comments