Skip to content

Commit 9445897

Browse files
committed
Merge remote-tracking branch 'apache/main' into reduce-token-cloning
2 parents 56c070b + 024a878 commit 9445897

32 files changed

+1699
-863
lines changed

Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,18 @@ name = "sqlparser"
3737
path = "src/lib.rs"
3838

3939
[features]
40-
default = ["std"]
40+
default = ["std", "recursive-protection"]
4141
std = []
42+
recursive-protection = ["std", "recursive"]
4243
# Enable JSON output in the `cli` example:
4344
json_example = ["serde_json", "serde"]
4445
visitor = ["sqlparser_derive"]
4546

4647
[dependencies]
4748
bigdecimal = { version = "0.4.1", features = ["serde"], optional = true }
4849
log = "0.4"
50+
recursive = { version = "0.1.1", optional = true}
51+
4952
serde = { version = "1.0", features = ["derive"], optional = true }
5053
# serde_json is only used in examples/cli, but we have to put it outside
5154
# of dev-dependencies because of

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ The following optional [crate features](https://doc.rust-lang.org/cargo/referen
6363

6464
* `serde`: Adds [Serde](https://serde.rs/) support by implementing `Serialize` and `Deserialize` for all AST nodes.
6565
* `visitor`: Adds a `Visitor` capable of recursively walking the AST tree.
66-
66+
* `recursive-protection` (enabled by default), uses [recursive](https://docs.rs/recursive/latest/recursive/) for stack overflow protection.
6767

6868
## Syntax vs Semantics
6969

derive/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,10 @@ fn derive_visit(input: proc_macro::TokenStream, visit_type: &VisitType) -> proc_
7878

7979
let expanded = quote! {
8080
// The generated impl.
81+
// Note that it uses [`recursive::recursive`] to protect from stack overflow.
82+
// See tests in https://github.com/apache/datafusion-sqlparser-rs/pull/1522/ for more info.
8183
impl #impl_generics sqlparser::ast::#visit_trait for #name #ty_generics #where_clause {
84+
#[cfg_attr(feature = "recursive-protection", recursive::recursive)]
8285
fn visit<V: sqlparser::ast::#visitor_trait>(
8386
&#modifier self,
8487
visitor: &mut V

sqlparser_bench/benches/sqlparser_bench.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,46 @@ fn basic_queries(c: &mut Criterion) {
4242
group.bench_function("sqlparser::with_select", |b| {
4343
b.iter(|| Parser::parse_sql(&dialect, with_query).unwrap());
4444
});
45+
46+
let large_statement = {
47+
let expressions = (0..1000)
48+
.map(|n| format!("FN_{}(COL_{})", n, n))
49+
.collect::<Vec<_>>()
50+
.join(", ");
51+
let tables = (0..1000)
52+
.map(|n| format!("TABLE_{}", n))
53+
.collect::<Vec<_>>()
54+
.join(" JOIN ");
55+
let where_condition = (0..1000)
56+
.map(|n| format!("COL_{} = {}", n, n))
57+
.collect::<Vec<_>>()
58+
.join(" OR ");
59+
let order_condition = (0..1000)
60+
.map(|n| format!("COL_{} DESC", n))
61+
.collect::<Vec<_>>()
62+
.join(", ");
63+
64+
format!(
65+
"SELECT {} FROM {} WHERE {} ORDER BY {}",
66+
expressions, tables, where_condition, order_condition
67+
)
68+
};
69+
70+
group.bench_function("parse_large_statement", |b| {
71+
b.iter(|| Parser::parse_sql(&dialect, criterion::black_box(large_statement.as_str())));
72+
});
73+
74+
let large_statement = Parser::parse_sql(&dialect, large_statement.as_str())
75+
.unwrap()
76+
.pop()
77+
.unwrap();
78+
79+
group.bench_function("format_large_statement", |b| {
80+
b.iter(|| {
81+
let formatted_query = large_statement.to_string();
82+
assert_eq!(formatted_query, large_statement);
83+
});
84+
});
4585
}
4686

4787
criterion_group!(benches, basic_queries);

src/ast/data_type.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ pub enum DataType {
254254
/// [postgresql]: https://www.postgresql.org/docs/15/datatype.html
255255
Float8,
256256
/// Double
257-
Double,
257+
Double(ExactNumberInfo),
258258
/// Double PRECISION e.g. [standard], [postgresql]
259259
///
260260
/// [standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#approximate-numeric-type
@@ -373,6 +373,10 @@ pub enum DataType {
373373
///
374374
/// [postgresql]: https://www.postgresql.org/docs/current/plpgsql-trigger.html
375375
Trigger,
376+
/// Any data type, used in BigQuery UDF definitions for templated parameters
377+
///
378+
/// [bigquery]: https://cloud.google.com/bigquery/docs/user-defined-functions#templated-sql-udf-parameters
379+
AnyType,
376380
}
377381

378382
impl fmt::Display for DataType {
@@ -383,7 +387,6 @@ impl fmt::Display for DataType {
383387
DataType::CharacterVarying(size) => {
384388
format_character_string_type(f, "CHARACTER VARYING", size)
385389
}
386-
387390
DataType::CharVarying(size) => format_character_string_type(f, "CHAR VARYING", size),
388391
DataType::Varchar(size) => format_character_string_type(f, "VARCHAR", size),
389392
DataType::Nvarchar(size) => format_character_string_type(f, "NVARCHAR", size),
@@ -505,7 +508,7 @@ impl fmt::Display for DataType {
505508
DataType::Float4 => write!(f, "FLOAT4"),
506509
DataType::Float32 => write!(f, "Float32"),
507510
DataType::Float64 => write!(f, "FLOAT64"),
508-
DataType::Double => write!(f, "DOUBLE"),
511+
DataType::Double(info) => write!(f, "DOUBLE{info}"),
509512
DataType::Float8 => write!(f, "FLOAT8"),
510513
DataType::DoublePrecision => write!(f, "DOUBLE PRECISION"),
511514
DataType::Bool => write!(f, "BOOL"),
@@ -626,6 +629,7 @@ impl fmt::Display for DataType {
626629
}
627630
DataType::Unspecified => Ok(()),
628631
DataType::Trigger => write!(f, "TRIGGER"),
632+
DataType::AnyType => write!(f, "ANY TYPE"),
629633
}
630634
}
631635
}

src/ast/ddl.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -885,12 +885,14 @@ impl fmt::Display for TableConstraint {
885885
} => {
886886
write!(
887887
f,
888-
"{}FOREIGN KEY ({}) REFERENCES {}({})",
888+
"{}FOREIGN KEY ({}) REFERENCES {}",
889889
display_constraint_name(name),
890890
display_comma_separated(columns),
891891
foreign_table,
892-
display_comma_separated(referred_columns),
893892
)?;
893+
if !referred_columns.is_empty() {
894+
write!(f, "({})", display_comma_separated(referred_columns))?;
895+
}
894896
if let Some(action) = on_delete {
895897
write!(f, " ON DELETE {action}")?;
896898
}

0 commit comments

Comments
 (0)