MCPcopy Create free account
hub / github.com/apache/datafusion / plan_all_op

Function plan_all_op

datafusion/sql/src/expr/mod.rs:1315–1362  ·  view source on GitHub ↗

Plans `needle ALL(haystack)` with proper SQL NULL semantics. CASE/WHEN structure: WHEN arr IS NULL → NULL WHEN empty → TRUE WHEN lhs IS NULL → NULL WHEN decisive_condition → FALSE WHEN has_nulls → NULL ELSE → TRUE

(
    needle: &Expr,
    haystack: &Expr,
    compare_op: &BinaryOperator,
)

Source from the content-addressed store, hash-verified

1313/// WHEN has_nulls → NULL
1314/// ELSE → TRUE
1315fn plan_all_op(
1316 needle: &Expr,
1317 haystack: &Expr,
1318 compare_op: &BinaryOperator,
1319) -> Result<Expr> {
1320 let null_arr_check = haystack.clone().is_null();
1321 let empty_check = cardinality(haystack.clone()).eq(lit(0u64));
1322 let null_lhs_check = needle.clone().is_null();
1323 // DataFusion's array_position uses is_null() checks internally (not equality),
1324 // so it can locate NULL elements even though NULL = NULL is NULL in standard SQL.
1325 let has_nulls =
1326 array_position(haystack.clone(), lit(ScalarValue::Null), lit(1i64)).is_not_null();
1327
1328 let decisive_condition = match compare_op {
1329 BinaryOperator::NotEq => array_has(haystack.clone(), needle.clone()),
1330 BinaryOperator::Eq => {
1331 let all_equal = array_min(haystack.clone())
1332 .eq(needle.clone())
1333 .and(array_max(haystack.clone()).eq(needle.clone()));
1334 Expr::Not(Box::new(all_equal))
1335 }
1336 BinaryOperator::Gt => {
1337 Expr::Not(Box::new(needle.clone().gt(array_max(haystack.clone()))))
1338 }
1339 BinaryOperator::Lt => {
1340 Expr::Not(Box::new(needle.clone().lt(array_min(haystack.clone()))))
1341 }
1342 BinaryOperator::GtEq => {
1343 Expr::Not(Box::new(needle.clone().gt_eq(array_max(haystack.clone()))))
1344 }
1345 BinaryOperator::LtEq => {
1346 Expr::Not(Box::new(needle.clone().lt_eq(array_min(haystack.clone()))))
1347 }
1348 _ => {
1349 return plan_err!(
1350 "Unsupported AllOp: '{compare_op}', only '=', '<>', '>', '<', '>=', '<=' are supported"
1351 );
1352 }
1353 };
1354
1355 let null_bool = lit(ScalarValue::Boolean(None));
1356 when(null_arr_check, null_bool.clone())
1357 .when(empty_check, lit(true))
1358 .when(null_lhs_check, null_bool.clone())
1359 .when(decisive_condition, lit(false))
1360 .when(has_nulls, null_bool)
1361 .otherwise(lit(true))
1362}
1363
1364#[cfg(test)]
1365mod tests {

Callers 1

Calls 15

NotClass · 0.85
newFunction · 0.85
whenFunction · 0.85
is_not_nullMethod · 0.80
otherwiseMethod · 0.80
whenMethod · 0.80
litFunction · 0.50
is_nullMethod · 0.45
cloneMethod · 0.45
eqMethod · 0.45
andMethod · 0.45
gtMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…