@@ -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),
@@ -10097,10 +10097,18 @@ impl<'a> Parser<'a> {
1009710097 self.parse_optional_precision()?,
1009810098 TimezoneInfo::Tz,
1009910099 )),
10100- // Interval types can be followed by a complicated interval
10101- // qualifier that we don't currently support. See
10102- // parse_interval for a taste.
10103- Keyword::INTERVAL => Ok(DataType::Interval),
10100+ Keyword::INTERVAL => {
10101+ if self.dialect.supports_interval_options() {
10102+ let fields = self.maybe_parse_optional_interval_fields()?;
10103+ let precision = self.parse_optional_precision()?;
10104+ Ok(DataType::Interval { fields, precision })
10105+ } else {
10106+ Ok(DataType::Interval {
10107+ fields: None,
10108+ precision: None,
10109+ })
10110+ }
10111+ }
1010410112 Keyword::JSON => Ok(DataType::JSON),
1010510113 Keyword::JSONB => Ok(DataType::JSONB),
1010610114 Keyword::REGCLASS => Ok(DataType::Regclass),
@@ -11069,6 +11077,85 @@ impl<'a> Parser<'a> {
1106911077 }
1107011078 }
1107111079
11080+ fn maybe_parse_optional_interval_fields(
11081+ &mut self,
11082+ ) -> Result<Option<IntervalFields>, ParserError> {
11083+ match self.parse_one_of_keywords(&[
11084+ // Can be followed by `TO` option
11085+ Keyword::YEAR,
11086+ Keyword::DAY,
11087+ Keyword::HOUR,
11088+ Keyword::MINUTE,
11089+ // No `TO` option
11090+ Keyword::MONTH,
11091+ Keyword::SECOND,
11092+ ]) {
11093+ Some(Keyword::YEAR) => {
11094+ if self.peek_keyword(Keyword::TO) {
11095+ self.expect_keyword(Keyword::TO)?;
11096+ self.expect_keyword(Keyword::MONTH)?;
11097+ Ok(Some(IntervalFields::YearToMonth))
11098+ } else {
11099+ Ok(Some(IntervalFields::Year))
11100+ }
11101+ }
11102+ Some(Keyword::DAY) => {
11103+ if self.peek_keyword(Keyword::TO) {
11104+ self.expect_keyword(Keyword::TO)?;
11105+ match self.expect_one_of_keywords(&[
11106+ Keyword::HOUR,
11107+ Keyword::MINUTE,
11108+ Keyword::SECOND,
11109+ ])? {
11110+ Keyword::HOUR => Ok(Some(IntervalFields::DayToHour)),
11111+ Keyword::MINUTE => Ok(Some(IntervalFields::DayToMinute)),
11112+ Keyword::SECOND => Ok(Some(IntervalFields::DayToSecond)),
11113+ _ => {
11114+ self.prev_token();
11115+ self.expected("HOUR, MINUTE, or SECOND", self.peek_token())
11116+ }
11117+ }
11118+ } else {
11119+ Ok(Some(IntervalFields::Day))
11120+ }
11121+ }
11122+ Some(Keyword::HOUR) => {
11123+ if self.peek_keyword(Keyword::TO) {
11124+ self.expect_keyword(Keyword::TO)?;
11125+ match self.expect_one_of_keywords(&[Keyword::MINUTE, Keyword::SECOND])? {
11126+ Keyword::MINUTE => Ok(Some(IntervalFields::HourToMinute)),
11127+ Keyword::SECOND => Ok(Some(IntervalFields::HourToSecond)),
11128+ _ => {
11129+ self.prev_token();
11130+ self.expected("MINUTE or SECOND", self.peek_token())
11131+ }
11132+ }
11133+ } else {
11134+ Ok(Some(IntervalFields::Hour))
11135+ }
11136+ }
11137+ Some(Keyword::MINUTE) => {
11138+ if self.peek_keyword(Keyword::TO) {
11139+ self.expect_keyword(Keyword::TO)?;
11140+ self.expect_keyword(Keyword::SECOND)?;
11141+ Ok(Some(IntervalFields::MinuteToSecond))
11142+ } else {
11143+ Ok(Some(IntervalFields::Minute))
11144+ }
11145+ }
11146+ Some(Keyword::MONTH) => Ok(Some(IntervalFields::Month)),
11147+ Some(Keyword::SECOND) => Ok(Some(IntervalFields::Second)),
11148+ Some(_) => {
11149+ self.prev_token();
11150+ self.expected(
11151+ "YEAR, MONTH, DAY, HOUR, MINUTE, or SECOND",
11152+ self.peek_token(),
11153+ )
11154+ }
11155+ None => Ok(None),
11156+ }
11157+ }
11158+
1107211159 /// Parse datetime64 [1]
1107311160 /// Syntax
1107411161 /// ```sql
0 commit comments