Closed
Description
Describe the bug
In InfluxDB we sometimes create deeply nested queries like this that cause a stack overflow, even in release builds:
To Reproduce
Download: blowout.zip
And run
datafusion-cli -f blowout.sql
This results in
andrewlamb@Andrews-MacBook-Pro Downloads % datafusion-cli -f blowout.sql
datafusion-cli -f blowout.sql
DataFusion CLI v36.0.0
thread 'main' has overflowed its stack
fatal runtime error: stack overflow
The query looks like this
SELECT
(SELECT 1)
UNION ALL (SELECT 1)
UNION ALL (SELECT 1)
UNION ALL (SELECT 1)
.... (works with 2500 clauses, overflow with 3000)
UNION ALL (SELECT 1)
Expected behavior
a runtime error rather than stack overflow. Bonus points if the query actually completed
Additional context
It may be possible to change the treenode recursion to use an iterative approach rather than a recursive one (aka keep a worklist), much as we did in the sql parser to protect against deeply nested expressions
Note it is important to use a release build (as the debug build fails earlier in the process)
In a release build, the stack looks like this:
<alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter 0x000000010372c65c
core::iter::adapters::try_process 0x00000001037aaffc
datafusion_common::tree_node::TreeNode::transform_up 0x0000000103818c4c
<alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter 0x000000010372c684
core::iter::adapters::try_process 0x00000001037aaffc
datafusion_common::tree_node::TreeNode::transform_up 0x0000000103818c4c
<alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter 0x000000010372c684
.... MANY REPEATS ....
datafusion_common::tree_node::TreeNode::transform_up 0x0000000103818c4c
datafusion_optimizer::analyzer::Analyzer::execute_and_check 0x00000001035ed1b0
datafusion::execution::context::SessionState::optimize 0x00000001035e487c
datafusion::dataframe::DataFrame::create_physical_plan::{{closure}} 0x0000000102e35e5c
datafusion_cli::exec::exec_and_print::{{closure}} 0x0000000102e3ffa8
datafusion_cli::exec::exec_from_lines::{{closure}} 0x0000000102e41efc
datafusion_cli::exec::exec_from_files::{{closure}} 0x0000000102e41a38
datafusion_cli::main_inner::{{closure}} 0x0000000102e5d1b4
tokio::runtime::park::CachedParkThread::block_on 0x0000000102e56f64
tokio::runtime::runtime::Runtime::block_on 0x0000000102f72e7c
datafusion_cli::main 0x0000000102f004d0
std::sys_common::backtrace::__rust_begin_short_backtrace 0x0000000102f2c4f0
std::rt::lang_start::{{closure}} 0x0000000102f5b3f0
[Inlined] core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once function.rs:284
[Inlined] std::panicking::try::do_call panicking.rs:552
[Inlined] std::panicking::try panicking.rs:516
[Inlined] std::panic::catch_unwind panic.rs:142
[Inlined] std::rt::lang_start_internal::{{closure}} rt.rs:148
[Inlined] std::panicking::try::do_call panicking.rs:552
[Inlined] std::panicking::try panicking.rs:516
[Inlined] std::panic::catch_unwind panic.rs:142
std::rt::lang_start_internal rt.rs:148
main 0x0000000102f005d8
start 0x00000001825fd0e0