Skip to content

Commit e4c5500

Browse files
Fixed overflow error, recursion counter was not included for parenthesis (apache#2199)
1 parent bc55b37 commit e4c5500

File tree

3 files changed

+14
-6
lines changed

3 files changed

+14
-6
lines changed

src/parser/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13268,6 +13268,7 @@ impl<'a> Parser<'a> {
1326813268
/// preceded with some `WITH` CTE declarations and optionally followed
1326913269
/// by `ORDER BY`. Unlike some other parse_... methods, this one doesn't
1327013270
/// expect the initial keyword to be already consumed
13271+
#[cfg_attr(feature = "recursive-protection", recursive::recursive)]
1327113272
pub fn parse_query(&mut self) -> Result<Box<Query>, ParserError> {
1327213273
let _guard = self.recursion_counter.try_decrease()?;
1327313274
let with = if self.parse_keyword(Keyword::WITH) {
@@ -15118,7 +15119,9 @@ impl<'a> Parser<'a> {
1511815119
}
1511915120

1512015121
/// A table name or a parenthesized subquery, followed by optional `[AS] alias`
15122+
#[cfg_attr(feature = "recursive-protection", recursive::recursive)]
1512115123
pub fn parse_table_factor(&mut self) -> Result<TableFactor, ParserError> {
15124+
let _guard = self.recursion_counter.try_decrease()?;
1512215125
if self.parse_keyword(Keyword::LATERAL) {
1512315126
// LATERAL must always be followed by a subquery or table function.
1512415127
if self.consume_token(&Token::LParen) {

tests/sqlparser_common.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11020,6 +11020,13 @@ fn parse_deeply_nested_parens_hits_recursion_limits() {
1102011020
assert_eq!(ParserError::RecursionLimitExceeded, res.unwrap_err());
1102111021
}
1102211022

11023+
#[test]
11024+
fn parse_update_deeply_nested_parens_hits_recursion_limits() {
11025+
let sql = format!("\nUPDATE\n\n\n\n\n\n\n\n\n\n{}", "(".repeat(1000));
11026+
let res = parse_sql_statements(&sql);
11027+
assert_eq!(ParserError::RecursionLimitExceeded, res.unwrap_err());
11028+
}
11029+
1102311030
#[test]
1102411031
fn parse_deeply_nested_unary_op_hits_recursion_limits() {
1102511032
let sql = format!("SELECT {}", "+".repeat(1000));

tests/sqlparser_snowflake.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3202,21 +3202,19 @@ fn parse_view_column_descriptions() {
32023202

32033203
#[test]
32043204
fn test_parentheses_overflow() {
3205-
// TODO: increase / improve after we fix the recursion limit
3206-
// for real (see https://github.com/apache/datafusion-sqlparser-rs/issues/984)
32073205
let max_nesting_level: usize = 25;
32083206

3209-
// Verify the recursion check is not too wasteful... (num of parentheses - 2 is acceptable)
3210-
let slack = 2;
3207+
// Verify the recursion check is not too wasteful (num of parentheses within budget)
3208+
let slack = 3;
32113209
let l_parens = "(".repeat(max_nesting_level - slack);
32123210
let r_parens = ")".repeat(max_nesting_level - slack);
32133211
let sql = format!("SELECT * FROM {l_parens}a.b.c{r_parens}");
32143212
let parsed =
32153213
snowflake_with_recursion_limit(max_nesting_level).parse_sql_statements(sql.as_str());
32163214
assert_eq!(parsed.err(), None);
32173215

3218-
// Verify the recursion check triggers... (num of parentheses - 1 is acceptable)
3219-
let slack = 1;
3216+
// Verify the recursion check triggers (one more paren exceeds the budget)
3217+
let slack = 2;
32203218
let l_parens = "(".repeat(max_nesting_level - slack);
32213219
let r_parens = ")".repeat(max_nesting_level - slack);
32223220
let sql = format!("SELECT * FROM {l_parens}a.b.c{r_parens}");

0 commit comments

Comments
 (0)