diff --git a/datafusion/sql/src/parser.rs b/datafusion/sql/src/parser.rs index f185d65fa194..ee121a072fa1 100644 --- a/datafusion/sql/src/parser.rs +++ b/datafusion/sql/src/parser.rs @@ -257,6 +257,9 @@ fn ensure_not_set(field: &Option, name: &str) -> Result<(), ParserError> { Ok(()) } +// By default, allow expressions up to this deep before error +const DEFAULT_REMAINING_DEPTH: usize = 100; + /// DataFusion SQL Parser based on [`sqlparser`] /// /// Parses DataFusion's SQL dialect, often delegating to [`sqlparser`]'s [`Parser`]. @@ -287,7 +290,9 @@ impl<'a> DFParser<'a> { let tokens = tokenizer.tokenize()?; Ok(DFParser { - parser: Parser::new(dialect).with_tokens(tokens), + parser: Parser::new(dialect) + .with_recursion_limit(DEFAULT_REMAINING_DEPTH) + .with_tokens(tokens), }) } @@ -299,7 +304,7 @@ impl<'a> DFParser<'a> { } /// Parse a SQL string and produce one or more [`Statement`]s with - /// with the specified dialect. + /// the specified dialect. pub fn parse_sql_with_dialect( sql: &str, dialect: &dyn Dialect, diff --git a/datafusion/sqllogictest/bin/sqllogictests.rs b/datafusion/sqllogictest/bin/sqllogictests.rs index f6b35bf3771c..de7c8b42a765 100644 --- a/datafusion/sqllogictest/bin/sqllogictests.rs +++ b/datafusion/sqllogictest/bin/sqllogictests.rs @@ -52,6 +52,7 @@ const SQLITE_PREFIX: &str = "sqlite"; pub fn main() -> Result<()> { tokio::runtime::Builder::new_multi_thread() .enable_all() + .thread_stack_size(4 * 1024 * 1024) .build()? .block_on(run_tests()) } diff --git a/datafusion/sqllogictest/test_files/errors.slt b/datafusion/sqllogictest/test_files/errors.slt index a153a2e9cecf..9c5d757b4851 100644 --- a/datafusion/sqllogictest/test_files/errors.slt +++ b/datafusion/sqllogictest/test_files/errors.slt @@ -161,3 +161,17 @@ create table records (timestamp timestamp, value float) as values ( '2021-01-01 00:00:00', 1.0, '2021-01-01 00:00:00', 2.0 ); + +# Error number of nested expressions exceeds limit +statement error DataFusion error: SQL error: RecursionLimitExceeded +SELECT + c1 +FROM + aggregate_test_100 +WHERE + c1=0 OR (c2=0 OR (c3=0 OR (c4=0 OR (c5=0 OR (c6=0 OR (c7=0 OR (c8=0 OR (c9=0 OR (c10=0 OR + (c1=1 OR (c2=1 OR (c3=1 OR (c4=1 OR (c5=1 OR (c6=1 OR (c7=1 OR (c8=1 OR (c9=1 OR (c10=1 OR + (c1=2 OR (c2=2 OR (c3=2 OR (c4=2 OR (c5=2 OR (c6=2 OR (c7=2 OR (c8=2 OR (c9=2 OR (c10=2 OR + (c1=3 OR (c2=3 OR (c3=3 OR (c4=3 OR (c5=3 OR (c6=3 OR (c7=3 OR (c8=3 OR (c9=3 OR (c10=3 OR + (c1=4 OR (c2=4 OR (c3=4 OR (c4=4 OR (c5=4 OR (c6=4 OR (c7=4 OR (c8=4 OR (c9=4 OR (c10=4 + )))))))))))))))))))))))))))))))))))))))))))))))));