diff --git a/Cargo.toml b/Cargo.toml index 99546465b..96c708a80 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,7 +38,7 @@ path = "src/lib.rs" [features] default = ["std"] -std = [] +std = ["stacker"] # Enable JSON output in the `cli` example: json_example = ["serde_json", "serde"] visitor = ["sqlparser_derive"] @@ -48,10 +48,11 @@ bigdecimal = { version = "0.4.1", features = ["serde"], optional = true } log = "0.4" serde = { version = "1.0", features = ["derive"], optional = true } # serde_json is only used in examples/cli, but we have to put it outside -# of dev-dependencies because of +# dev-dependencies because of # https://github.com/rust-lang/cargo/issues/1596 serde_json = { version = "1.0", optional = true } sqlparser_derive = { version = "0.2.0", path = "derive", optional = true } +stacker = { version = "0.1.17", optional = true } [dev-dependencies] simple_logger = "5.0" diff --git a/src/parser/mod.rs b/src/parser/mod.rs index cd9be1d8f..20d6e61ab 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -65,6 +65,14 @@ mod recursion { use super::ParserError; + /// try to grow stack + fn maybe_grow() { + #[cfg(debug_assertions)] + stacker::maybe_grow(512 << 10, 8 << 20, || {}); + #[cfg(not(debug_assertions))] + stacker::maybe_grow(128 << 10, 2 << 20, || {}); + } + /// Tracks remaining recursion depth. This value is decremented on /// each call to [`RecursionCounter::try_decrease()`], when it reaches 0 an error will /// be returned. @@ -93,10 +101,12 @@ mod recursion { /// remaining depth upon drop; pub fn try_decrease(&self) -> Result { let old_value = self.remaining_depth.get(); - // ran out of space + if old_value == 0 { Err(ParserError::RecursionLimitExceeded) } else { + maybe_grow(); + self.remaining_depth.set(old_value - 1); Ok(DepthGuard::new(Rc::clone(&self.remaining_depth))) }