Skip to content

Commit 22ab29b

Browse files
Parser: regression test for compound-chain blowup
1 parent 43152a2 commit 22ab29b

1 file changed

Lines changed: 27 additions & 0 deletions

File tree

tests/sqlparser_common.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18977,3 +18977,30 @@ fn parse_non_pg_dialects_keep_xml_names_as_regular_identifiers() {
1897718977
let dialects = all_dialects_except(|d| d.supports_xml_expressions());
1897818978
dialects.verified_only_select("SELECT xml FROM t");
1897918979
}
18980+
18981+
/// Regression test for the 2^N parse-time blowup in `parse_compound_expr` on
18982+
/// inputs like `IF a0.a1...aN.#`. The parse is run on a worker thread and the
18983+
/// main thread asserts that it reports back within a generous timeout. Post-fix
18984+
/// the parser returns `Err` in well under a millisecond, so the timeout is a
18985+
/// hang guard, not a perf threshold.
18986+
#[test]
18987+
fn parse_compound_chain_no_exponential_blowup() {
18988+
use std::sync::mpsc;
18989+
use std::thread;
18990+
use std::time::Duration;
18991+
18992+
let chain: String = (0..30)
18993+
.map(|i| format!("a{i}"))
18994+
.collect::<Vec<_>>()
18995+
.join(".");
18996+
let sql = format!("IF {chain}.#");
18997+
18998+
let (tx, rx) = mpsc::channel();
18999+
thread::spawn(move || {
19000+
let _ = Parser::parse_sql(&GenericDialect {}, &sql);
19001+
let _ = tx.send(());
19002+
});
19003+
19004+
rx.recv_timeout(Duration::from_secs(5))
19005+
.expect("parser should reject this quickly, not loop exponentially");
19006+
}

0 commit comments

Comments
 (0)