@@ -109,8 +109,14 @@ pub enum Token {
109
109
RArrow ,
110
110
/// Sharp `#` used for PostgreSQL Bitwise XOR operator
111
111
Sharp ,
112
- /// Tilde `~` used for PostgreSQL Bitwise NOT operator
112
+ /// Tilde `~` used for PostgreSQL Bitwise NOT operator or case sensitive match regular expression operator
113
113
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 ,
114
120
/// `<<`, a bitwise shift left operator in PostgreSQL
115
121
ShiftLeft ,
116
122
/// `>>`, a bitwise shift right operator in PostgreSQL
@@ -172,6 +178,9 @@ impl fmt::Display for Token {
172
178
Token :: ExclamationMark => f. write_str ( "!" ) ,
173
179
Token :: DoubleExclamationMark => f. write_str ( "!!" ) ,
174
180
Token :: Tilde => f. write_str ( "~" ) ,
181
+ Token :: TildeAsterisk => f. write_str ( "~*" ) ,
182
+ Token :: ExclamationMarkTilde => f. write_str ( "!~" ) ,
183
+ Token :: ExclamationMarkTildeAsterisk => f. write_str ( "!~*" ) ,
175
184
Token :: AtSign => f. write_str ( "@" ) ,
176
185
Token :: ShiftLeft => f. write_str ( "<<" ) ,
177
186
Token :: ShiftRight => f. write_str ( ">>" ) ,
@@ -489,6 +498,14 @@ impl<'a> Tokenizer<'a> {
489
498
match chars. peek ( ) {
490
499
Some ( '=' ) => self . consume_and_return ( chars, Token :: Neq ) ,
491
500
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
+ }
492
509
_ => Ok ( Some ( Token :: ExclamationMark ) ) ,
493
510
}
494
511
}
@@ -538,7 +555,13 @@ impl<'a> Tokenizer<'a> {
538
555
comment,
539
556
} ) ) )
540
557
}
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
+ }
542
565
'#' => self . consume_and_return ( chars, Token :: Sharp ) ,
543
566
'@' => self . consume_and_return ( chars, Token :: AtSign ) ,
544
567
other => self . consume_and_return ( chars, Token :: Char ( other) ) ,
@@ -1114,6 +1137,45 @@ mod tests {
1114
1137
compare ( expected, tokens) ;
1115
1138
}
1116
1139
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
+
1117
1179
fn compare ( expected : Vec < Token > , actual : Vec < Token > ) {
1118
1180
//println!("------------------------------");
1119
1181
//println!("tokens = {:?}", actual);
0 commit comments