File tree 4 files changed +60
-1
lines changed
4 files changed +60
-1
lines changed Original file line number Diff line number Diff line change @@ -139,6 +139,11 @@ pub enum BinaryOperator {
139
139
DuckIntegerDivide ,
140
140
/// MySQL [`DIV`](https://dev.mysql.com/doc/refman/8.0/en/arithmetic-functions.html) integer division
141
141
MyIntegerDivide ,
142
+ /// MATCH operator, e.g. `a MATCH b` (SQLite-specific)
143
+ /// See <https://www.sqlite.org/lang_expr.html#the_like_glob_regexp_match_and_extract_operators>
144
+ Match ,
145
+ /// REGEXP operator, e.g. `a REGEXP b` (SQLite-specific)
146
+ Regexp ,
142
147
/// Support for custom operators (such as Postgres custom operators)
143
148
Custom ( String ) ,
144
149
/// Bitwise XOR, e.g. `a # b` (PostgreSQL-specific)
@@ -350,6 +355,8 @@ impl fmt::Display for BinaryOperator {
350
355
BinaryOperator :: BitwiseXor => f. write_str ( "^" ) ,
351
356
BinaryOperator :: DuckIntegerDivide => f. write_str ( "//" ) ,
352
357
BinaryOperator :: MyIntegerDivide => f. write_str ( "DIV" ) ,
358
+ BinaryOperator :: Match => f. write_str ( "MATCH" ) ,
359
+ BinaryOperator :: Regexp => f. write_str ( "REGEXP" ) ,
353
360
BinaryOperator :: Custom ( s) => f. write_str ( s) ,
354
361
BinaryOperator :: PGBitwiseXor => f. write_str ( "#" ) ,
355
362
BinaryOperator :: PGBitwiseShiftLeft => f. write_str ( "<<" ) ,
Original file line number Diff line number Diff line change @@ -619,6 +619,7 @@ pub trait Dialect: Debug + Any {
619
619
Token :: Word ( w) if w. keyword == Keyword :: ILIKE => Ok ( p ! ( Like ) ) ,
620
620
Token :: Word ( w) if w. keyword == Keyword :: RLIKE => Ok ( p ! ( Like ) ) ,
621
621
Token :: Word ( w) if w. keyword == Keyword :: REGEXP => Ok ( p ! ( Like ) ) ,
622
+ Token :: Word ( w) if w. keyword == Keyword :: MATCH => Ok ( p ! ( Like ) ) ,
622
623
Token :: Word ( w) if w. keyword == Keyword :: SIMILAR => Ok ( p ! ( Like ) ) ,
623
624
_ => Ok ( self . prec_unknown ( ) ) ,
624
625
} ,
@@ -630,6 +631,7 @@ pub trait Dialect: Debug + Any {
630
631
Token :: Word ( w) if w. keyword == Keyword :: ILIKE => Ok ( p ! ( Like ) ) ,
631
632
Token :: Word ( w) if w. keyword == Keyword :: RLIKE => Ok ( p ! ( Like ) ) ,
632
633
Token :: Word ( w) if w. keyword == Keyword :: REGEXP => Ok ( p ! ( Like ) ) ,
634
+ Token :: Word ( w) if w. keyword == Keyword :: MATCH => Ok ( p ! ( Like ) ) ,
633
635
Token :: Word ( w) if w. keyword == Keyword :: SIMILAR => Ok ( p ! ( Like ) ) ,
634
636
Token :: Word ( w) if w. keyword == Keyword :: OPERATOR => Ok ( p ! ( Between ) ) ,
635
637
Token :: Word ( w) if w. keyword == Keyword :: DIV => Ok ( p ! ( MulDivModOp ) ) ,
Original file line number Diff line number Diff line change 15
15
// specific language governing permissions and limitations
16
16
// under the License.
17
17
18
- use crate :: ast:: Statement ;
18
+ use crate :: ast:: BinaryOperator ;
19
+ use crate :: ast:: { Expr , Statement } ;
19
20
use crate :: dialect:: Dialect ;
20
21
use crate :: keywords:: Keyword ;
21
22
use crate :: parser:: { Parser , ParserError } ;
@@ -70,6 +71,27 @@ impl Dialect for SQLiteDialect {
70
71
}
71
72
}
72
73
74
+ fn parse_infix (
75
+ & self ,
76
+ parser : & mut crate :: parser:: Parser ,
77
+ expr : & crate :: ast:: Expr ,
78
+ _precedence : u8 ,
79
+ ) -> Option < Result < crate :: ast:: Expr , ParserError > > {
80
+ // Parse MATCH and REGEXP as operators
81
+ // See <https://www.sqlite.org/lang_expr.html#the_like_glob_regexp_match_and_extract_operators>
82
+ for ( keyword, op) in [
83
+ ( Keyword :: REGEXP , BinaryOperator :: Regexp ) ,
84
+ ( Keyword :: MATCH , BinaryOperator :: Match ) ,
85
+ ] {
86
+ if parser. parse_keyword ( keyword) {
87
+ let left = Box :: new ( expr. clone ( ) ) ;
88
+ let right = Box :: new ( parser. parse_expr ( ) . unwrap ( ) ) ;
89
+ return Some ( Ok ( Expr :: BinaryOp { left, op, right } ) ) ;
90
+ }
91
+ }
92
+ None
93
+ }
94
+
73
95
fn supports_in_empty_list ( & self ) -> bool {
74
96
true
75
97
}
Original file line number Diff line number Diff line change @@ -562,6 +562,34 @@ fn test_dollar_identifier_as_placeholder() {
562
562
}
563
563
}
564
564
565
+ #[ test]
566
+ fn test_match_operator ( ) {
567
+ assert_eq ! (
568
+ sqlite( ) . verified_expr( "col MATCH 'pattern'" ) ,
569
+ Expr :: BinaryOp {
570
+ op: BinaryOperator :: Match ,
571
+ left: Box :: new( Expr :: Identifier ( Ident :: new( "col" ) ) ) ,
572
+ right: Box :: new( Expr :: Value (
573
+ ( Value :: SingleQuotedString ( "pattern" . to_string( ) ) ) . with_empty_span( )
574
+ ) )
575
+ }
576
+ ) ;
577
+ }
578
+
579
+ #[ test]
580
+ fn test_regexp_operator ( ) {
581
+ assert_eq ! (
582
+ sqlite( ) . verified_expr( "col REGEXP 'pattern'" ) ,
583
+ Expr :: BinaryOp {
584
+ op: BinaryOperator :: Regexp ,
585
+ left: Box :: new( Expr :: Identifier ( Ident :: new( "col" ) ) ) ,
586
+ right: Box :: new( Expr :: Value (
587
+ ( Value :: SingleQuotedString ( "pattern" . to_string( ) ) ) . with_empty_span( )
588
+ ) )
589
+ }
590
+ ) ;
591
+ }
592
+
565
593
fn sqlite ( ) -> TestedDialects {
566
594
TestedDialects :: new ( vec ! [ Box :: new( SQLiteDialect { } ) ] )
567
595
}
You can’t perform that action at this time.
0 commit comments