@@ -208,8 +208,13 @@ impl Parser {
208
208
Token :: Mult => Ok ( ASTNode :: SQLWildcard ) ,
209
209
tok @ Token :: Minus | tok @ Token :: Plus => {
210
210
let p = self . get_precedence ( & tok) ?;
211
+ let operator = if tok == Token :: Plus {
212
+ SQLOperator :: Plus
213
+ } else {
214
+ SQLOperator :: Minus
215
+ } ;
211
216
Ok ( ASTNode :: SQLUnary {
212
- operator : self . to_sql_operator ( & tok ) ? ,
217
+ operator,
213
218
expr : Box :: new ( self . parse_subexpr ( p) ?) ,
214
219
} )
215
220
}
@@ -377,59 +382,75 @@ impl Parser {
377
382
} )
378
383
}
379
384
380
- /// Parse an expression infix (typically an operator)
385
+ /// Parse an operator following an expression
381
386
pub fn parse_infix ( & mut self , expr : ASTNode , precedence : u8 ) -> Result < ASTNode , ParserError > {
382
387
debug ! ( "parsing infix" ) ;
383
- match self . next_token ( ) {
384
- Some ( tok) => match tok {
385
- Token :: SQLWord ( ref k) if k. keyword == "IS" => {
386
- if self . parse_keywords ( vec ! [ "NULL" ] ) {
388
+ let tok = self . next_token ( ) . unwrap ( ) ; // safe as EOF's precedence is the lowest
389
+
390
+ let regular_binary_operator = match tok {
391
+ Token :: Eq => Some ( SQLOperator :: Eq ) ,
392
+ Token :: Neq => Some ( SQLOperator :: NotEq ) ,
393
+ Token :: Gt => Some ( SQLOperator :: Gt ) ,
394
+ Token :: GtEq => Some ( SQLOperator :: GtEq ) ,
395
+ Token :: Lt => Some ( SQLOperator :: Lt ) ,
396
+ Token :: LtEq => Some ( SQLOperator :: LtEq ) ,
397
+ Token :: Plus => Some ( SQLOperator :: Plus ) ,
398
+ Token :: Minus => Some ( SQLOperator :: Minus ) ,
399
+ Token :: Mult => Some ( SQLOperator :: Multiply ) ,
400
+ Token :: Mod => Some ( SQLOperator :: Modulus ) ,
401
+ Token :: Div => Some ( SQLOperator :: Divide ) ,
402
+ Token :: SQLWord ( ref k) => match k. keyword . as_ref ( ) {
403
+ "AND" => Some ( SQLOperator :: And ) ,
404
+ "OR" => Some ( SQLOperator :: Or ) ,
405
+ "LIKE" => Some ( SQLOperator :: Like ) ,
406
+ "NOT" => {
407
+ if self . parse_keyword ( "LIKE" ) {
408
+ Some ( SQLOperator :: NotLike )
409
+ } else {
410
+ None
411
+ }
412
+ }
413
+ _ => None ,
414
+ } ,
415
+ _ => None ,
416
+ } ;
417
+
418
+ if let Some ( op) = regular_binary_operator {
419
+ Ok ( ASTNode :: SQLBinaryExpr {
420
+ left : Box :: new ( expr) ,
421
+ op,
422
+ right : Box :: new ( self . parse_subexpr ( precedence) ?) ,
423
+ } )
424
+ } else if let Token :: SQLWord ( ref k) = tok {
425
+ match k. keyword . as_ref ( ) {
426
+ "IS" => {
427
+ if self . parse_keyword ( "NULL" ) {
387
428
Ok ( ASTNode :: SQLIsNull ( Box :: new ( expr) ) )
388
429
} else if self . parse_keywords ( vec ! [ "NOT" , "NULL" ] ) {
389
430
Ok ( ASTNode :: SQLIsNotNull ( Box :: new ( expr) ) )
390
431
} else {
391
432
self . expected ( "NULL or NOT NULL after IS" , self . peek_token ( ) )
392
433
}
393
434
}
394
- Token :: SQLWord ( ref k) if k. keyword == "NOT" => {
435
+ "NOT" | "IN" | "BETWEEN" => {
436
+ self . prev_token ( ) ;
437
+ let negated = self . parse_keyword ( "NOT" ) ;
395
438
if self . parse_keyword ( "IN" ) {
396
- self . parse_in ( expr, true )
439
+ self . parse_in ( expr, negated )
397
440
} else if self . parse_keyword ( "BETWEEN" ) {
398
- self . parse_between ( expr, true )
399
- } else if self . parse_keyword ( "LIKE" ) {
400
- Ok ( ASTNode :: SQLBinaryExpr {
401
- left : Box :: new ( expr) ,
402
- op : SQLOperator :: NotLike ,
403
- right : Box :: new ( self . parse_subexpr ( precedence) ?) ,
404
- } )
441
+ self . parse_between ( expr, negated)
405
442
} else {
406
- self . expected ( "BETWEEN, IN or LIKE after NOT" , self . peek_token ( ) )
443
+ panic ! ( )
407
444
}
408
445
}
409
- Token :: SQLWord ( ref k) if k. keyword == "IN" => self . parse_in ( expr, false ) ,
410
- Token :: SQLWord ( ref k) if k. keyword == "BETWEEN" => self . parse_between ( expr, false ) ,
411
- Token :: DoubleColon => self . parse_pg_cast ( expr) ,
412
- Token :: SQLWord ( _)
413
- | Token :: Eq
414
- | Token :: Neq
415
- | Token :: Gt
416
- | Token :: GtEq
417
- | Token :: Lt
418
- | Token :: LtEq
419
- | Token :: Plus
420
- | Token :: Minus
421
- | Token :: Mult
422
- | Token :: Mod
423
- | Token :: Div => Ok ( ASTNode :: SQLBinaryExpr {
424
- left : Box :: new ( expr) ,
425
- op : self . to_sql_operator ( & tok) ?,
426
- right : Box :: new ( self . parse_subexpr ( precedence) ?) ,
427
- } ) ,
428
- _ => parser_err ! ( format!( "No infix parser for token {:?}" , tok) ) ,
429
- } ,
430
- // This is not supposed to happen, because of the precedence check
431
- // in parse_subexpr.
432
- None => parser_err ! ( "Unexpected EOF in parse_infix" ) ,
446
+ // Can only happen if `get_precedence` got out of sync with this function
447
+ _ => panic ! ( "No infix parser for token {:?}" , tok) ,
448
+ }
449
+ } else if Token :: DoubleColon == tok {
450
+ self . parse_pg_cast ( expr)
451
+ } else {
452
+ // Can only happen if `get_precedence` got out of sync with this function
453
+ panic ! ( "No infix parser for token {:?}" , tok)
433
454
}
434
455
}
435
456
@@ -475,28 +496,6 @@ impl Parser {
475
496
} )
476
497
}
477
498
478
- /// Convert a token operator to an AST operator
479
- pub fn to_sql_operator ( & self , tok : & Token ) -> Result < SQLOperator , ParserError > {
480
- match tok {
481
- Token :: Eq => Ok ( SQLOperator :: Eq ) ,
482
- Token :: Neq => Ok ( SQLOperator :: NotEq ) ,
483
- Token :: Lt => Ok ( SQLOperator :: Lt ) ,
484
- Token :: LtEq => Ok ( SQLOperator :: LtEq ) ,
485
- Token :: Gt => Ok ( SQLOperator :: Gt ) ,
486
- Token :: GtEq => Ok ( SQLOperator :: GtEq ) ,
487
- Token :: Plus => Ok ( SQLOperator :: Plus ) ,
488
- Token :: Minus => Ok ( SQLOperator :: Minus ) ,
489
- Token :: Mult => Ok ( SQLOperator :: Multiply ) ,
490
- Token :: Div => Ok ( SQLOperator :: Divide ) ,
491
- Token :: Mod => Ok ( SQLOperator :: Modulus ) ,
492
- Token :: SQLWord ( ref k) if k. keyword == "AND" => Ok ( SQLOperator :: And ) ,
493
- Token :: SQLWord ( ref k) if k. keyword == "OR" => Ok ( SQLOperator :: Or ) ,
494
- //Token::SQLWord(ref k) if k.keyword == "NOT" => Ok(SQLOperator::Not),
495
- Token :: SQLWord ( ref k) if k. keyword == "LIKE" => Ok ( SQLOperator :: Like ) ,
496
- _ => parser_err ! ( format!( "Unsupported SQL operator {:?}" , tok) ) ,
497
- }
498
- }
499
-
500
499
/// Get the precedence of the next token
501
500
pub fn get_next_precedence ( & self ) -> Result < u8 , ParserError > {
502
501
if let Some ( token) = self . peek_token ( ) {
0 commit comments