Skip to content

Commit 07a914d

Browse files
committed
Separate semantics for evaluates_to_null and
authoritative_restrict_null_predicate Restore evaluates_to_null behavior for general expressions without boolean-downcasting arrays. Fix scalar_subquery_with_non_strong_project regression. Update authoritative_restrict_null_predicate to handle predicate results directly, treating scalar NULL as null-restricting, resolving the CASE ... ELSE NULL test failure. Maintain non-join-column fast path functionality.
1 parent 2da82cd commit 07a914d

1 file changed

Lines changed: 23 additions & 38 deletions

File tree

datafusion/optimizer/src/utils.rs

Lines changed: 23 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -181,10 +181,12 @@ pub fn evaluates_to_null<'a>(
181181
return Ok(true);
182182
}
183183

184-
Ok(authoritative_null_result(evaluate_expr_with_null_column(
185-
predicate,
186-
null_columns,
187-
)?)? == AuthoritativeNullResult::AlwaysNull)
184+
Ok(
185+
match evaluate_expr_with_null_column(predicate, null_columns)? {
186+
ColumnarValue::Array(_) => false,
187+
ColumnarValue::Scalar(scalar) => scalar.is_null(),
188+
},
189+
)
188190
}
189191

190192
fn evaluate_expr_with_null_column<'a>(
@@ -218,41 +220,24 @@ fn authoritative_restrict_null_predicate<'a>(
218220
predicate: Expr,
219221
join_cols_of_predicate: impl IntoIterator<Item = &'a Column>,
220222
) -> Result<bool> {
221-
Ok(authoritative_null_result(evaluate_expr_with_null_column(
222-
predicate,
223-
join_cols_of_predicate,
224-
)?)? == AuthoritativeNullResult::NullRestricting)
225-
}
226-
227-
#[derive(Debug, PartialEq, Eq)]
228-
enum AuthoritativeNullResult {
229-
AlwaysNull,
230-
NullRestricting,
231-
Other,
232-
}
233-
234-
fn authoritative_null_result(value: ColumnarValue) -> Result<AuthoritativeNullResult> {
235-
Ok(match value {
236-
ColumnarValue::Array(array) => {
237-
if array.len() != 1 {
238-
return Ok(AuthoritativeNullResult::Other);
223+
Ok(
224+
match evaluate_expr_with_null_column(predicate, join_cols_of_predicate)? {
225+
ColumnarValue::Array(array) => {
226+
if array.len() == 1 {
227+
let boolean_array = as_boolean_array(&array)?;
228+
boolean_array.is_null(0) || !boolean_array.value(0)
229+
} else {
230+
false
231+
}
239232
}
240-
241-
let boolean_array = as_boolean_array(&array)?;
242-
if boolean_array.is_null(0) || !boolean_array.value(0) {
243-
AuthoritativeNullResult::NullRestricting
244-
} else {
245-
AuthoritativeNullResult::Other
246-
}
247-
}
248-
ColumnarValue::Scalar(scalar) if scalar.is_null() => {
249-
AuthoritativeNullResult::AlwaysNull
250-
}
251-
ColumnarValue::Scalar(
252-
ScalarValue::Boolean(None) | ScalarValue::Boolean(Some(false)),
253-
) => AuthoritativeNullResult::NullRestricting,
254-
ColumnarValue::Scalar(_) => AuthoritativeNullResult::Other,
255-
})
233+
ColumnarValue::Scalar(scalar) => matches!(
234+
scalar,
235+
ScalarValue::Boolean(None)
236+
| ScalarValue::Boolean(Some(false))
237+
| ScalarValue::Null
238+
),
239+
},
240+
)
256241
}
257242

258243
fn coerce(expr: Expr, schema: &DFSchema) -> Result<Expr> {

0 commit comments

Comments
 (0)