Skip to content

Commit ced7473

Browse files
committed
make recursive optional
1 parent bfabd48 commit ced7473

File tree

17 files changed

+50
-51
lines changed

17 files changed

+50
-51
lines changed

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,6 @@ pbjson = { version = "0.7.0" }
143143
prost = "0.13.1"
144144
prost-derive = "0.13.1"
145145
rand = "0.8"
146-
recursive = "0.1.1"
147146
regex = "1.8"
148147
rstest = "0.23.0"
149148
serde_json = "1"

datafusion-cli/Cargo.lock

Lines changed: 0 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

datafusion/common/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ avro = ["apache-avro"]
4040
backtrace = []
4141
pyarrow = ["pyo3", "arrow/pyarrow", "parquet"]
4242
force_hash_collisions = []
43+
recursive-protection = ["recursive"]
4344

4445
[dependencies]
4546
ahash = { workspace = true }
@@ -61,7 +62,7 @@ object_store = { workspace = true, optional = true }
6162
parquet = { workspace = true, optional = true, default-features = true }
6263
paste = "1.0.15"
6364
pyo3 = { version = "0.22.0", optional = true }
64-
recursive = { workspace = true }
65+
recursive = { version = "0.1.1", optional = true }
6566
sqlparser = { workspace = true }
6667
tokio = { workspace = true }
6768

