Skip to content

Commit 9f19fed

Browse files
committed
improve lambda_parameters infinite loop guard
1 parent 9cb4882 commit 9f19fed

2 files changed

Lines changed: 14 additions & 2 deletions

File tree

datafusion/expr/src/higher_order_function.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,22 @@ pub struct HigherOrderSignature {
7575
pub volatility: Volatility,
7676
/// Whether [HigherOrderUDF::coerce_values_for_lambdas] should be called
7777
pub coerce_values_for_lambdas: bool,
78+
/// The max number of times to call [HigherOrderUDF::lambda_parameters] before raising an error.
79+
/// Used to guard against implementations that causes an infinite loop by endlessly returning
80+
/// [LambdaParametersProgress::Partial]. Defaults to 256
81+
pub lambda_parameters_max_iterations: usize,
7882
}
7983

84+
const LAMBDA_PARAMETERS_MAX_ITERATIONS: usize = 256;
85+
8086
impl HigherOrderSignature {
8187
/// Creates a new `HigherOrderSignature` from a given type signature and volatility.
8288
pub fn new(type_signature: HigherOrderTypeSignature, volatility: Volatility) -> Self {
8389
HigherOrderSignature {
8490
type_signature,
8591
volatility,
8692
coerce_values_for_lambdas: false,
93+
lambda_parameters_max_iterations: LAMBDA_PARAMETERS_MAX_ITERATIONS,
8794
}
8895
}
8996

@@ -93,6 +100,7 @@ impl HigherOrderSignature {
93100
type_signature: HigherOrderTypeSignature::UserDefined,
94101
volatility,
95102
coerce_values_for_lambdas: false,
103+
lambda_parameters_max_iterations: LAMBDA_PARAMETERS_MAX_ITERATIONS,
96104
}
97105
}
98106

@@ -102,6 +110,7 @@ impl HigherOrderSignature {
102110
type_signature: HigherOrderTypeSignature::VariadicAny,
103111
volatility,
104112
coerce_values_for_lambdas: false,
113+
lambda_parameters_max_iterations: LAMBDA_PARAMETERS_MAX_ITERATIONS,
105114
}
106115
}
107116

@@ -111,6 +120,7 @@ impl HigherOrderSignature {
111120
type_signature: HigherOrderTypeSignature::Any(arg_count),
112121
volatility,
113122
coerce_values_for_lambdas: false,
123+
lambda_parameters_max_iterations: LAMBDA_PARAMETERS_MAX_ITERATIONS,
114124
}
115125
}
116126

datafusion/sql/src/expr/function.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -513,11 +513,13 @@ impl<S: ContextProvider> SqlToRel<'_, S> {
513513
}
514514
}
515515

516+
let limit = fm.signature().lambda_parameters_max_iterations;
517+
516518
step += 1;
517519

518-
if step > 256 {
520+
if step > limit {
519521
return plan_err!(
520-
"{} lambda_parameters called 256 times without completion",
522+
"{} lambda_parameters called {limit} times without completion",
521523
fm.name()
522524
);
523525
}

0 commit comments

Comments
 (0)