arrow_data/transform/
union.rs1use super::{_MutableArrayData, Extend};
19use crate::ArrayData;
20use arrow_schema::DataType;
21
22pub(super) fn build_extend_sparse(array: &ArrayData) -> Extend<'_> {
23 let type_ids = array.buffer::<i8>(0);
24
25 Box::new(
26 move |mutable: &mut _MutableArrayData, index: usize, start: usize, len: usize| {
27 mutable
29 .buffer1
30 .extend_from_slice(&type_ids[start..start + len]);
31
32 mutable
33 .child_data
34 .iter_mut()
35 .for_each(|child| child.extend(index, start, start + len))
36 },
37 )
38}
39
40pub(super) fn build_extend_dense(array: &ArrayData) -> Extend<'_> {
41 let type_ids = array.buffer::<i8>(0);
42 let offsets = array.buffer::<i32>(1);
43 let arrow_schema::DataType::Union(src_fields, _) = array.data_type() else {
44 unreachable!();
45 };
46
47 Box::new(
48 move |mutable: &mut _MutableArrayData, index: usize, start: usize, len: usize| {
49 mutable
51 .buffer1
52 .extend_from_slice(&type_ids[start..start + len]);
53
54 (start..start + len).for_each(|i| {
55 let type_id = type_ids[i];
56 let child_index = src_fields
57 .iter()
58 .position(|(r, _)| r == type_id)
59 .expect("invalid union type ID");
60 let src_offset = offsets[i] as usize;
61 let child_data = &mut mutable.child_data[child_index];
62 let dst_offset = child_data.len();
63
64 mutable.buffer2.push(dst_offset as i32);
66 mutable.child_data[child_index].extend(index, src_offset, src_offset + 1)
67 })
68 },
69 )
70}
71
72pub(super) fn extend_nulls_dense(mutable: &mut _MutableArrayData, len: usize) {
73 let DataType::Union(fields, _) = &mutable.data_type else {
74 unreachable!()
75 };
76 let first_type_id = fields
77 .iter()
78 .next()
79 .expect("union must have at least one field")
80 .0;
81
82 mutable.buffer1.extend_from_slice(&vec![first_type_id; len]);
84
85 let child_offset = mutable.child_data[0].len();
87 let (start, end) = (child_offset as i32, (child_offset + len) as i32);
88 mutable.buffer2.extend(start..end);
89 mutable.child_data[0].extend_nulls(len);
90}
91
92pub(super) fn extend_nulls_sparse(mutable: &mut _MutableArrayData, len: usize) {
93 let DataType::Union(fields, _) = &mutable.data_type else {
94 unreachable!()
95 };
96 let first_type_id = fields
97 .iter()
98 .next()
99 .expect("union must have at least one field")
100 .0;
101
102 mutable.buffer1.extend_from_slice(&vec![first_type_id; len]);
104
105 mutable
107 .child_data
108 .iter_mut()
109 .for_each(|child| child.extend_nulls(len));
110}