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,
)
| 227 | /// ) |
| 228 | /// ``` |
| 229 | fn 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), |
nothing calls this directly
no test coverage detected
searching dependent graphs…