@@ -195,6 +195,7 @@ impl Parser {
195
195
"DATE" => Ok ( ASTNode :: SQLValue ( Value :: Date ( self . parse_literal_string ( ) ?) ) ) ,
196
196
"EXISTS" => self . parse_exists_expression ( ) ,
197
197
"EXTRACT" => self . parse_extract_expression ( ) ,
198
+ "INTERVAL" => self . parse_literal_interval ( ) ,
198
199
"NOT" => Ok ( ASTNode :: SQLUnary {
199
200
operator : SQLOperator :: Not ,
200
201
expr : Box :: new ( self . parse_subexpr ( Self :: UNARY_NOT_PREC ) ?) ,
@@ -425,20 +426,7 @@ impl Parser {
425
426
426
427
pub fn parse_extract_expression ( & mut self ) -> Result < ASTNode , ParserError > {
427
428
self . expect_token ( & Token :: LParen ) ?;
428
- let tok = self . next_token ( ) ;
429
- let field = if let Some ( Token :: SQLWord ( ref k) ) = tok {
430
- match k. keyword . as_ref ( ) {
431
- "YEAR" => SQLDateTimeField :: Year ,
432
- "MONTH" => SQLDateTimeField :: Month ,
433
- "DAY" => SQLDateTimeField :: Day ,
434
- "HOUR" => SQLDateTimeField :: Hour ,
435
- "MINUTE" => SQLDateTimeField :: Minute ,
436
- "SECOND" => SQLDateTimeField :: Second ,
437
- _ => self . expected ( "Date/time field inside of EXTRACT function" , tok) ?,
438
- }
439
- } else {
440
- self . expected ( "Date/time field inside of EXTRACT function" , tok) ?
441
- } ;
429
+ let field = self . parse_date_time_field ( ) ?;
442
430
self . expect_keyword ( "FROM" ) ?;
443
431
let expr = self . parse_expr ( ) ?;
444
432
self . expect_token ( & Token :: RParen ) ?;
@@ -448,6 +436,86 @@ impl Parser {
448
436
} )
449
437
}
450
438
439
+ pub fn parse_date_time_field ( & mut self ) -> Result < SQLDateTimeField , ParserError > {
440
+ let tok = self . next_token ( ) ;
441
+ if let Some ( Token :: SQLWord ( ref k) ) = tok {
442
+ match k. keyword . as_ref ( ) {
443
+ "YEAR" => Ok ( SQLDateTimeField :: Year ) ,
444
+ "MONTH" => Ok ( SQLDateTimeField :: Month ) ,
445
+ "DAY" => Ok ( SQLDateTimeField :: Day ) ,
446
+ "HOUR" => Ok ( SQLDateTimeField :: Hour ) ,
447
+ "MINUTE" => Ok ( SQLDateTimeField :: Minute ) ,
448
+ "SECOND" => Ok ( SQLDateTimeField :: Second ) ,
449
+ _ => self . expected ( "date/time field" , tok) ?,
450
+ }
451
+ } else {
452
+ self . expected ( "date/time field" , tok) ?
453
+ }
454
+ }
455
+
456
+ /// Parse an INTERVAL literal.
457
+ ///
458
+ /// Some syntactically valid intervals:
459
+ ///
460
+ /// 1. `INTERVAL '1' DAY`
461
+ /// 2. `INTERVAL '1-1' YEAR TO MONTH`
462
+ /// 3. `INTERVAL '1' SECOND`
463
+ /// 4. `INTERVAL '1:1:1.1' HOUR (5) TO SECOND (5)`
464
+ /// 5. `INTERVAL '1.1' SECOND (2, 2)`
465
+ /// 6. `INTERVAL '1:1' HOUR (5) TO MINUTE (5)`
466
+ ///
467
+ /// Note that we do not currently attempt to parse the quoted value.
468
+ pub fn parse_literal_interval ( & mut self ) -> Result < ASTNode , ParserError > {
469
+ // The SQL standard allows an optional sign before the value string, but
470
+ // it is not clear if any implementations support that syntax, so we
471
+ // don't currently try to parse it. (The sign can instead be included
472
+ // inside the value string.)
473
+
474
+ // The first token in an interval is a string literal which specifies
475
+ // the duration of the interval.
476
+ let value = self . parse_literal_string ( ) ?;
477
+
478
+ // Following the string literal is a qualifier which indicates the units
479
+ // of the duration specified in the string literal.
480
+ //
481
+ // Note that PostgreSQL allows omitting the qualifier, but we currently
482
+ // require at least the leading field, in accordance with the ANSI spec.
483
+ let leading_field = self . parse_date_time_field ( ) ?;
484
+
485
+ let ( leading_precision, last_field, fsec_precision) =
486
+ if leading_field == SQLDateTimeField :: Second {
487
+ // SQL mandates special syntax for `SECOND TO SECOND` literals.
488
+ // Instead of
489
+ // `SECOND [(<leading precision>)] TO SECOND[(<fractional seconds precision>)]`
490
+ // one must use the special format:
491
+ // `SECOND [( <leading precision> [ , <fractional seconds precision>] )]`
492
+ let last_field = None ;
493
+ let ( leading_precision, fsec_precision) = self . parse_optional_precision_scale ( ) ?;
494
+ ( leading_precision, last_field, fsec_precision)
495
+ } else {
496
+ let leading_precision = self . parse_optional_precision ( ) ?;
497
+ if self . parse_keyword ( "TO" ) {
498
+ let last_field = Some ( self . parse_date_time_field ( ) ?) ;
499
+ let fsec_precision = if last_field == Some ( SQLDateTimeField :: Second ) {
500
+ self . parse_optional_precision ( ) ?
501
+ } else {
502
+ None
503
+ } ;
504
+ ( leading_precision, last_field, fsec_precision)
505
+ } else {
506
+ ( leading_precision, None , None )
507
+ }
508
+ } ;
509
+
510
+ Ok ( ASTNode :: SQLValue ( Value :: Interval {
511
+ value,
512
+ leading_field,
513
+ leading_precision,
514
+ last_field,
515
+ fractional_seconds_precision : fsec_precision,
516
+ } ) )
517
+ }
518
+
451
519
/// Parse an operator following an expression
452
520
pub fn parse_infix ( & mut self , expr : ASTNode , precedence : u8 ) -> Result < ASTNode , ParserError > {
453
521
debug ! ( "parsing infix" ) ;
@@ -1182,6 +1250,10 @@ impl Parser {
1182
1250
}
1183
1251
Ok ( SQLType :: Time )
1184
1252
}
1253
+ // Interval types can be followed by a complicated interval
1254
+ // qualifier that we don't currently support. See
1255
+ // parse_interval_literal for a taste.
1256
+ "INTERVAL" => Ok ( SQLType :: Interval ) ,
1185
1257
"REGCLASS" => Ok ( SQLType :: Regclass ) ,
1186
1258
"TEXT" => {
1187
1259
if self . consume_token ( & Token :: LBracket ) {
0 commit comments