diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 2d51d4717..d2668d3b7 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -3368,7 +3368,10 @@ impl<'a> Parser<'a> { /// ``` /// /// Note that we do not currently attempt to parse the quoted value. + #[cfg_attr(feature = "recursive-protection", recursive::recursive)] pub fn parse_interval(&mut self) -> Result { + let _guard = self.recursion_counter.try_decrease()?; + // The SQL standard allows an optional sign before the value string, but // it is not clear if any implementations support that syntax, so we // don't currently try to parse it. (The sign can instead be included diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index bad083602..0800bc41f 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -11419,6 +11419,20 @@ fn parse_deeply_nested_subquery_expr_hits_recursion_limits() { assert_eq!(res, Err(ParserError::RecursionLimitExceeded)); } +#[test] +fn parse_deeply_nested_interval_hits_recursion_limits() { + let dialect = GenericDialect {}; + + let sql = format!("SELECT {}1", "INTERVAL ".repeat(1000)); + + let res = Parser::new(&dialect) + .try_with_sql(&sql) + .expect("tokenize to work") + .parse_statements(); + + assert_eq!(res, Err(ParserError::RecursionLimitExceeded)); +} + #[test] fn parse_with_recursion_limit() { let dialect = GenericDialect {};