@@ -1534,7 +1534,7 @@ impl<'a> Parser<'a> {
15341534 let loc = self.peek_token_ref().span.start;
15351535 let opt_expr = self.maybe_parse(|parser| {
15361536 match parser.parse_data_type()? {
1537- DataType::Interval => parser.parse_interval(),
1537+ DataType::Interval { .. } => parser.parse_interval(),
15381538 // PostgreSQL allows almost any identifier to be used as custom data type name,
15391539 // and we support that in `parse_data_type()`. But unlike Postgres we don't
15401540 // have a list of globally reserved keywords (since they vary across dialects),
@@ -10066,10 +10066,18 @@ impl<'a> Parser<'a> {
1006610066 self.parse_optional_precision()?,
1006710067 TimezoneInfo::Tz,
1006810068 )),
10069- // Interval types can be followed by a complicated interval
10070- // qualifier that we don't currently support. See
10071- // parse_interval for a taste.
10072- Keyword::INTERVAL => Ok(DataType::Interval),
10069+ Keyword::INTERVAL => {
10070+ if self.dialect.supports_interval_options() {
10071+ let fields = self.maybe_parse_optional_interval_fields()?;
10072+ let precision = self.parse_optional_precision()?;
10073+ Ok(DataType::Interval { fields, precision })
10074+ } else {
10075+ Ok(DataType::Interval {
10076+ fields: None,
10077+ precision: None,
10078+ })
10079+ }
10080+ }
1007310081 Keyword::JSON => Ok(DataType::JSON),
1007410082 Keyword::JSONB => Ok(DataType::JSONB),
1007510083 Keyword::REGCLASS => Ok(DataType::Regclass),
@@ -11038,6 +11046,85 @@ impl<'a> Parser<'a> {
1103811046 }
1103911047 }
1104011048
11049+ fn maybe_parse_optional_interval_fields(
11050+ &mut self,
11051+ ) -> Result<Option<IntervalFields>, ParserError> {
11052+ match self.parse_one_of_keywords(&[
11053+ // Can be followed by `TO` option
11054+ Keyword::YEAR,
11055+ Keyword::DAY,
11056+ Keyword::HOUR,
11057+ Keyword::MINUTE,
11058+ // No `TO` option
11059+ Keyword::MONTH,
11060+ Keyword::SECOND,
11061+ ]) {
11062+ Some(Keyword::YEAR) => {
11063+ if self.peek_keyword(Keyword::TO) {
11064+ self.expect_keyword(Keyword::TO)?;
11065+ self.expect_keyword(Keyword::MONTH)?;
11066+ Ok(Some(IntervalFields::YearToMonth))
11067+ } else {
11068+ Ok(Some(IntervalFields::Year))
11069+ }
11070+ }
11071+ Some(Keyword::DAY) => {
11072+ if self.peek_keyword(Keyword::TO) {
11073+ self.expect_keyword(Keyword::TO)?;
11074+ match self.expect_one_of_keywords(&[
11075+ Keyword::HOUR,
11076+ Keyword::MINUTE,
11077+ Keyword::SECOND,
11078+ ])? {
11079+ Keyword::HOUR => Ok(Some(IntervalFields::DayToHour)),
11080+ Keyword::MINUTE => Ok(Some(IntervalFields::DayToMinute)),
11081+ Keyword::SECOND => Ok(Some(IntervalFields::DayToSecond)),
11082+ _ => {
11083+ self.prev_token();
11084+ self.expected("HOUR, MINUTE, or SECOND", self.peek_token())
11085+ }
11086+ }
11087+ } else {
11088+ Ok(Some(IntervalFields::Day))
11089+ }
11090+ }
11091+ Some(Keyword::HOUR) => {
11092+ if self.peek_keyword(Keyword::TO) {
11093+ self.expect_keyword(Keyword::TO)?;
11094+ match self.expect_one_of_keywords(&[Keyword::MINUTE, Keyword::SECOND])? {
11095+ Keyword::MINUTE => Ok(Some(IntervalFields::HourToMinute)),
11096+ Keyword::SECOND => Ok(Some(IntervalFields::HourToSecond)),
11097+ _ => {
11098+ self.prev_token();
11099+ self.expected("MINUTE or SECOND", self.peek_token())
11100+ }
11101+ }
11102+ } else {
11103+ Ok(Some(IntervalFields::Hour))
11104+ }
11105+ }
11106+ Some(Keyword::MINUTE) => {
11107+ if self.peek_keyword(Keyword::TO) {
11108+ self.expect_keyword(Keyword::TO)?;
11109+ self.expect_keyword(Keyword::SECOND)?;
11110+ Ok(Some(IntervalFields::MinuteToSecond))
11111+ } else {
11112+ Ok(Some(IntervalFields::Minute))
11113+ }
11114+ }
11115+ Some(Keyword::MONTH) => Ok(Some(IntervalFields::Month)),
11116+ Some(Keyword::SECOND) => Ok(Some(IntervalFields::Second)),
11117+ Some(_) => {
11118+ self.prev_token();
11119+ self.expected(
11120+ "YEAR, MONTH, DAY, HOUR, MINUTE, or SECOND",
11121+ self.peek_token(),
11122+ )
11123+ }
11124+ None => Ok(None),
11125+ }
11126+ }
11127+
1104111128 /// Parse datetime64 [1]
1104211129 /// Syntax
1104311130 /// ```sql
0 commit comments