Skip to content

Commit df6fcca

Browse files
authored
Merge pull request #18 from kemingy/v0.54.x
fix: add recursive protection to Convert
2 parents 76f17c3 + b88168d commit df6fcca

File tree

6 files changed

+36
-12
lines changed

6 files changed

+36
-12
lines changed

src/ast/mod.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ where
115115
Self: Into<T>,
116116
{
117117
#[inline(always)]
118+
#[cfg_attr(feature = "recursive-protection", recursive::recursive)]
118119
fn convert(value: Self) -> T {
119120
Self::into(value)
120121
}
@@ -4575,9 +4576,17 @@ impl fmt::Display for Statement {
45754576
"{hivevar}{name} = {l_paren}{value}{r_paren}",
45764577
hivevar = if *hivevar { "HIVEVAR:" } else { "" },
45774578
name = variables,
4578-
l_paren = if parenthesized { "(" } else { Default::default() },
4579+
l_paren = if parenthesized {
4580+
"("
4581+
} else {
4582+
Default::default()
4583+
},
45794584
value = display_comma_separated(value),
4580-
r_paren = if parenthesized { ")" } else { Default::default() },
4585+
r_paren = if parenthesized {
4586+
")"
4587+
} else {
4588+
Default::default()
4589+
},
45814590
)
45824591
}
45834592
Statement::SetTimeZone { local, value } => {

src/parser/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2364,8 +2364,7 @@ impl<'a> Parser<'a> {
23642364
self.expect_token(&Token::LParen)?;
23652365
let mut trim_where = None;
23662366
if let Token::Word(word) = self.peek_token().token {
2367-
if [Keyword::BOTH, Keyword::LEADING, Keyword::TRAILING].contains(&word.keyword)
2368-
{
2367+
if [Keyword::BOTH, Keyword::LEADING, Keyword::TRAILING].contains(&word.keyword) {
23692368
trim_where = Some(self.parse_trim_where()?);
23702369
}
23712370
}

tests/sqlparser_common.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13348,3 +13348,16 @@ fn parse_range_range_align_to_calculate() {
1334813348
"Expected: end of statement, found: )",
1334913349
);
1335013350
}
13351+
13352+
#[test]
13353+
fn convert_to_datafusion_statement_overflow() {
13354+
let expr = std::iter::repeat_n("num BETWEEN 0 AND 1", 1000)
13355+
.collect::<Vec<_>>()
13356+
.join(" OR ");
13357+
let sql = format!("SELECT num FROM numbers WHERE {expr}");
13358+
13359+
let mut statements = Parser::parse_sql(&GenericDialect {}, sql.as_str()).unwrap();
13360+
let statement = statements.pop().unwrap();
13361+
let df_statement: df_sqlparser::ast::Statement = statement.into();
13362+
assert_eq!(df_statement.to_string(), sql);
13363+
}

tests/sqlparser_duckdb.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -778,7 +778,9 @@ fn parse_use() {
778778
for &quote in &quote_styles {
779779
// Test double identifier with different type of quotes
780780
assert_eq!(
781-
duckdb().verified_stmt(&format!("USE {quote}CATALOG{quote}.{quote}my_schema{quote}")),
781+
duckdb().verified_stmt(&format!(
782+
"USE {quote}CATALOG{quote}.{quote}my_schema{quote}"
783+
)),
782784
Statement::Use(Use::Object(ObjectName(vec![
783785
Ident::with_quote(quote, "CATALOG"),
784786
Ident::with_quote(quote, "my_schema")

tests/sqlparser_mysql.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -598,8 +598,7 @@ fn parse_use() {
598598
for &quote in &quote_styles {
599599
// Test single identifier with different type of quotes
600600
assert_eq!(
601-
mysql_and_generic()
602-
.verified_stmt(&format!("USE {quote}{object_name}{quote}")),
601+
mysql_and_generic().verified_stmt(&format!("USE {quote}{object_name}{quote}")),
603602
Statement::Use(Use::Object(ObjectName(vec![Ident::with_quote(
604603
quote,
605604
object_name.to_string(),

tests/sqlparser_snowflake.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2234,9 +2234,7 @@ fn test_snowflake_stage_object_names() {
22342234
.zip(allowed_object_names.iter_mut())
22352235
{
22362236
let (formatted_name, object_name) = it;
2237-
let sql = format!(
2238-
"COPY INTO {formatted_name} FROM 'gcs://mybucket/./../a.csv'"
2239-
);
2237+
let sql = format!("COPY INTO {formatted_name} FROM 'gcs://mybucket/./../a.csv'");
22402238
match snowflake().verified_stmt(&sql) {
22412239
Statement::CopyIntoSnowflake { into, .. } => {
22422240
assert_eq!(into.0, object_name.0)
@@ -2714,7 +2712,9 @@ fn parse_use() {
27142712
for &quote in &quote_styles {
27152713
// Test double identifier with different type of quotes
27162714
assert_eq!(
2717-
snowflake().verified_stmt(&format!("USE {quote}CATALOG{quote}.{quote}my_schema{quote}")),
2715+
snowflake().verified_stmt(&format!(
2716+
"USE {quote}CATALOG{quote}.{quote}my_schema{quote}"
2717+
)),
27182718
Statement::Use(Use::Object(ObjectName(vec![
27192719
Ident::with_quote(quote, "CATALOG"),
27202720
Ident::with_quote(quote, "my_schema")
@@ -2747,7 +2747,9 @@ fn parse_use() {
27472747
)])))
27482748
);
27492749
assert_eq!(
2750-
snowflake().verified_stmt(&format!("USE SCHEMA {quote}CATALOG{quote}.{quote}my_schema{quote}")),
2750+
snowflake().verified_stmt(&format!(
2751+
"USE SCHEMA {quote}CATALOG{quote}.{quote}my_schema{quote}"
2752+
)),
27512753
Statement::Use(Use::Schema(ObjectName(vec![
27522754
Ident::with_quote(quote, "CATALOG"),
27532755
Ident::with_quote(quote, "my_schema")

0 commit comments

Comments
 (0)