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

Function general_remove

datafusion/functions-nested/src/remove.rs:377–469  ·  view source on GitHub ↗

For each element of `list_array[i]`, removed up to `arr_n[i]` occurrences of `element_array[i]`. The type of each **element** in `list_array` must be the same as the type of `element_array`. This function also handles nested arrays ([`arrow::array::ListArray`] of [`arrow::array::ListArray`]s) For example, when called to remove a list array (where each element is a list of int32s, the second argu

(
    list_array: &GenericListArray<OffsetSize>,
    element_array: &ArrayRef,
    arr_n: &[i64],
)

Source from the content-addressed store, hash-verified

375/// )
376/// ```
377fn general_remove<OffsetSize: OffsetSizeTrait>(
378 list_array: &GenericListArray<OffsetSize>,
379 element_array: &ArrayRef,
380 arr_n: &[i64],
381) -> Result<ArrayRef> {
382 let list_field = match list_array.data_type() {
383 DataType::List(field) | DataType::LargeList(field) => field,
384 _ => {
385 return exec_err!(
386 "Expected List or LargeList data type, got {:?}",
387 list_array.data_type()
388 );
389 }
390 };
391 let original_data = list_array.values().to_data();
392 // Build up the offsets for the final output array
393 let mut offsets = Vec::<OffsetSize>::with_capacity(arr_n.len() + 1);
394 offsets.push(OffsetSize::zero());
395
396 let mut mutable = MutableArrayData::with_capacities(
397 vec![&original_data],
398 false,
399 Capacities::Array(original_data.len()),
400 );
401
402 // Pre-compute combined null bitmap
403 let nulls = NullBuffer::union(list_array.nulls(), element_array.nulls());
404
405 for (row_index, offset_window) in list_array.offsets().windows(2).enumerate() {
406 if nulls.as_ref().is_some_and(|nulls| nulls.is_null(row_index)) {
407 offsets.push(offsets[row_index]);
408 continue;
409 }
410
411 let start = offset_window[0].to_usize().unwrap();
412 let end = offset_window[1].to_usize().unwrap();
413 // n is the number of elements to remove in this row
414 let n = arr_n[row_index];
415
416 // compare each element in the list, `false` means the element matches and should be removed
417 let eq_array = utils::compare_element_to_list(
418 &list_array.value(row_index),
419 element_array,
420 row_index,
421 false,
422 )?;
423
424 let num_to_remove = eq_array.false_count();
425
426 // Fast path: no elements to remove, copy entire row
427 if num_to_remove == 0 {
428 mutable.extend(0, start, end);
429 offsets.push(offsets[row_index] + OffsetSize::usize_as(end - start));
430 continue;
431 }
432
433 // Remove at most `n` matching elements
434 let max_removals = n.min(num_to_remove as i64);

Callers

nothing calls this directly

Calls 15

compare_element_to_listFunction · 0.85
make_arrayFunction · 0.85
newFunction · 0.85
offsetsMethod · 0.80
is_noneMethod · 0.80
unionFunction · 0.50
data_typeMethod · 0.45
valuesMethod · 0.45
lenMethod · 0.45
pushMethod · 0.45
nullsMethod · 0.45
as_refMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…