diff --git a/src/ast/mod.rs b/src/ast/mod.rs index d2383f2af..77936c2b0 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -115,6 +115,7 @@ where Self: Into, { #[inline(always)] + #[cfg_attr(feature = "recursive-protection", recursive::recursive)] fn convert(value: Self) -> T { Self::into(value) } @@ -4575,9 +4576,17 @@ impl fmt::Display for Statement { "{hivevar}{name} = {l_paren}{value}{r_paren}", hivevar = if *hivevar { "HIVEVAR:" } else { "" }, name = variables, - l_paren = if parenthesized { "(" } else { Default::default() }, + l_paren = if parenthesized { + "(" + } else { + Default::default() + }, value = display_comma_separated(value), - r_paren = if parenthesized { ")" } else { Default::default() }, + r_paren = if parenthesized { + ")" + } else { + Default::default() + }, ) } Statement::SetTimeZone { local, value } => { diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 624b60b3d..97457e2ca 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -2364,8 +2364,7 @@ impl<'a> Parser<'a> { self.expect_token(&Token::LParen)?; let mut trim_where = None; if let Token::Word(word) = self.peek_token().token { - if [Keyword::BOTH, Keyword::LEADING, Keyword::TRAILING].contains(&word.keyword) - { + if [Keyword::BOTH, Keyword::LEADING, Keyword::TRAILING].contains(&word.keyword) { trim_where = Some(self.parse_trim_where()?); } } diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index 3b3b3aeff..499cc0279 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -13348,3 +13348,16 @@ fn parse_range_range_align_to_calculate() { "Expected: end of statement, found: )", ); } + +#[test] +fn convert_to_datafusion_statement_overflow() { + let expr = std::iter::repeat_n("num BETWEEN 0 AND 1", 1000) + .collect::>() + .join(" OR "); + let sql = format!("SELECT num FROM numbers WHERE {expr}"); + + let mut statements = Parser::parse_sql(&GenericDialect {}, sql.as_str()).unwrap(); + let statement = statements.pop().unwrap(); + let df_statement: df_sqlparser::ast::Statement = statement.into(); + assert_eq!(df_statement.to_string(), sql); +} diff --git a/tests/sqlparser_duckdb.rs b/tests/sqlparser_duckdb.rs index c9408c74c..6fa56c2ae 100644 --- a/tests/sqlparser_duckdb.rs +++ b/tests/sqlparser_duckdb.rs @@ -778,7 +778,9 @@ fn parse_use() { for "e in "e_styles { // Test double identifier with different type of quotes assert_eq!( - duckdb().verified_stmt(&format!("USE {quote}CATALOG{quote}.{quote}my_schema{quote}")), + duckdb().verified_stmt(&format!( + "USE {quote}CATALOG{quote}.{quote}my_schema{quote}" + )), Statement::Use(Use::Object(ObjectName(vec![ Ident::with_quote(quote, "CATALOG"), Ident::with_quote(quote, "my_schema") diff --git a/tests/sqlparser_mysql.rs b/tests/sqlparser_mysql.rs index ff1f5e41b..bae724787 100644 --- a/tests/sqlparser_mysql.rs +++ b/tests/sqlparser_mysql.rs @@ -598,8 +598,7 @@ fn parse_use() { for "e in "e_styles { // Test single identifier with different type of quotes assert_eq!( - mysql_and_generic() - .verified_stmt(&format!("USE {quote}{object_name}{quote}")), + mysql_and_generic().verified_stmt(&format!("USE {quote}{object_name}{quote}")), Statement::Use(Use::Object(ObjectName(vec![Ident::with_quote( quote, object_name.to_string(), diff --git a/tests/sqlparser_snowflake.rs b/tests/sqlparser_snowflake.rs index 855d4f394..e2b47d729 100644 --- a/tests/sqlparser_snowflake.rs +++ b/tests/sqlparser_snowflake.rs @@ -2234,9 +2234,7 @@ fn test_snowflake_stage_object_names() { .zip(allowed_object_names.iter_mut()) { let (formatted_name, object_name) = it; - let sql = format!( - "COPY INTO {formatted_name} FROM 'gcs://mybucket/./../a.csv'" - ); + let sql = format!("COPY INTO {formatted_name} FROM 'gcs://mybucket/./../a.csv'"); match snowflake().verified_stmt(&sql) { Statement::CopyIntoSnowflake { into, .. } => { assert_eq!(into.0, object_name.0) @@ -2714,7 +2712,9 @@ fn parse_use() { for "e in "e_styles { // Test double identifier with different type of quotes assert_eq!( - snowflake().verified_stmt(&format!("USE {quote}CATALOG{quote}.{quote}my_schema{quote}")), + snowflake().verified_stmt(&format!( + "USE {quote}CATALOG{quote}.{quote}my_schema{quote}" + )), Statement::Use(Use::Object(ObjectName(vec![ Ident::with_quote(quote, "CATALOG"), Ident::with_quote(quote, "my_schema") @@ -2747,7 +2747,9 @@ fn parse_use() { )]))) ); assert_eq!( - snowflake().verified_stmt(&format!("USE SCHEMA {quote}CATALOG{quote}.{quote}my_schema{quote}")), + snowflake().verified_stmt(&format!( + "USE SCHEMA {quote}CATALOG{quote}.{quote}my_schema{quote}" + )), Statement::Use(Use::Schema(ObjectName(vec![ Ident::with_quote(quote, "CATALOG"), Ident::with_quote(quote, "my_schema")