datafusion/common/src/tree_node.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
//! [`TreeNode`] for visiting and rewriting expression and plan trees
1919
2020
use crate::Result;
21-
use recursive::recursive;
2221
use std::collections::HashMap;
2322
use std::hash::Hash;
2423
use std::sync::Arc;
@@ -125,7 +124,7 @@ pub trait TreeNode: Sized {
125124
/// TreeNodeVisitor::f_up(ChildNode2)
126125
/// TreeNodeVisitor::f_up(ParentNode)
127126
/// ```
128-
#[recursive]
127+
#[cfg_attr(feature = "recursive-protection", recursive::recursive)]
129128
fn visit<'n, V: TreeNodeVisitor<'n, Node = Self>>(
130129
&'n self,
131130
visitor: &mut V,
@@ -175,7 +174,7 @@ pub trait TreeNode: Sized {
175174
/// TreeNodeRewriter::f_up(ChildNode2)
176175
/// TreeNodeRewriter::f_up(ParentNode)
177176
/// ```
178-
#[recursive]
177+
#[cfg_attr(feature = "recursive-protection", recursive::recursive)]
179178
fn rewrite<R: TreeNodeRewriter<Node = Self>>(
180179
self,
181180
rewriter: &mut R,
@@ -198,7 +197,7 @@ pub trait TreeNode: Sized {
198197
&'n self,
199198
mut f: F,
200199
) -> Result<TreeNodeRecursion> {
201-
#[recursive]
200+
#[cfg_attr(feature = "recursive-protection", recursive::recursive)]
202201
fn apply_impl<'n, N: TreeNode, F: FnMut(&'n N) -> Result<TreeNodeRecursion>>(
203202
node: &'n N,
204203
f: &mut F,
@@ -233,7 +232,7 @@ pub trait TreeNode: Sized {
233232
self,
234233
mut f: F,
235234
) -> Result<Transformed<Self>> {
236-
#[recursive]
235+
#[cfg_attr(feature = "recursive-protection", recursive::recursive)]
237236
fn transform_down_impl<N: TreeNode, F: FnMut(N) -> Result<Transformed<N>>>(
238237
node: N,
239238
f: &mut F,
@@ -257,7 +256,7 @@ pub trait TreeNode: Sized {
257256
self,
258257
mut f: F,
259258
) -> Result<Transformed<Self>> {
260-
#[recursive]
259+
#[cfg_attr(feature = "recursive-protection", recursive::recursive)]
261260
fn transform_up_impl<N: TreeNode, F: FnMut(N) -> Result<Transformed<N>>>(
262261
node: N,
263262
f: &mut F,
@@ -372,7 +371,7 @@ pub trait TreeNode: Sized {
372371
mut f_down: FD,
373372
mut f_up: FU,
374373
) -> Result<Transformed<Self>> {
375-
#[recursive]
374+
#[cfg_attr(feature = "recursive-protection", recursive::recursive)]
376375
fn transform_down_up_impl<
377376
N: TreeNode,
378377
FD: FnMut(N) -> Result<Transformed<N>>,

datafusion/expr/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ name = "datafusion_expr"
3636
path = "src/lib.rs"
3737

3838
[features]
39+
default = ["recursive-protection"]
40+
recursive-protection = ["recursive"]
3941

4042
[dependencies]
4143
arrow = { workspace = true }
@@ -48,7 +50,7 @@ datafusion-functions-window-common = { workspace = true }
4850
datafusion-physical-expr-common = { workspace = true }
4951
indexmap = { workspace = true }
5052
paste = "^1.0"
51-
recursive = { workspace = true }
53+
recursive = { version = "0.1.1", optional = true }
5254
serde_json = { workspace = true }
5355
sqlparser = { workspace = true }
5456

datafusion/expr/src/expr_schema.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ use datafusion_common::{
3232
TableReference,
3333
};
3434
use datafusion_functions_window_common::field::WindowUDFFieldArgs;
35-
use recursive::recursive;
3635
use std::collections::HashMap;
3736
use std::sync::Arc;
3837

@@ -100,7 +99,7 @@ impl ExprSchemable for Expr {
10099
/// expression refers to a column that does not exist in the
101100
/// schema, or when the expression is incorrectly typed
102101
/// (e.g. `[utf8] + [bool]`).
103-
#[recursive]
102+
#[cfg_attr(feature = "recursive-protection", recursive::recursive)]
104103
fn get_type(&self, schema: &dyn ExprSchema) -> Result<DataType> {
105104
match self {
106105
Expr::Alias(Alias { expr, name, .. }) => match &**expr {

datafusion/expr/src/logical_plan/tree_node.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ use crate::{
4545
UserDefinedLogicalNode, Values, Window,
4646
};
4747
use datafusion_common::tree_node::TreeNodeRefContainer;
48-
use recursive::recursive;
4948

5049
use crate::expr::{Exists, InSubquery};
5150
use datafusion_common::tree_node::{
@@ -669,7 +668,7 @@ impl LogicalPlan {
669668

670669
/// Visits a plan similarly to [`Self::visit`], including subqueries that
671670
/// may appear in expressions such as `IN (SELECT ...)`.
672-
#[recursive]
671+
#[cfg_attr(feature = "recursive-protection", recursive::recursive)]
673672
pub fn visit_with_subqueries<V: for<'n> TreeNodeVisitor<'n, Node = Self>>(
674673
&self,
675674
visitor: &mut V,
@@ -688,7 +687,7 @@ impl LogicalPlan {
688687
/// Similarly to [`Self::rewrite`], rewrites this node and its inputs using `f`,
689688
/// including subqueries that may appear in expressions such as `IN (SELECT
690689
/// ...)`.
691-
#[recursive]
690+
#[cfg_attr(feature = "recursive-protection", recursive::recursive)]
692691
pub fn rewrite_with_subqueries<R: TreeNodeRewriter<Node = Self>>(
693692
self,
694693
rewriter: &mut R,
@@ -707,7 +706,7 @@ impl LogicalPlan {
707706
&self,
708707
mut f: F,
709708
) -> Result<TreeNodeRecursion> {
710-
#[recursive]
709+
#[cfg_attr(feature = "recursive-protection", recursive::recursive)]
711710
fn apply_with_subqueries_impl<
712711
F: FnMut(&LogicalPlan) -> Result<TreeNodeRecursion>,
713712
>(
@@ -742,7 +741,7 @@ impl LogicalPlan {
742741
self,
743742
mut f: F,
744743
) -> Result<Transformed<Self>> {
745-
#[recursive]
744+
#[cfg_attr(feature = "recursive-protection", recursive::recursive)]
746745
fn transform_down_with_subqueries_impl<
747746
F: FnMut(LogicalPlan) -> Result<Transformed<LogicalPlan>>,
748747
>(
@@ -767,7 +766,7 @@ impl LogicalPlan {
767766
self,
768767
mut f: F,
769768
) -> Result<Transformed<Self>> {
770-
#[recursive]
769+
#[cfg_attr(feature = "recursive-protection", recursive::recursive)]
771770
fn transform_up_with_subqueries_impl<
772771
F: FnMut(LogicalPlan) -> Result<Transformed<LogicalPlan>>,
773772
>(
@@ -795,7 +794,7 @@ impl LogicalPlan {
795794
mut f_down: FD,
796795
mut f_up: FU,
797796
) -> Result<Transformed<Self>> {
798-
#[recursive]
797+
#[cfg_attr(feature = "recursive-protection", recursive::recursive)]
799798
fn transform_down_up_with_subqueries_impl<
800799
FD: FnMut(LogicalPlan) -> Result<Transformed<LogicalPlan>>,
801800
FU: FnMut(LogicalPlan) -> Result<Transformed<LogicalPlan>>,

datafusion/optimizer/Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ workspace = true
3535
name = "datafusion_optimizer"
3636
path = "src/lib.rs"
3737

38+
[features]
39+
default = ["recursive-protection"]
40+
recursive-protection = ["recursive"]
41+
3842
[dependencies]
3943
arrow = { workspace = true }
4044
chrono = { workspace = true }
@@ -44,7 +48,7 @@ datafusion-physical-expr = { workspace = true }
4448
indexmap = { workspace = true }
4549
itertools = { workspace = true }
4650
log = { workspace = true }
47-
recursive = { workspace = true }
51+
recursive = { version = "0.1.1", optional = true }
4852
regex = { workspace = true }
4953
regex-syntax = "0.8.0"
5054

datafusion/optimizer/src/analyzer/subquery.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
use crate::analyzer::check_plan;
1919
use crate::utils::collect_subquery_cols;
20-
use recursive::recursive;
2120

2221
use datafusion_common::tree_node::{TreeNode, TreeNodeRecursion};
2322
use datafusion_common::{plan_err, Result};
@@ -79,7 +78,7 @@ pub fn check_subquery_expr(
7978
match outer_plan {
8079
LogicalPlan::Projection(_)
8180
| LogicalPlan::Filter(_) => Ok(()),
82-
LogicalPlan::Aggregate(Aggregate {group_expr, aggr_expr,..}) => {
81+
LogicalPlan::Aggregate(Aggregate { group_expr, aggr_expr, .. }) => {
8382
if group_expr.contains(expr) && !aggr_expr.contains(expr) {
8483
// TODO revisit this validation logic
8584
plan_err!(
@@ -88,7 +87,7 @@ pub fn check_subquery_expr(
8887
} else {
8988
Ok(())
9089
}
91-
},
90+
}
9291
_ => plan_err!(
9392
"Correlated scalar subquery can only be used in Projection, Filter, Aggregate plan nodes"
9493
)
@@ -129,7 +128,7 @@ fn check_correlations_in_subquery(inner_plan: &LogicalPlan) -> Result<()> {
129128
}
130129

131130
// Recursively check the unsupported outer references in the sub query plan.
132-
#[recursive]
131+
#[cfg_attr(feature = "recursive-protection", recursive::recursive)]
133132
fn check_inner_plan(inner_plan: &LogicalPlan, can_contain_outer_ref: bool) -> Result<()> {
134133
if !can_contain_outer_ref && inner_plan.contains_outer_reference() {
135134
return plan_err!("Accessing outer reference columns is not allowed in the plan");

datafusion/optimizer/src/common_subexpr_eliminate.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ use std::fmt::Debug;
2222
use std::sync::Arc;
2323

2424
use crate::{OptimizerConfig, OptimizerRule};
25-
use recursive::recursive;
2625

2726
use crate::optimizer::ApplyOrder;
2827
use crate::utils::NamePreserver;
@@ -532,7 +531,7 @@ impl OptimizerRule for CommonSubexprEliminate {
532531
None
533532
}
534533

535-
#[recursive]
534+
#[cfg_attr(feature = "recursive-protection", recursive::recursive)]
536535
fn rewrite(
537536
&self,
538537
plan: LogicalPlan,
@@ -951,7 +950,7 @@ mod test {
951950
)?
952951
.build()?;
953952

954-
let expected ="Aggregate: groupBy=[[]], aggr=[[avg(__common_expr_1) AS col1, my_agg(__common_expr_1) AS col2]]\
953+
let expected = "Aggregate: groupBy=[[]], aggr=[[avg(__common_expr_1) AS col1, my_agg(__common_expr_1) AS col2]]\
955954
\n Projection: UInt32(1) + test.a AS __common_expr_1, test.a, test.b, test.c\
956955
\n TableScan: test";
957956

0 commit comments

Comments
 (0)