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