@@ -108,8 +108,14 @@ pub enum Token {
108
108
RArrow ,
109
109
/// Sharp `#` used for PostgreSQL Bitwise XOR operator
110
110
Sharp ,
111
- /// Tilde `~` used for PostgreSQL Bitwise NOT operator
111
+ /// Tilde `~` used for PostgreSQL Bitwise NOT operator or case sensitive match regular operator
112
112
Tilde ,
113
+ /// `~*` , a case insensitive match regular operator in PostgreSQL
114
+ TildeAsterisk ,
115
+ /// `!~` , a case sensitive not match regular operator in PostgreSQL
116
+ ExclamationMarkTilde ,
117
+ /// `!~*` , a case insensitive not match regular operator in PostgreSQL
118
+ ExclamationMarkTildeAsterisk ,
113
119
/// `<<`, a bitwise shift left operator in PostgreSQL
114
120
ShiftLeft ,
115
121
/// `>>`, a bitwise shift right operator in PostgreSQL
@@ -171,6 +177,9 @@ impl fmt::Display for Token {
171
177
Token :: ExclamationMark => f. write_str ( "!" ) ,
172
178
Token :: DoubleExclamationMark => f. write_str ( "!!" ) ,
173
179
Token :: Tilde => f. write_str ( "~" ) ,
180
+ Token :: TildeAsterisk => f. write_str ( "~*" ) ,
181
+ Token :: ExclamationMarkTilde => f. write_str ( "!~" ) ,
182
+ Token :: ExclamationMarkTildeAsterisk => f. write_str ( "!~*" ) ,
174
183
Token :: AtSign => f. write_str ( "@" ) ,
175
184
Token :: ShiftLeft => f. write_str ( "<<" ) ,
176
185
Token :: ShiftRight => f. write_str ( ">>" ) ,
@@ -486,6 +495,14 @@ impl<'a> Tokenizer<'a> {
486
495
match chars. peek ( ) {
487
496
Some ( '=' ) => self . consume_and_return ( chars, Token :: Neq ) ,
488
497
Some ( '!' ) => self . consume_and_return ( chars, Token :: DoubleExclamationMark ) ,
498
+ Some ( '~' ) => {
499
+ chars. next ( ) ;
500
+ match chars. peek ( ) {
501
+ Some ( '*' ) => self
502
+ . consume_and_return ( chars, Token :: ExclamationMarkTildeAsterisk ) ,
503
+ _ => Ok ( Some ( Token :: ExclamationMarkTilde ) ) ,
504
+ }
505
+ }
489
506
_ => Ok ( Some ( Token :: ExclamationMark ) ) ,
490
507
}
491
508
}
@@ -535,7 +552,13 @@ impl<'a> Tokenizer<'a> {
535
552
comment,
536
553
} ) ) )
537
554
}
538
- '~' => self . consume_and_return ( chars, Token :: Tilde ) ,
555
+ '~' => {
556
+ chars. next ( ) ; // consume
557
+ match chars. peek ( ) {
558
+ Some ( '*' ) => self . consume_and_return ( chars, Token :: TildeAsterisk ) ,
559
+ _ => Ok ( Some ( Token :: Tilde ) ) ,
560
+ }
561
+ }
539
562
'#' => self . consume_and_return ( chars, Token :: Sharp ) ,
540
563
'@' => self . consume_and_return ( chars, Token :: AtSign ) ,
541
564
other => self . consume_and_return ( chars, Token :: Char ( other) ) ,
@@ -1111,6 +1134,45 @@ mod tests {
1111
1134
compare ( expected, tokens) ;
1112
1135
}
1113
1136
1137
+ #[ test]
1138
+ fn tokenize_pg_regex_match ( ) {
1139
+ let sql = "SELECT col ~ '^a', col ~* '^a', col !~ '^a', col !~* '^a'" ;
1140
+ let dialect = GenericDialect { } ;
1141
+ let mut tokenizer = Tokenizer :: new ( & dialect, sql) ;
1142
+ let tokens = tokenizer. tokenize ( ) . unwrap ( ) ;
1143
+ let expected = vec ! [
1144
+ Token :: make_keyword( "SELECT" ) ,
1145
+ Token :: Whitespace ( Whitespace :: Space ) ,
1146
+ Token :: make_word( "col" , None ) ,
1147
+ Token :: Whitespace ( Whitespace :: Space ) ,
1148
+ Token :: Tilde ,
1149
+ Token :: Whitespace ( Whitespace :: Space ) ,
1150
+ Token :: SingleQuotedString ( "^a" . into( ) ) ,
1151
+ Token :: Comma ,
1152
+ Token :: Whitespace ( Whitespace :: Space ) ,
1153
+ Token :: make_word( "col" , None ) ,
1154
+ Token :: Whitespace ( Whitespace :: Space ) ,
1155
+ Token :: TildeAsterisk ,
1156
+ Token :: Whitespace ( Whitespace :: Space ) ,
1157
+ Token :: SingleQuotedString ( "^a" . into( ) ) ,
1158
+ Token :: Comma ,
1159
+ Token :: Whitespace ( Whitespace :: Space ) ,
1160
+ Token :: make_word( "col" , None ) ,
1161
+ Token :: Whitespace ( Whitespace :: Space ) ,
1162
+ Token :: ExclamationMarkTilde ,
1163
+ Token :: Whitespace ( Whitespace :: Space ) ,
1164
+ Token :: SingleQuotedString ( "^a" . into( ) ) ,
1165
+ Token :: Comma ,
1166
+ Token :: Whitespace ( Whitespace :: Space ) ,
1167
+ Token :: make_word( "col" , None ) ,
1168
+ Token :: Whitespace ( Whitespace :: Space ) ,
1169
+ Token :: ExclamationMarkTildeAsterisk ,
1170
+ Token :: Whitespace ( Whitespace :: Space ) ,
1171
+ Token :: SingleQuotedString ( "^a" . into( ) ) ,
1172
+ ] ;
1173
+ compare ( expected, tokens) ;
1174
+ }
1175
+
1114
1176
fn compare ( expected : Vec < Token > , actual : Vec < Token > ) {
1115
1177
//println!("------------------------------");
1116
1178
//println!("tokens = {:?}", actual);
0 commit comments