@@ -289,14 +289,6 @@ impl Parser {
289
289
} )
290
290
}
291
291
292
- /// Parse a postgresql casting style which is in the form of `expr::datatype`
293
- pub fn parse_pg_cast ( & mut self , expr : ASTNode ) -> Result < ASTNode , ParserError > {
294
- Ok ( ASTNode :: SQLCast {
295
- expr : Box :: new ( expr) ,
296
- data_type : self . parse_data_type ( ) ?,
297
- } )
298
- }
299
-
300
292
/// Parse an expression infix (typically an operator)
301
293
pub fn parse_infix ( & mut self , expr : ASTNode , precedence : u8 ) -> Result < ASTNode , ParserError > {
302
294
debug ! ( "parsing infix" ) ;
@@ -308,24 +300,30 @@ impl Parser {
308
300
} else if self . parse_keywords ( vec ! [ "NOT" , "NULL" ] ) {
309
301
Ok ( ASTNode :: SQLIsNotNull ( Box :: new ( expr) ) )
310
302
} else {
311
- parser_err ! ( "Invalid tokens after IS" )
303
+ parser_err ! ( format!(
304
+ "Expected NULL or NOT NULL after IS, found {:?}" ,
305
+ self . peek_token( )
306
+ ) )
312
307
}
313
308
}
314
309
Token :: SQLWord ( ref k) if k. keyword == "NOT" => {
315
- if self . parse_keywords ( vec ! [ "LIKE" ] ) {
310
+ if self . parse_keyword ( "IN" ) {
311
+ self . parse_in ( expr, true )
312
+ } else if self . parse_keyword ( "LIKE" ) {
316
313
Ok ( ASTNode :: SQLBinaryExpr {
317
314
left : Box :: new ( expr) ,
318
315
op : SQLOperator :: NotLike ,
319
316
right : Box :: new ( self . parse_subexpr ( precedence) ?) ,
320
317
} )
321
318
} else {
322
- parser_err ! ( "Invalid tokens after NOT" )
319
+ parser_err ! ( format!(
320
+ "Expected IN or LIKE after NOT, found {:?}" ,
321
+ self . peek_token( )
322
+ ) )
323
323
}
324
324
}
325
- Token :: DoubleColon => {
326
- let pg_cast = self . parse_pg_cast ( expr) ?;
327
- Ok ( pg_cast)
328
- }
325
+ Token :: SQLWord ( ref k) if k. keyword == "IN" => self . parse_in ( expr, false ) ,
326
+ Token :: DoubleColon => self . parse_pg_cast ( expr) ,
329
327
Token :: SQLWord ( _)
330
328
| Token :: Eq
331
329
| Token :: Neq
@@ -350,6 +348,35 @@ impl Parser {
350
348
}
351
349
}
352
350
351
+ /// Parses the parens following the `[ NOT ] IN` operator
352
+ pub fn parse_in ( & mut self , expr : ASTNode , negated : bool ) -> Result < ASTNode , ParserError > {
353
+ self . expect_token ( & Token :: LParen ) ?;
354
+ let in_op = if self . parse_keyword ( "SELECT" ) || self . parse_keyword ( "WITH" ) {
355
+ self . prev_token ( ) ;
356
+ ASTNode :: SQLInSubquery {
357
+ expr : Box :: new ( expr) ,
358
+ subquery : Box :: new ( self . parse_query ( ) ?) ,
359
+ negated,
360
+ }
361
+ } else {
362
+ ASTNode :: SQLInList {
363
+ expr : Box :: new ( expr) ,
364
+ list : self . parse_expr_list ( ) ?,
365
+ negated,
366
+ }
367
+ } ;
368
+ self . expect_token ( & Token :: RParen ) ?;
369
+ Ok ( in_op)
370
+ }
371
+
372
+ /// Parse a postgresql casting style which is in the form of `expr::datatype`
373
+ pub fn parse_pg_cast ( & mut self , expr : ASTNode ) -> Result < ASTNode , ParserError > {
374
+ Ok ( ASTNode :: SQLCast {
375
+ expr : Box :: new ( expr) ,
376
+ data_type : self . parse_data_type ( ) ?,
377
+ } )
378
+ }
379
+
353
380
/// Convert a token operator to an AST operator
354
381
pub fn to_sql_operator ( & self , tok : & Token ) -> Result < SQLOperator , ParserError > {
355
382
match tok {
@@ -390,6 +417,7 @@ impl Parser {
390
417
& Token :: SQLWord ( ref k) if k. keyword == "AND" => Ok ( 10 ) ,
391
418
& Token :: SQLWord ( ref k) if k. keyword == "NOT" => Ok ( 15 ) ,
392
419
& Token :: SQLWord ( ref k) if k. keyword == "IS" => Ok ( 17 ) ,
420
+ & Token :: SQLWord ( ref k) if k. keyword == "IN" => Ok ( 20 ) ,
393
421
& Token :: SQLWord ( ref k) if k. keyword == "LIKE" => Ok ( 20 ) ,
394
422
& Token :: Eq | & Token :: Lt | & Token :: LtEq | & Token :: Neq | & Token :: Gt | & Token :: GtEq => {
395
423
Ok ( 20 )
0 commit comments