@@ -194,6 +194,7 @@ impl Parser {
194
194
"DATE" => Ok ( ASTNode :: SQLValue ( Value :: Date ( self . parse_literal_string ( ) ?) ) ) ,
195
195
"EXISTS" => self . parse_exists_expression ( ) ,
196
196
"EXTRACT" => self . parse_extract_expression ( ) ,
197
+ "INTERVAL" => self . parse_literal_interval ( ) ,
197
198
"NOT" => Ok ( ASTNode :: SQLUnary {
198
199
operator : SQLOperator :: Not ,
199
200
expr : Box :: new ( self . parse_subexpr ( Self :: UNARY_NOT_PREC ) ?) ,
@@ -421,20 +422,7 @@ impl Parser {
421
422
422
423
pub fn parse_extract_expression ( & mut self ) -> Result < ASTNode , ParserError > {
423
424
self . expect_token ( & Token :: LParen ) ?;
424
- let tok = self . next_token ( ) ;
425
- let field = if let Some ( Token :: SQLWord ( ref k) ) = tok {
426
- match k. keyword . as_ref ( ) {
427
- "YEAR" => SQLDateTimeField :: Year ,
428
- "MONTH" => SQLDateTimeField :: Month ,
429
- "DAY" => SQLDateTimeField :: Day ,
430
- "HOUR" => SQLDateTimeField :: Hour ,
431
- "MINUTE" => SQLDateTimeField :: Minute ,
432
- "SECOND" => SQLDateTimeField :: Second ,
433
- _ => self . expected ( "Date/time field inside of EXTRACT function" , tok) ?,
434
- }
435
- } else {
436
- self . expected ( "Date/time field inside of EXTRACT function" , tok) ?
437
- } ;
425
+ let field = self . parse_date_time_field ( ) ?;
438
426
self . expect_keyword ( "FROM" ) ?;
439
427
let expr = self . parse_expr ( ) ?;
440
428
self . expect_token ( & Token :: RParen ) ?;
@@ -444,6 +432,100 @@ impl Parser {
444
432
} )
445
433
}
446
434
435
+ pub fn parse_date_time_field ( & mut self ) -> Result < SQLDateTimeField , ParserError > {
436
+ let tok = self . next_token ( ) ;
437
+ if let Some ( Token :: SQLWord ( ref k) ) = tok {
438
+ match k. keyword . as_ref ( ) {
439
+ "YEAR" => Ok ( SQLDateTimeField :: Year ) ,
440
+ "MONTH" => Ok ( SQLDateTimeField :: Month ) ,
441
+ "DAY" => Ok ( SQLDateTimeField :: Day ) ,
442
+ "HOUR" => Ok ( SQLDateTimeField :: Hour ) ,
443
+ "MINUTE" => Ok ( SQLDateTimeField :: Minute ) ,
444
+ "SECOND" => Ok ( SQLDateTimeField :: Second ) ,
445
+ _ => self . expected ( "date/time field" , tok) ?,
446
+ }
447
+ } else {
448
+ self . expected ( "date/time field" , tok) ?
449
+ }
450
+ }
451
+
452
+ /// Parse an INTERVAL literal.
453
+ ///
454
+ /// Some valid intervals:
455
+ /// 1. `INTERVAL '1' DAY`
456
+ /// 2. `INTERVAL '1-1' YEAR TO MONTH`
457
+ /// 3. `INTERVAL '1' SECONDS`
458
+ /// 4. `INTERVAL '1:1:1.1' HOUR (5) TO SECONDS (5)`
459
+ /// 5. `INTERVAL '1.1` SECONDS (2, 2)`
460
+ /// 6. `INTERVAL '1:1' HOUR (5) TO MINUTE (5)`
461
+ /// 7. `INTERVAL '1:1' SECOND TO SECOND`
462
+ ///
463
+ /// Note that (6) is not technically standards compliant, as the only
464
+ /// end qualifier which can specify a precision is `SECOND`. (7) is also
465
+ /// not standards compliant, as `SECOND` is not permitted to appear as a
466
+ /// start qualifier, except in the special form of (5). In the interest of
467
+ /// sanity, for the time being, we accept all the forms listed above.
468
+ pub fn parse_literal_interval ( & mut self ) -> Result < ASTNode , ParserError > {
469
+ // The first token in an interval is a string literal which specifies
470
+ // the duration of the interval.
471
+ let value = self . parse_literal_string ( ) ?;
472
+
473
+ // Following the string literal is a qualifier which indicates the units
474
+ // of the duration specified in the string literal.
475
+ let start_field = self . parse_date_time_field ( ) ?;
476
+
477
+ // The start qualifier is optionally followed by a numeric precision.
478
+ // If the the start qualifier has the same units as the end qualifier,
479
+ // we'll actually get *two* precisions here, for both the start and the
480
+ // end.
481
+ let ( start_precision, end_precision) = if self . consume_token ( & Token :: LParen ) {
482
+ let start_precision = Some ( self . parse_literal_uint ( ) ?) ;
483
+ let end_precision = if self . consume_token ( & Token :: Comma ) {
484
+ Some ( self . parse_literal_uint ( ) ?)
485
+ } else {
486
+ None
487
+ } ;
488
+ self . expect_token ( & Token :: RParen ) ?;
489
+ ( start_precision, end_precision)
490
+ } else {
491
+ ( None , None )
492
+ } ;
493
+
494
+ // The start qualifier is optionally followed by an end qualifier.
495
+ let ( end_field, end_precision) = if self . parse_keyword ( "TO" ) {
496
+ if end_precision. is_some ( ) {
497
+ // This is an interval like `INTERVAL '1' HOUR (2, 2) TO MINUTE (3)`.
498
+ // We've already seen the end precision, so allowing an explicit
499
+ // end qualifier would raise the question of which to keep.
500
+ // Note that while technically `INTERVAL '1:1' HOUR (2, 2) TO MINUTE`
501
+ // is unambiguous, it is extremely confusing and non-standard,
502
+ // so just reject it.
503
+ return parser_err ! ( "Cannot use dual-precision syntax with TO in INTERVAL literal" ) ;
504
+ }
505
+ (
506
+ self . parse_date_time_field ( ) ?,
507
+ self . parse_optional_precision ( ) ?,
508
+ )
509
+ } else {
510
+ // If no end qualifier is specified, use the values from the start
511
+ // qualifier. Note that we might have an explicit end precision even
512
+ // if we don't have an explicit start field.
513
+ ( start_field. clone ( ) , end_precision. or ( start_precision) )
514
+ } ;
515
+
516
+ Ok ( ASTNode :: SQLValue ( Value :: Interval {
517
+ value,
518
+ start_qualifier : SQLIntervalQualifier {
519
+ field : start_field,
520
+ precision : start_precision,
521
+ } ,
522
+ end_qualifier : SQLIntervalQualifier {
523
+ field : end_field,
524
+ precision : end_precision,
525
+ } ,
526
+ } ) )
527
+ }
528
+
447
529
/// Parse an operator following an expression
448
530
pub fn parse_infix ( & mut self , expr : ASTNode , precedence : u8 ) -> Result < ASTNode , ParserError > {
449
531
debug ! ( "parsing infix" ) ;
@@ -1151,6 +1233,7 @@ impl Parser {
1151
1233
}
1152
1234
Ok ( SQLType :: Time )
1153
1235
}
1236
+ "INTERVAL" => Ok ( SQLType :: Interval ) ,
1154
1237
"REGCLASS" => Ok ( SQLType :: Regclass ) ,
1155
1238
"TEXT" => {
1156
1239
if self . consume_token ( & Token :: LBracket ) {
0 commit comments