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

Function general_list_repeat

datafusion/functions-nested/src/repeat.rs:229–310  ·  view source on GitHub ↗

Handle List version of `general_repeat` For each element of `list_array[i]` repeat `count_array[i]` times. For example, ```text array_repeat( [[1, 2, 3], [4, 5], [6]], [2, 0, 1] => [[[1, 2, 3], [1, 2, 3]], [], [[6]]] ) ```

(
    list_array: &GenericListArray<O>,
    count_array: &Int64Array,
)

Source from the content-addressed store, hash-verified

227/// )
228/// ```
229fn general_list_repeat<O: OffsetSizeTrait>(
230 list_array: &GenericListArray<O>,
231 count_array: &Int64Array,
232) -> Result<ArrayRef> {
233 let list_offsets = list_array.value_offsets();
234
235 // calculate capacities for pre-allocation
236 let mut outer_total = 0usize;
237 let mut inner_total = 0usize;
238 for i in 0..count_array.len() {
239 let count = get_count_with_validity(count_array, i);
240 if count > 0 {
241 outer_total += count;
242 if list_array.is_valid(i) {
243 let len = list_offsets[i + 1].to_usize().unwrap()
244 - list_offsets[i].to_usize().unwrap();
245 inner_total += len * count;
246 }
247 }
248 }
249
250 // Build inner structures
251 let mut inner_offsets = Vec::with_capacity(outer_total + 1);
252 let mut take_indices = Vec::with_capacity(inner_total);
253 let mut inner_nulls = BooleanBufferBuilder::new(outer_total);
254 let mut inner_running = 0usize;
255 inner_offsets.push(O::zero());
256
257 for row_idx in 0..count_array.len() {
258 let count = get_count_with_validity(count_array, row_idx);
259 let list_is_valid = list_array.is_valid(row_idx);
260 let start = list_offsets[row_idx].to_usize().unwrap();
261 let end = list_offsets[row_idx + 1].to_usize().unwrap();
262 let row_len = end - start;
263
264 for _ in 0..count {
265 inner_running = inner_running.checked_add(row_len).ok_or_else(|| {
266 DataFusionError::Execution(
267 "array_repeat: inner offset overflowed usize".to_string(),
268 )
269 })?;
270 let offset = O::from_usize(inner_running).ok_or_else(|| {
271 DataFusionError::Execution(format!(
272 "array_repeat: offset {inner_running} exceeds the maximum value for offset type"
273 ))
274 })?;
275 inner_offsets.push(offset);
276 inner_nulls.append(list_is_valid);
277 if list_is_valid {
278 take_indices.extend(start as u64..end as u64);
279 }
280 }
281 }
282
283 // Build inner ListArray
284 let inner_values = compute::take(
285 list_array.values().as_ref(),
286 &UInt64Array::from_iter_values(take_indices),

Callers

nothing calls this directly

Calls 15

get_count_with_validityFunction · 0.85
newFunction · 0.85
value_offsetsMethod · 0.80
value_typeMethod · 0.80
lenMethod · 0.45
is_validMethod · 0.45
pushMethod · 0.45
to_stringMethod · 0.45
appendMethod · 0.45
extendMethod · 0.45
as_refMethod · 0.45
valuesMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…