@@ -245,6 +245,58 @@ fn parse_prefix_case_chain(c: &mut Criterion) {
245245 group. finish ( ) ;
246246}
247247
248+ /// Benchmark parsing pathological paren chains that previously caused 2^N
249+ /// work in `parse_table_factor`. The input `SELECT 1 FROM ((((...` rejects
250+ /// at EOF, which used to force exponential backtracking through the chain.
251+ fn parse_table_factor_paren_chain ( c : & mut Criterion ) {
252+ let mut group = c. benchmark_group ( "parse_table_factor_paren_chain" ) ;
253+ let dialect = GenericDialect { } ;
254+
255+ for & n in & [ 10usize , 20 , 30 ] {
256+ let mut sql = String :: from ( "SELECT 1 " ) ;
257+ for _ in 0 ..5 {
258+ sql. push_str ( "FROM " ) ;
259+ sql. push_str ( & "(" . repeat ( n) ) ;
260+ sql. push ( ' ' ) ;
261+ }
262+
263+ group. bench_function ( format ! ( "chain_{n}" ) , |b| {
264+ b. iter ( || {
265+ let _ = Parser :: new ( & dialect)
266+ . with_recursion_limit ( 256 )
267+ . try_with_sql ( std:: hint:: black_box ( & sql) )
268+ . and_then ( |mut p| p. parse_statements ( ) ) ;
269+ } ) ;
270+ } ) ;
271+ }
272+
273+ group. finish ( ) ;
274+ }
275+
276+ /// Benchmark parsing pathological `CAST(CASE (CAST(CASE (...` chains that
277+ /// previously caused 2^N work in `parse_function_args` on dialects with
278+ /// expression-named function arguments (the argument expression was parsed
279+ /// once to detect the named form, then re-parsed on the unnamed path).
280+ fn parse_function_arg_call_chain ( c : & mut Criterion ) {
281+ let mut group = c. benchmark_group ( "parse_function_arg_call_chain" ) ;
282+ let dialect = PostgreSqlDialect { } ;
283+
284+ for & n in & [ 10usize , 20 , 30 ] {
285+ let sql = String :: from ( "SELECT " ) + & "CAST(CASE (" . repeat ( n) + & ")" . repeat ( n) ;
286+
287+ group. bench_function ( format ! ( "chain_{n}" ) , |b| {
288+ b. iter ( || {
289+ let _ = Parser :: new ( & dialect)
290+ . with_recursion_limit ( 256 )
291+ . try_with_sql ( std:: hint:: black_box ( & sql) )
292+ . and_then ( |mut p| p. parse_statements ( ) ) ;
293+ } ) ;
294+ } ) ;
295+ }
296+
297+ group. finish ( ) ;
298+ }
299+
248300criterion_group ! (
249301 benches,
250302 basic_queries,
@@ -253,6 +305,8 @@ criterion_group!(
253305 parse_compound_chain,
254306 parse_compound_keyword_chain,
255307 parse_prefix_keyword_call_chain,
256- parse_prefix_case_chain
308+ parse_prefix_case_chain,
309+ parse_table_factor_paren_chain,
310+ parse_function_arg_call_chain
257311) ;
258312criterion_main ! ( benches) ;
0 commit comments