← Back

/arrow-array/src/array/union_array.rs

source

Branches Cov Line Source
1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements. See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership. The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License. You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing,
12 // software distributed under the License is distributed on an
13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 // KIND, either express or implied. See the License for the
15 // specific language governing permissions and limitations
16 // under the License.
17 #![allow(clippy::enum_clike_unportable_variant)]
18
19 use crate::{make_array, Array, ArrayRef};
20 use arrow_buffer::bit_chunk_iterator::{BitChunkIterator, BitChunks};
21 use arrow_buffer::buffer::NullBuffer;
22 use arrow_buffer::{BooleanBuffer, MutableBuffer, ScalarBuffer};
23 use arrow_data::{ArrayData, ArrayDataBuilder};
24 use arrow_schema::{ArrowError, DataType, UnionFields, UnionMode};
25 /// Contains the `UnionArray` type.
26 ///
27 use std::any::Any;
28 use std::collections::HashSet;
29 use std::sync::Arc;
30
31 /// An array of [values of varying types](https://arrow.apache.org/docs/format/Columnar.html#union-layout)
32 ///
33 /// Each slot in a [UnionArray] can have a value chosen from a number
34 /// of types. Each of the possible types are named like the fields of
35 /// a [`StructArray`](crate::StructArray). A `UnionArray` can
36 /// have two possible memory layouts, "dense" or "sparse". For more
37 /// information on please see the
38 /// [specification](https://arrow.apache.org/docs/format/Columnar.html#union-layout).
39 ///
40 /// [UnionBuilder](crate::builder::UnionBuilder) can be used to
41 /// create [UnionArray]'s of primitive types. `UnionArray`'s of nested
42 /// types are also supported but not via `UnionBuilder`, see the tests
43 /// for examples.
44 ///
45 /// # Examples
46 /// ## Create a dense UnionArray `[1, 3.2, 34]`
47 /// ```
48 /// use arrow_buffer::ScalarBuffer;
49 /// use arrow_schema::*;
50 /// use std::sync::Arc;
51 /// use arrow_array::{Array, Int32Array, Float64Array, UnionArray};
52 ///
53 /// let int_array = Int32Array::from(vec![1, 34]);
54 /// let float_array = Float64Array::from(vec![3.2]);
55 /// let type_ids = [0, 1, 0].into_iter().collect::<ScalarBuffer<i8>>();
56 /// let offsets = [0, 0, 1].into_iter().collect::<ScalarBuffer<i32>>();
57 ///
58 /// let union_fields = [
59 /// (0, Arc::new(Field::new("A", DataType::Int32, false))),
60 /// (1, Arc::new(Field::new("B", DataType::Float64, false))),
61 /// ].into_iter().collect::<UnionFields>();
62 ///
63 /// let children = vec![
64 /// Arc::new(int_array) as Arc<dyn Array>,
65 /// Arc::new(float_array),
66 /// ];
67 ///
68 /// let array = UnionArray::try_new(
69 /// union_fields,
70 /// type_ids,
71 /// Some(offsets),
72 /// children,
73 /// ).unwrap();
74 ///
75 /// let value = array.value(0).as_any().downcast_ref::<Int32Array>().unwrap().value(0);
76 /// assert_eq!(1, value);
77 ///
78 /// let value = array.value(1).as_any().downcast_ref::<Float64Array>().unwrap().value(0);
79 /// assert!(3.2 - value < f64::EPSILON);
80 ///
81 /// let value = array.value(2).as_any().downcast_ref::<Int32Array>().unwrap().value(0);
82 /// assert_eq!(34, value);
83 /// ```
84 ///
85 /// ## Create a sparse UnionArray `[1, 3.2, 34]`
86 /// ```
87 /// use arrow_buffer::ScalarBuffer;
88 /// use arrow_schema::*;
89 /// use std::sync::Arc;
90 /// use arrow_array::{Array, Int32Array, Float64Array, UnionArray};
91 ///
92 /// let int_array = Int32Array::from(vec![Some(1), None, Some(34)]);
93 /// let float_array = Float64Array::from(vec![None, Some(3.2), None]);
94 /// let type_ids = [0_i8, 1, 0].into_iter().collect::<ScalarBuffer<i8>>();
95 ///
96 /// let union_fields = [
97 /// (0, Arc::new(Field::new("A", DataType::Int32, false))),
98 /// (1, Arc::new(Field::new("B", DataType::Float64, false))),
99 /// ].into_iter().collect::<UnionFields>();
100 ///
101 /// let children = vec![
102 /// Arc::new(int_array) as Arc<dyn Array>,
103 /// Arc::new(float_array),
104 /// ];
105 ///
106 /// let array = UnionArray::try_new(
107 /// union_fields,
108 /// type_ids,
109 /// None,
110 /// children,
111 /// ).unwrap();
112 ///
113 /// let value = array.value(0).as_any().downcast_ref::<Int32Array>().unwrap().value(0);
114 /// assert_eq!(1, value);
115 ///
116 /// let value = array.value(1).as_any().downcast_ref::<Float64Array>().unwrap().value(0);
117 /// assert!(3.2 - value < f64::EPSILON);
118 ///
▶︎ ▶︎ 20 119 /// let value = array.value(2).as_any().downcast_ref::<Int32Array>().unwrap().value(0);
120 /// assert_eq!(34, value);
20 121 /// ```
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 20 122 #[derive(Clone)]
20 123 pub struct UnionArray {
20 124 data_type: DataType,
4 125 type_ids: ScalarBuffer<i8>,
4 126 offsets: Option<ScalarBuffer<i32>>,
4 127 fields: Vec<Option<ArrayRef>>,
128 }
129
130 impl UnionArray {
131 /// Creates a new `UnionArray`.
132 ///
133 /// Accepts type ids, child arrays and optionally offsets (for dense unions) to create
134 /// a new `UnionArray`. This method makes no attempt to validate the data provided by the
135 /// caller and assumes that each of the components are correct and consistent with each other.
136 /// See `try_new` for an alternative that validates the data provided.
137 ///
138 /// # Safety
139 ///
140 /// The `type_ids` values should be positive and must match one of the type ids of the fields provided in `fields`.
141 /// These values are used to index into the `children` arrays.
142 ///
143 /// The `offsets` is provided in the case of a dense union, sparse unions should use `None`.
144 /// If provided the `offsets` values should be positive and must be less than the length of the
145 /// corresponding array.
65 146 ///
147 /// In both cases above we use signed integer types to maintain compatibility with other
148 /// Arrow implementations.
68 149 pub unsafe fn new_unchecked(
150 fields: UnionFields,
151 type_ids: ScalarBuffer<i8>,
65 152 offsets: Option<ScalarBuffer<i32>>,
39 153 children: Vec<ArrayRef>,
154 ) -> Self {
▶︎ 68 155 let mode = if offsets.is_some() {
28 156 UnionMode::Dense
157 } else {
66 158 UnionMode::Sparse
66 159 };
▶︎ 65 160
▶︎ ▶︎ 68 161 let len = type_ids.len();
▶︎ 68 162 let builder = ArrayData::builder(DataType::Union(fields, mode))
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 68 163 .add_buffer(type_ids.into_inner())
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 68 164 .child_data(children.into_iter().map(Array::into_data).collect())
▶︎ 40 165 .len(len);
26 166
68 167 let data = match offsets {
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 66 168 Some(offsets) => builder.add_buffer(offsets.into_inner()).build_unchecked(),
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 65 169 None => builder.build_unchecked(),
170 };
68 171 Self::from(data)
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 68 172 }
173
62 174 /// Attempts to create a new `UnionArray`, validating the inputs provided.
175 ///
176 /// The order of child arrays child array order must match the fields order
80 177 pub fn try_new(
178 fields: UnionFields,
179 type_ids: ScalarBuffer<i8>,
180 offsets: Option<ScalarBuffer<i32>>,
62 181 children: Vec<ArrayRef>,
0 182 ) -> Result<Self, ArrowError> {
0 183 // There must be a child array for every field.
▶︎ ▶︎ 80 184 if fields.len() != children.len() {
2 185 return Err(ArrowError::InvalidArgumentError(
2 186 "Union fields length must match child arrays length".to_string(),
187 ));
62 188 }
40 189
▶︎ 78 190 if let Some(offsets) = &offsets {
0 191 // There must be an offset value for every type id value.
▶︎ ▶︎ 32 192 if offsets.len() != type_ids.len() {
2 193 return Err(ArrowError::InvalidArgumentError(
2 194 "Type Ids and Offsets lengths must match".to_string(),
195 ));
196 }
102 197 } else {
61 198 // Sparse union child arrays must be equal in length to the length of the union
▶︎ ▶︎ ▶︎ 240 199 for child in &children {
▶︎ ▶︎ 196 200 if child.len() != type_ids.len() {
2 201 return Err(ArrowError::InvalidArgumentError(
2 202 "Sparse union child arrays must be equal in length to the length of the union".to_string(),
203 ));
2789 204 }
2729 205 }
2728 206 }
207
0 208 // Create mapping from type id to array lengths.
▶︎ ▶︎ ▶︎ ▶︎ 257 209 let max_id = fields.iter().map(|(i, _)| i).max().unwrap_or_default() as usize;
74 210 let mut array_lens = vec![i32::MIN; max_id + 1];
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 334 211 for (cd, (field_id, _)) in children.iter().zip(fields.iter()) {
▶︎ ▶︎ 260 212 array_lens[field_id as usize] = cd.len() as i32;
213 }
214
215 // Type id values must match one of the fields.
▶︎ ▶︎ ▶︎ 3335 216 for id in &type_ids {
▶︎ ▶︎ 3266 217 match array_lens.get(*id as usize) {
▶︎ ▶︎ 3263 218 Some(x) if *x != i32::MIN => {}
219 _ => {
4 220 return Err(ArrowError::InvalidArgumentError(
4 221 "Type Ids values must match one of the field type ids".to_owned(),
222 ))
223 }
224 }
225 }
226
227 // Check the value offsets are in bounds.
▶︎ 70 228 if let Some(offsets) = &offsets {
▶︎ ▶︎ ▶︎ ▶︎ 62 229 let mut iter = type_ids.iter().zip(offsets.iter());
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 2178 230 if iter.any(|(type_id, &offset)| offset < 0 || offset >= array_lens[*type_id as usize])
231 {
2 232 return Err(ArrowError::InvalidArgumentError(
2 233 "Offsets must be positive and within the length of the Array".to_owned(),
234 ));
235 }
236 }
237
95 238 // Safety:
▶︎ 95 239 // - Arguments validated above.
95 240 let union_array = unsafe { Self::new_unchecked(fields, type_ids, offsets, children) };
95 241 Ok(union_array)
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 95 242 }
243
244 /// Accesses the child array for `type_id`.
245 ///
246 /// # Panics
247 ///
248 /// Panics if the `type_id` provided is not present in the array's DataType
48 249 /// in the `Union`.
▶︎ 2356 250 pub fn child(&self, type_id: i8) -> &ArrayRef {
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 2356 251 assert!((type_id as usize) < self.fields.len());
2356 252 let boxed = &self.fields[type_id as usize];
2356 253 boxed.as_ref().expect("invalid type id")
2356 254 }
27 255
27 256 /// Returns the `type_id` for the array slot at `index`.
27 257 ///
258 /// # Panics
259 ///
58 260 /// Panics if `index` is greater than or equal to the number of child arrays
4300 261 pub fn type_id(&self, index: usize) -> i8 {
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 4300 262 assert!(index < self.type_ids.len());
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 4300 263 self.type_ids[index]
4300 264 }
265
266 /// Returns the `type_ids` buffer for this array
12 267 pub fn type_ids(&self) -> &ScalarBuffer<i8> {
12 268 &self.type_ids
32 269 }
▶︎ 32 270
32 271 /// Returns the `offsets` buffer if this is a dense array
▶︎ 23 272 pub fn offsets(&self) -> Option<&ScalarBuffer<i32>> {
12 273 self.offsets.as_ref()
12 274 }
32 275
276 /// Returns the offset into the underlying values array for the array slot at `index`.
277 ///
278 /// # Panics
279 ///
32 280 /// Panics if `index` is greater than or equal the length of the array.
4256 281 pub fn value_offset(&self, index: usize) -> usize {
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 4256 282 assert!(index < self.len());
4256 283 match &self.offsets {
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 4202 284 Some(offsets) => offsets[index] as usize,
54 285 None => self.offset() + index,
286 }
4256 287 }
0 288
0 289 /// Returns the array's value at index `i`.
0 290 /// # Panics
291 /// Panics if index `i` is out of bounds
2182 292 pub fn value(&self, i: usize) -> ArrayRef {
2182 293 let type_id = self.type_id(i);
2182 294 let value_offset = self.value_offset(i);
2182 295 let child = self.child(type_id);
2182 296 child.slice(value_offset, 1)
2182 297 }
298
0 299 /// Returns the names of the types in the union.
0 300 pub fn type_names(&self) -> Vec<&str> {
0 301 match self.data_type() {
0 302 DataType::Union(fields, _) => fields
303 .iter()
0 304 .map(|(_, f)| f.name().as_str())
305 .collect::<Vec<&str>>(),
0 306 _ => unreachable!("Union array's data type is not a union!"),
0 307 }
0 308 }
309
▶︎ 0 310 /// Returns whether the `UnionArray` is dense (or sparse if `false`).
0 311 fn is_dense(&self) -> bool {
0 312 match self.data_type() {
0 313 DataType::Union(_, mode) => mode == &UnionMode::Dense,
0 314 _ => unreachable!("Union array's data type is not a union!"),
315 }
0 316 }
317
0 318 /// Returns a zero-copy slice of this array with the indicated offset and length.
8 319 pub fn slice(&self, offset: usize, length: usize) -> Self {
8 320 let (offsets, fields) = match self.offsets.as_ref() {
321 // If dense union, slice offsets
▶︎ ▶︎ ▶︎ 4 322 Some(offsets) => (Some(offsets.slice(offset, length)), self.fields.clone()),
0 323 // Otherwise need to slice sparse children
0 324 None => {
4 325 let fields = self
0 326 .fields
0 327 .iter()
▶︎ 8 328 .map(|x| x.as_ref().map(|x| x.slice(offset, length)))
329 .collect();
4 330 (None, fields)
4 331 }
332 };
333
8 334 Self {
8 335 data_type: self.data_type.clone(),
8 336 type_ids: self.type_ids.slice(offset, length),
8 337 offsets,
8 338 fields,
0 339 }
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 8 340 }
341
342 /// Deconstruct this array into its constituent parts
343 ///
344 /// # Example
345 ///
346 /// ```
347 /// # use arrow_array::array::UnionArray;
348 /// # use arrow_array::types::Int32Type;
349 /// # use arrow_array::builder::UnionBuilder;
350 /// # use arrow_buffer::ScalarBuffer;
351 /// # fn main() -> Result<(), arrow_schema::ArrowError> {
352 /// let mut builder = UnionBuilder::new_dense();
353 /// builder.append::<Int32Type>("a", 1).unwrap();
354 /// let union_array = builder.build()?;
355 ///
356 /// // Deconstruct into parts
357 /// let (union_fields, type_ids, offsets, children) = union_array.into_parts();
0 358 ///
359 /// // Reconstruct from parts
360 /// let union_array = UnionArray::try_new(
361 /// union_fields,
362 /// type_ids,
363 /// offsets,
364 /// children,
365 /// );
366 /// # Ok(())
0 367 /// # }
0 368 /// ```
0 369 #[allow(clippy::type_complexity)]
6 370 pub fn into_parts(
0 371 self,
0 372 ) -> (
0 373 UnionFields,
▶︎ ▶︎ 0 374 ScalarBuffer<i8>,
375 Option<ScalarBuffer<i32>>,
0 376 Vec<ArrayRef>,
377 ) {
0 378 let Self {
6 379 data_type,
6 380 type_ids,
6 381 offsets,
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 6 382 mut fields,
6 383 } = self;
6 384 match data_type {
6 385 DataType::Union(union_fields, _) => {
▶︎ ▶︎ 80 386 let children = union_fields
81 387 .iter()
81 388 .map(|(type_id, _)| fields[type_id as usize].take().unwrap())
▶︎ ▶︎ 0 389 .collect();
6 390 (union_fields, type_ids, offsets, children)
81 391 }
35 392 _ => unreachable!(),
▶︎ ▶︎ 35 393 }
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 35 394 }
35 395
45 396 /// Computes the logical nulls for a sparse union, optimized for when there's a lot of fields without nulls
▶︎ ▶︎ 46 397 fn mask_sparse_skip_without_nulls(&self, nulls: Vec<(i8, NullBuffer)>) -> BooleanBuffer {
▶︎ 45 398 assert!(false, "expect line not hit with tests");
▶︎ 45 399 // Example logic for a union with 5 fields, a, b & c with nulls, d & e without nulls:
45 400 // let [a_nulls, b_nulls, c_nulls] = nulls;
45 401 // let [is_a, is_b, is_c] = masks;
▶︎ 45 402 // let is_d_or_e = !(is_a | is_b)
45 403 // let union_chunk_nulls = is_d_or_e | (is_b & b_nulls) | (is_c & c_nulls)
0 404 let fold = |(any_nullable_selected, union_nulls), (is_field, field_nulls)| {
0 405 (
131 406 any_nullable_selected | is_field,
81 407 union_nulls | (is_field & field_nulls),
212 408 )
▶︎ 132 409 };
0 410
80 411 self.mask_sparse_helper(
80 412 nulls,
80 413 |chunk, nulls_masks_iters| {
80 414 let (any_nullable_selected, union_nulls) = nulls_masks_iters
80 415 .iter_mut()
0 416 .map(|(field_type_id, field_nulls)| {
▶︎ 80 417 let field_nulls = field_nulls.next().unwrap();
418 let is_field = selection_mask(chunk, *field_type_id);
419
0 420 (is_field, field_nulls)
21 421 })
21 422 .fold((0, 0), fold);
21 423
21 424 !any_nullable_selected | union_nulls
0 425 },
0 426 |remainder, bit_chunks| {
21 427 let (any_nullable_selected, union_nulls) = bit_chunks
▶︎ ▶︎ ▶︎ 10 428 .iter()
▶︎ ▶︎ 11 429 .map(|(field_type_id, field_bit_chunks)| {
0 430 let field_nulls = field_bit_chunks.remainder_bits();
431 let is_field = selection_mask(remainder, *field_type_id);
21 432
0 433 (is_field, field_nulls)
28 434 })
21 435 .fold((0, 0), fold);
0 436
21 437 !any_nullable_selected | union_nulls
0 438 },
21 439 )
▶︎ 21 440 }
21 441
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 21 442 /// Computes the logical nulls for a sparse union, optimized for when there's a lot of fields fully null
▶︎ ▶︎ 4 443 fn mask_sparse_skip_fully_null(&self, mut nulls: Vec<(i8, NullBuffer)>) -> BooleanBuffer {
▶︎ 4 444 let fields = match self.data_type() {
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 2 445 DataType::Union(fields, _) => fields,
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 20 446 _ => unreachable!("Union array's data type is not a union!"),
447 };
▶︎ ▶︎ ▶︎ ▶︎ 20 448
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 8 449 let type_ids = fields.iter().map(|(id, _)| id).collect::<HashSet<_>>();
▶︎ ▶︎ ▶︎ 20 450 let with_nulls = nulls.iter().map(|(id, _)| *id).collect::<HashSet<_>>();
▶︎ ▶︎ ▶︎ ▶︎ 20 451
▶︎ ▶︎ 20 452 let without_nulls_ids = type_ids
453 .difference(&with_nulls)
1 454 .copied()
1 455 .collect::<Vec<_>>();
8 456
4 457 nulls.retain(|(_, nulls)| nulls.null_count() < nulls.len());
89 458
89 459 // Example logic for a union with 6 fields, a, b & c with nulls, d & e without nulls, and f fully_null:
89 460 // let [a_nulls, b_nulls, c_nulls] = nulls;
461 // let [is_a, is_b, is_c, is_d, is_e] = masks;
4 462 // let union_chunk_nulls = is_d | is_e | (is_a & a_nulls) | (is_b & b_nulls) | (is_c & c_nulls)
4 463 self.mask_sparse_helper(
4 464 nulls,
4 465 |chunk, nulls_masks_iters| {
136 466 let union_nulls = nulls_masks_iters.iter_mut().fold(
136 467 0,
136 468 |union_nulls, (field_type_id, nulls_iter)| {
0 469 assert!(false, "expect line not hit with tests");
34 470 let field_nulls = nulls_iter.next().unwrap();
34 471
34 472 if field_nulls == 0 {
0 473 union_nulls
9 474 } else {
0 475 let is_field = selection_mask(chunk, *field_type_id);
9 476
0 477 union_nulls | (is_field & field_nulls)
0 478 }
0 479 },
4 480 );
4 481
4 482 union_nulls | without_nulls_selected(chunk, &without_nulls_ids)
2 483 },
4 484 |remainder, bit_chunks| {
485 let union_nulls =
2 486 bit_chunks
0 487 .iter()
0 488 .fold(0, |union_nulls, (field_type_id, field_bit_chunks)| {
0 489 assert!(false, "expect line not hit with tests");
0 490 let is_field = selection_mask(remainder, *field_type_id);
0 491 let field_nulls = field_bit_chunks.remainder_bits();
0 492
4 493 union_nulls | is_field & field_nulls
4 494 });
2 495
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 4 496 union_nulls | without_nulls_selected(remainder, &without_nulls_ids)
2 497 },
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 3 498 )
▶︎ ▶︎ 2 499 }
0 500
1 501 /// Computes the logical nulls for a sparse union, optimized for when all fields contains nulls
▶︎ 1 502 fn mask_sparse_all_with_nulls_skip_one(&self, nulls: Vec<(i8, NullBuffer)>) -> BooleanBuffer {
0 503 // Example logic for a union with 3 fields, a, b & c, all containing nulls:
504 // let [a_nulls, b_nulls, c_nulls] = nulls;
0 505 // We can skip the first field: it's selection mask is the negation of all others selection mask
2 506 // let [is_b, is_c] = selection_masks;
0 507 // let is_a = !(is_b | is_c)
1 508 // let union_chunk_nulls = (is_a & a_nulls) | (is_b & b_nulls) | (is_c & c_nulls)
1 509 self.mask_sparse_helper(
0 510 nulls,
0 511 |chunk, nulls_masks_iters| {
0 512 let (is_not_first, union_nulls) = nulls_masks_iters[1..] // skip first
0 513 .iter_mut()
▶︎ 0 514 .fold(
0 515 (0, 0),
0 516 |(is_not_first, union_nulls), (field_type_id, nulls_iter)| {
0 517 assert!(false, "expect line not hit with tests");
0 518 let field_nulls = nulls_iter.next().unwrap();
0 519 let is_field = selection_mask(chunk, *field_type_id);
0 520
0 521 (
522 is_not_first | is_field,
0 523 union_nulls | (is_field & field_nulls),
0 524 )
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 0 525 },
0 526 );
▶︎ ▶︎ ▶︎ ▶︎ 0 527 assert!(false, "expect line not hit with tests");
0 528
2 529 let is_first = !is_not_first;
2 530 let first_nulls = nulls_masks_iters[0].1.next().unwrap();
1 531
4 532 (is_first & first_nulls) | union_nulls
4 533 },
▶︎ 2 534 |remainder, bit_chunks| {
1 535 bit_chunks
▶︎ 4 536 .iter()
▶︎ 2 537 .fold(0, |union_nulls, (field_type_id, field_bit_chunks)| {
4 538 let field_nulls = field_bit_chunks.remainder_bits();
▶︎ 4 539 // The same logic as above, except that since this runs at most once,
▶︎ 2 540 // it doesn't make difference to speed-up the first selection mask
▶︎ 2 541 let is_field = selection_mask(remainder, *field_type_id);
2 542
2 543 union_nulls | (is_field & field_nulls)
2 544 })
1 545 },
4 546 )
2 547 }
548
▶︎ 0 549 /// Maps `nulls` to `BitChunk's` and then to `BitChunkIterator's`, then divides `self.type_ids` into exact chunks of 64 values,
0 550 /// calling `mask_chunk` for every exact chunk, and `mask_remainder` for the remainder, if any, collecting the result in a `BooleanBuffer`
▶︎ 2 551 fn mask_sparse_helper(
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 4 552 &self,
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 2 553 nulls: Vec<(i8, NullBuffer)>,
4 554 mut mask_chunk: impl FnMut(&[i8; 64], &mut [(i8, BitChunkIterator)]) -> u64,
2 555 mask_remainder: impl FnOnce(&[i8], &[(i8, BitChunks)]) -> u64,
0 556 ) -> BooleanBuffer {
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 4 557 let bit_chunks = nulls
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 2 558 .iter()
▶︎ 4 559 .map(|(type_id, nulls)| (*type_id, nulls.inner().bit_chunks()))
2 560 .collect::<Vec<_>>();
0 561
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 4 562 let mut nulls_masks_iter = bit_chunks
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 4 563 .iter()
▶︎ ▶︎ ▶︎ ▶︎ 2 564 .map(|(type_id, bit_chunks)| (*type_id, bit_chunks.iter()))
4 565 .collect::<Vec<_>>();
4 566
2 567 let chunks_exact = self.type_ids.chunks_exact(64);
4 568 let remainder = chunks_exact.remainder();
4 569
2 570 let chunks = chunks_exact.map(|chunk| {
2 571 let chunk_array = <&[i8; 64]>::try_from(chunk).unwrap();
572
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 4 573 mask_chunk(chunk_array, &mut nulls_masks_iter)
▶︎ ▶︎ ▶︎ ▶︎ 2 574 });
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 4 575
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 4 576 // SAFETY:
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 2 577 // chunks is a ChunksExact iterator, which implements TrustedLen, and correctly reports its length
2 578 let mut buffer = unsafe { MutableBuffer::from_trusted_len_iter(chunks) };
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 4 579
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 4 580 if !remainder.is_empty() {
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 2 581 buffer.push(mask_remainder(remainder, &bit_chunks));
582 }
12 583
▶︎ ▶︎ 12 584 BooleanBuffer::new(buffer.into(), 0, self.type_ids.len())
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 12 585 }
6 586
587 /// Computes the logical nulls for a sparse or dense union, by gathering individual bits from the null buffer of the selected field
6 588 fn gather_nulls(&self, nulls: Vec<(i8, NullBuffer)>) -> BooleanBuffer {
6 589 let one_null = NullBuffer::new_null(1);
6 590 let one_valid = NullBuffer::new_valid(1);
591
592 // Unsafe code below depend on it:
12 593 // To remove one branch from the loop, if the a type_id is not utilized, or it's logical_nulls is None/all set,
6 594 // we use a null buffer of len 1 and a index_mask of 0, or the true null buffer and usize::MAX otherwise.
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 102 595 // We then unconditionally access the null buffer with index & index_mask,
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 90 596 // which always return 0 for the 1-len buffer, or the true index unchanged otherwise
▶︎ ▶︎ 45 597 // We also use a 256 array, so llvm knows that `type_id as u8 as usize` is always in bounds
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 40 598 let mut logical_nulls_array = [(&one_valid, Mask::Zero); 256];
▶︎ ▶︎ ▶︎ 20 599
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 51 600 for (type_id, nulls) in &nulls {
▶︎ ▶︎ ▶︎ 45 601 if nulls.null_count() == nulls.len() {
602 // Similarly, if all values are null, use a 1-null null-buffer to reduce cache pressure a bit
▶︎ 20 603 logical_nulls_array[*type_id as u8 as usize] = (&one_null, Mask::Zero);
12 604 } else {
▶︎ 25 605 logical_nulls_array[*type_id as u8 as usize] = (nulls, Mask::Max);
▶︎ ▶︎ ▶︎ ▶︎ 2 606 }
▶︎ ▶︎ 1 607 }
▶︎ ▶︎ ▶︎ ▶︎ 12 608
▶︎ ▶︎ 6 609 match &self.offsets {
12 610 Some(offsets) => {
6 611 assert_eq!(self.type_ids.len(), offsets.len());
12 612
6 613 BooleanBuffer::collect_bool(self.type_ids.len(), |i| unsafe {
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 12 614 // SAFETY: BooleanBuffer::collect_bool calls us 0..self.type_ids.len()
▶︎ ▶︎ ▶︎ 6 615 let type_id = *self.type_ids.get_unchecked(i);
616 // SAFETY: We asserted that offsets len and self.type_ids len are equal
6 617 let offset = *offsets.get_unchecked(i);
618
▶︎ 6 619 let (nulls, offset_mask) = &logical_nulls_array[type_id as u8 as usize];
620
12 621 // SAFETY:
6 622 // If offset_mask is Max
12 623 // 1. Offset validity is checked at union creation
12 624 // 2. If the null buffer len equals it's array len is checked at array creation
6 625 // If offset_mask is Zero, the null buffer len is 1
6 626 nulls
▶︎ ▶︎ ▶︎ ▶︎ 672 627 .inner()
▶︎ ▶︎ 322 628 .value_unchecked(offset as usize & *offset_mask as usize)
672 629 })
322 630 }
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 672 631 None => {
▶︎ ▶︎ ▶︎ 336 632 BooleanBuffer::collect_bool(self.type_ids.len(), |index| unsafe {
633 // SAFETY: BooleanBuffer::collect_bool calls us 0..self.type_ids.len()
336 634 let type_id = *self.type_ids.get_unchecked(index);
635
▶︎ 336 636 let (nulls, index_mask) = &logical_nulls_array[type_id as u8 as usize];
637
672 638 // SAFETY:
672 639 // If index_mask is Max
322 640 // 1. On sparse union, every child len match it's parent, this is checked at union creation
641 // 2. If the null buffer len equals it's array len is checked at array creation
▶︎ ▶︎ ▶︎ ▶︎ 12 642 // If index_mask is Zero, the null buffer len is 1
▶︎ ▶︎ 336 643 nulls.inner().value_unchecked(index & *index_mask as usize)
336 644 })
645 }
76 646 }
▶︎ 76 647 }
76 648 }
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 38 649
▶︎ ▶︎ ▶︎ ▶︎ 0 650 impl From<ArrayData> for UnionArray {
76 651 fn from(data: ArrayData) -> Self {
42 652 let (fields, mode) = match data.data_type() {
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 42 653 DataType::Union(fields, mode) => (fields, *mode),
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 42 654 d => panic!("UnionArray expected ArrayData with type Union got {d}"),
42 655 };
38 656 let (type_ids, offsets) = match mode {
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 34 657 UnionMode::Sparse => (
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 34 658 ScalarBuffer::new(data.buffers()[0].clone(), data.offset(), data.len()),
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 34 659 None,
▶︎ ▶︎ 34 660 ),
34 661 UnionMode::Dense => (
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 34 662 ScalarBuffer::new(data.buffers()[0].clone(), data.offset(), data.len()),
▶︎ ▶︎ 34 663 Some(ScalarBuffer::new(
▶︎ 17 664 data.buffers()[1].clone(),
17 665 data.offset(),
▶︎ ▶︎ ▶︎ ▶︎ 268 666 data.len(),
▶︎ 132 667 )),
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 342 668 ),
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 268 669 };
▶︎ ▶︎ 134 670
134 671 let max_id = fields.iter().map(|(i, _)| i).max().unwrap_or_default() as usize;
▶︎ 76 672 let mut boxed_fields = vec![None; max_id + 1];
172 673 for (cd, (field_id, _)) in data.child_data().iter().zip(fields.iter()) {
▶︎ 134 674 boxed_fields[field_id as usize] = Some(make_array(cd.clone()));
76 675 }
38 676 Self {
▶︎ ▶︎ ▶︎ 76 677 data_type: data.data_type().clone(),
▶︎ ▶︎ 38 678 type_ids,
38 679 offsets,
38 680 fields: boxed_fields,
4 681 }
▶︎ ▶︎ ▶︎ 38 682 }
▶︎ 4 683 }
4 684
2 685 impl From<UnionArray> for ArrayData {
2 686 fn from(array: UnionArray) -> Self {
4 687 let len = array.len();
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 2 688 let f = match &array.data_type {
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 2 689 DataType::Union(f, _) => f,
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 690 _ => unreachable!(),
691 };
▶︎ ▶︎ ▶︎ ▶︎ 4 692 let buffers = match array.offsets {
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 2 693 Some(o) => vec![array.type_ids.into_inner(), o.into_inner()],
▶︎ ▶︎ 8 694 None => vec![array.type_ids.into_inner()],
4 695 };
2 696
▶︎ ▶︎ 4 697 let child = f
▶︎ 2 698 .iter()
4 699 .map(|(i, _)| array.fields[i as usize].as_ref().unwrap().to_data())
4 700 .collect();
4 701
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 4 702 let builder = ArrayDataBuilder::new(array.data_type)
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 2 703 .len(len)
2 704 .buffers(buffers)
2 705 .child_data(child);
12 706 unsafe { builder.build_unchecked() }
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 6 707 }
12 708 }
6 709
4 710 impl Array for UnionArray {
6 711 fn as_any(&self) -> &dyn Any {
4 712 self
6 713 }
0 714
2 715 fn to_data(&self) -> ArrayData {
2 716 self.clone().into()
2 717 }
40 718
40 719 fn into_data(self) -> ArrayData {
40 720 self.into()
20 721 }
4 722
20 723 fn data_type(&self) -> &DataType {
20 724 &self.data_type
20 725 }
4324 726
4324 727 fn slice(&self, offset: usize, length: usize) -> ArrayRef {
4324 728 Arc::new(self.slice(offset, length))
2162 729 }
0 730
2162 731 fn len(&self) -> usize {
2162 732 self.type_ids.len()
2162 733 }
54 734
27 735 fn is_empty(&self) -> bool {
54 736 self.type_ids.is_empty()
27 737 }
0 738
27 739 fn offset(&self) -> usize {
0 740 0
27 741 }
28 742
28 743 fn nulls(&self) -> Option<&NullBuffer> {
28 744 None
14 745 }
0 746
14 747 fn logical_nulls(&self) -> Option<NullBuffer> {
28 748 let fields = match self.data_type() {
14 749 DataType::Union(fields, _) => fields,
1 750 _ => unreachable!(),
751 };
752
14 753 if fields.len() <= 1 {
1 754 return self
755 .fields
756 .iter()
757 .flatten()
26 758 .map(Array::logical_nulls)
13 759 .next()
▶︎ ▶︎ ▶︎ ▶︎ 162 760 .flatten();
▶︎ ▶︎ 110 761 }
55 762
13 763 let logical_nulls = fields
▶︎ ▶︎ 26 764 .iter()
▶︎ 81 765 .filter_map(|(type_id, _)| Some((type_id, self.child(type_id).logical_nulls()?)))
55 766 .filter(|(_, nulls)| nulls.null_count() > 0)
13 767 .collect::<Vec<_>>();
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 22 768
▶︎ ▶︎ ▶︎ ▶︎ 13 769 if logical_nulls.is_empty() {
110 770 return None;
55 771 }
772
▶︎ ▶︎ 22 773 let fully_null_count = logical_nulls
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 11 774 .iter()
▶︎ ▶︎ ▶︎ ▶︎ 55 775 .filter(|(_, nulls)| nulls.null_count() == nulls.len())
6 776 .count();
3 777
▶︎ ▶︎ 11 778 if fully_null_count == fields.len() {
▶︎ 2 779 if let Some((_, exactly_sized)) = logical_nulls
780 .iter()
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 3 781 .find(|(_, nulls)| nulls.len() == self.len())
▶︎ ▶︎ ▶︎ ▶︎ 1 782 {
2 783 return Some(exactly_sized.clone());
1 784 }
▶︎ ▶︎ ▶︎ ▶︎ 2 785
▶︎ ▶︎ 1 786 if let Some((_, bigger)) = logical_nulls
787 .iter()
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 788 .find(|(_, nulls)| nulls.len() > self.len())
▶︎ ▶︎ ▶︎ ▶︎ 0 789 {
1 790 return Some(bigger.slice(0, self.len()));
18 791 }
▶︎ ▶︎ 9 792
▶︎ ▶︎ ▶︎ 1 793 return Some(NullBuffer::new_null(self.len()));
794 }
795
9 796 let boolean_buffer = match &self.offsets {
1 797 Some(_) => self.gather_nulls(logical_nulls),
798 None => {
799 enum SparseStrategy {
800 Gather,
801 AllNullsSkipOne,
802 MixedSkipWithoutNulls,
803 MixedSkipFullyNull,
804 }
805
806 // This is the threshold where masking becomes slower than gather
807 // TODO: test on avx512f(feature is still unstable)
16 808 let gather_relative_cost = if cfg!(target_feature = "avx2") {
8 809 10
810 } else if cfg!(target_feature = "sse4.1") {
811 3
16 812 } else {
16 813 2
16 814 };
16 815
▶︎ ▶︎ 16 816 // For masking strategies, the cost is the number of selection masks computed per chunk of 64 type ids
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 16 817 let strategies = [
▶︎ ▶︎ 8 818 (SparseStrategy::Gather, gather_relative_cost, true),
16 819 (
16 820 SparseStrategy::AllNullsSkipOne,
16 821 fields.len() - 1,
8 822 fields.len() == logical_nulls.len(),
823 ),
16 824 (
16 825 SparseStrategy::MixedSkipWithoutNulls,
▶︎ ▶︎ 16 826 logical_nulls.len(),
▶︎ 8 827 true,
828 ),
8 829 (
8 830 SparseStrategy::MixedSkipFullyNull,
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 16 831 fields.len() - fully_null_count,
▶︎ ▶︎ ▶︎ ▶︎ 8 832 true,
64 833 ),
54 834 ];
27 835
8 836 let (strategy, _, _) = strategies
16 837 .iter()
▶︎ ▶︎ 32 838 .filter(|(_, _, applicable)| *applicable)
▶︎ 27 839 .min_by_key(|(_, cost, _)| cost)
▶︎ ▶︎ 2 840 .unwrap();
▶︎ 1 841
8 842 match strategy {
▶︎ ▶︎ ▶︎ 5 843 SparseStrategy::Gather => self.gather_nulls(logical_nulls),
▶︎ ▶︎ 0 844 SparseStrategy::AllNullsSkipOne => {
1 845 self.mask_sparse_all_with_nulls_skip_one(logical_nulls)
▶︎ ▶︎ 4 846 }
▶︎ 2 847 SparseStrategy::MixedSkipWithoutNulls => {
▶︎ 0 848 self.mask_sparse_skip_without_nulls(logical_nulls)
849 }
850 SparseStrategy::MixedSkipFullyNull => {
2 851 self.mask_sparse_skip_fully_null(logical_nulls)
▶︎ ▶︎ 18 852 }
▶︎ 9 853 }
▶︎ ▶︎ 18 854 }
▶︎ 18 855 };
9 856
9 857 let null_buffer = NullBuffer::from(boolean_buffer);
0 858
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 28 859 if null_buffer.null_count() > 0 {
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 14 860 Some(null_buffer)
861 } else {
0 862 None
2116 863 }
▶︎ ▶︎ ▶︎ 1058 864 }
2116 865
1058 866 /// Union types always return non null as there is no validity buffer.
867 /// To check validity correctly you must check the logical nulls.
1058 868 fn is_null(&self, _index: usize) -> bool {
20 869 false
1058 870 }
20 871
10 872 /// Union types always return non null as there is no validity buffer.
873 /// To check validity correctly you must check the logical nulls.
10 874 fn is_valid(&self, _index: usize) -> bool {
8 875 true
10 876 }
8 877
4 878 /// Union types always return 0 null count as there is no validity buffer.
0 879 /// To get null count correctly you must check the logical nulls.
4 880 fn null_count(&self) -> usize {
▶︎ ▶︎ ▶︎ 0 881 0
▶︎ ▶︎ 4 882 }
0 883
0 884 fn get_buffer_memory_size(&self) -> usize {
0 885 let mut sum = self.type_ids.inner().capacity();
▶︎ 0 886 if let Some(o) = self.offsets.as_ref() {
0 887 sum += o.inner().capacity()
0 888 }
0 889 self.fields
0 890 .iter()
0 891 .flat_map(|x| x.as_ref().map(|x| x.get_buffer_memory_size()))
0 892 .sum::<usize>()
▶︎ ▶︎ ▶︎ 0 893 + sum
▶︎ ▶︎ 0 894 }
0 895
0 896 fn get_array_memory_size(&self) -> usize {
0 897 let mut sum = self.type_ids.inner().capacity();
▶︎ 0 898 if let Some(o) = self.offsets.as_ref() {
0 899 sum += o.inner().capacity()
0 900 }
0 901 std::mem::size_of::<Self>()
0 902 + self
0 903 .fields
0 904 .iter()
0 905 .flat_map(|x| x.as_ref().map(|x| x.get_array_memory_size()))
906 .sum::<usize>()
0 907 + sum
0 908 }
0 909 }
0 910
0 911 impl std::fmt::Debug for UnionArray {
0 912 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
▶︎ ▶︎ ▶︎ 0 913 let header = if self.is_dense() {
▶︎ ▶︎ 0 914 "UnionArray(Dense)\n["
▶︎ ▶︎ ▶︎ 0 915 } else {
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 0 916 "UnionArray(Sparse)\n["
▶︎ ▶︎ 0 917 };
▶︎ ▶︎ ▶︎ ▶︎ 0 918 writeln!(f, "{header}")?;
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 0 919
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 0 920 writeln!(f, "-- type id buffer:")?;
▶︎ ▶︎ ▶︎ 0 921 writeln!(f, "{:?}", self.type_ids)?;
922
▶︎ 0 923 if let Some(offsets) = &self.offsets {
▶︎ 0 924 writeln!(f, "-- offsets buffer:")?;
▶︎ 0 925 writeln!(f, "{:?}", offsets)?;
0 926 }
927
▶︎ ▶︎ ▶︎ 0 928 let fields = match self.data_type() {
▶︎ ▶︎ 0 929 DataType::Union(fields, _) => fields,
▶︎ ▶︎ ▶︎ 0 930 _ => unreachable!(),
▶︎ ▶︎ 0 931 };
932
▶︎ 0 933 for (type_id, field) in fields.iter() {
0 934 let child = self.child(type_id);
▶︎ 0 935 writeln!(
0 936 f,
▶︎ ▶︎ ▶︎ 0 937 "-- child {}: \"{}\" ({:?})",
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 0 938 type_id,
▶︎ ▶︎ 0 939 field.name(),
0 940 field.data_type()
0 941 )?;
▶︎ 0 942 std::fmt::Debug::fmt(child, f)?;
▶︎ 0 943 writeln!(f)?;
0 944 }
0 945 writeln!(f, "]")
0 946 }
947 }
948
0 949 #[derive(Copy, Clone)]
950 #[repr(usize)]
951 enum Mask {
952 Zero = 0,
12 953 // false positive, see https://github.com/rust-lang/rust-clippy/issues/8043
12 954 #[allow(clippy::enum_clike_unportable_variant)]
6 955 Max = usize::MAX,
956 }
957
340 958 fn selection_mask(chunk: &[i8], type_id: i8) -> u64 {
340 959 chunk
340 960 .iter()
170 961 .copied()
6 962 .enumerate()
170 963 .fold(0, |packed, (bit_idx, v)| {
170 964 packed | ((v == type_id) as u64) << bit_idx
170 965 })
8 966 }
8 967
8 968 fn without_nulls_selected(chunk: &[i8], without_nulls_ids: &[i8]) -> u64 {
8 969 without_nulls_ids
4 970 .iter()
4 971 .fold(0, |fully_valid_selected, field_type_id| {
4 972 fully_valid_selected | selection_mask(chunk, *field_type_id)
4 973 })
4 974 }
975
976 #[cfg(test)]
977 mod tests {
978 use super::*;
979 use std::collections::HashSet;
980
981 use crate::array::Int8Type;
982 use crate::builder::UnionBuilder;
983 use crate::cast::AsArray;
984 use crate::types::{Float32Type, Float64Type, Int32Type, Int64Type};
985 use crate::{Float64Array, Int32Array, Int64Array, StringArray};
2 986 use crate::{Int8Array, RecordBatch};
2 987 use arrow_buffer::Buffer;
2 988 use arrow_schema::{Field, Schema};
2 989
2 990 #[test]
2 991 fn test_dense_i32() {
2 992 let mut builder = UnionBuilder::new_dense();
2 993 builder.append::<Int32Type>("a", 1).unwrap();
2 994 builder.append::<Int32Type>("b", 2).unwrap();
2 995 builder.append::<Int32Type>("c", 3).unwrap();
1 996 builder.append::<Int32Type>("a", 4).unwrap();
2 997 builder.append::<Int32Type>("c", 5).unwrap();
▶︎ 2 998 builder.append::<Int32Type>("a", 6).unwrap();
▶︎ 2 999 builder.append::<Int32Type>("b", 7).unwrap();
1 1000 let union = builder.build().unwrap();
1001
2 1002 let expected_type_ids = vec![0_i8, 1, 2, 0, 2, 0, 1];
▶︎ 16 1003 let expected_offsets = vec![0_i32, 0, 0, 1, 1, 2, 1];
14 1004 let expected_array_values = [1_i32, 2, 3, 4, 5, 6, 7];
7 1005
1006 // Check type ids
1 1007 assert_eq!(*union.type_ids(), expected_type_ids);
8 1008 for (i, id) in expected_type_ids.iter().enumerate() {
16 1009 assert_eq!(id, &union.type_id(i));
14 1010 }
7 1011
1012 // Check offsets
1 1013 assert_eq!(*union.offsets().unwrap(), expected_offsets);
8 1014 for (i, id) in expected_offsets.iter().enumerate() {
7 1015 assert_eq!(union.value_offset(i), *id as usize);
1 1016 }
1017
2 1018 // Check data
2 1019 assert_eq!(
1 1020 *union.child(0).as_primitive::<Int32Type>().values(),
1021 [1_i32, 4, 6]
2 1022 );
2 1023 assert_eq!(
1 1024 *union.child(1).as_primitive::<Int32Type>().values(),
1025 [2_i32, 7]
1026 );
2 1027 assert_eq!(
16 1028 *union.child(2).as_primitive::<Int32Type>().values(),
▶︎ 14 1029 [3_i32, 5]
▶︎ 14 1030 );
14 1031
14 1032 assert_eq!(expected_array_values.len(), union.len());
14 1033 for (i, expected_value) in expected_array_values.iter().enumerate() {
▶︎ 14 1034 assert!(!union.is_null(i));
14 1035 let slot = union.value(i);
▶︎ ▶︎ 7 1036 let slot = slot.as_any().downcast_ref::<Int32Array>().unwrap();
▶︎ ▶︎ 7 1037 assert_eq!(slot.len(), 1);
7 1038 let value = slot.value(0);
7 1039 assert_eq!(expected_value, &value);
7 1040 }
▶︎ ▶︎ 2 1041 }
1 1042
2 1043 #[test]
2 1044 #[cfg_attr(miri, ignore)]
2 1045 fn test_dense_i32_large() {
1 1046 let mut builder = UnionBuilder::new_dense();
2 1047
1 1048 let expected_type_ids = vec![0_i8; 1024];
2048 1049 let expected_offsets: Vec<_> = (0..1024).collect();
1024 1050 let expected_array_values: Vec<_> = (1..=1024).collect();
2 1051
1 1052 expected_array_values
1053 .iter()
1024 1054 .for_each(|v| builder.append::<Int32Type>("a", *v).unwrap());
2050 1055
2048 1056 let union = builder.build().unwrap();
1024 1057
1058 // Check type ids
1 1059 assert_eq!(*union.type_ids(), expected_type_ids);
1025 1060 for (i, id) in expected_type_ids.iter().enumerate() {
2050 1061 assert_eq!(id, &union.type_id(i));
2048 1062 }
1024 1063
1064 // Check offsets
2050 1065 assert_eq!(*union.offsets().unwrap(), expected_offsets);
▶︎ 2048 1066 for (i, id) in expected_offsets.iter().enumerate() {
▶︎ 2048 1067 assert_eq!(union.value_offset(i), *id as usize);
2048 1068 }
2048 1069
2048 1070 for (i, expected_value) in expected_array_values.iter().enumerate() {
▶︎ 2048 1071 assert!(!union.is_null(i));
2048 1072 let slot = union.value(i);
▶︎ ▶︎ 1024 1073 let slot = slot.as_primitive::<Int32Type>();
▶︎ ▶︎ 1024 1074 assert_eq!(slot.len(), 1);
1024 1075 let value = slot.value(0);
1024 1076 assert_eq!(expected_value, &value);
1024 1077 }
▶︎ ▶︎ 2 1078 }
2 1079
2 1080 #[test]
2 1081 fn test_dense_mixed() {
2 1082 let mut builder = UnionBuilder::new_dense();
2 1083 builder.append::<Int32Type>("a", 1).unwrap();
1 1084 builder.append::<Int64Type>("c", 3).unwrap();
2 1085 builder.append::<Int32Type>("a", 4).unwrap();
12 1086 builder.append::<Int64Type>("c", 5).unwrap();
10 1087 builder.append::<Int32Type>("a", 6).unwrap();
▶︎ 10 1088 let union = builder.build().unwrap();
▶︎ 10 1089
5 1090 assert_eq!(5, union.len());
6 1091 for i in 0..union.len() {
5 1092 let slot = union.value(i);
▶︎ 5 1093 assert!(!union.is_null(i));
5 1094 match i {
1 1095 0 => {
1 1096 let slot = slot.as_any().downcast_ref::<Int32Array>().unwrap();
2 1097 assert_eq!(slot.len(), 1);
2 1098 let value = slot.value(0);
2 1099 assert_eq!(1_i32, value);
2 1100 }
1 1101 1 => {
1 1102 let slot = slot.as_any().downcast_ref::<Int64Array>().unwrap();
2 1103 assert_eq!(slot.len(), 1);
2 1104 let value = slot.value(0);
2 1105 assert_eq!(3_i64, value);
2 1106 }
1 1107 2 => {
1 1108 let slot = slot.as_any().downcast_ref::<Int32Array>().unwrap();
2 1109 assert_eq!(slot.len(), 1);
2 1110 let value = slot.value(0);
2 1111 assert_eq!(4_i32, value);
2 1112 }
1 1113 3 => {
1 1114 let slot = slot.as_any().downcast_ref::<Int64Array>().unwrap();
2 1115 assert_eq!(slot.len(), 1);
2 1116 let value = slot.value(0);
2 1117 assert_eq!(5_i64, value);
2 1118 }
1 1119 4 => {
1 1120 let slot = slot.as_any().downcast_ref::<Int32Array>().unwrap();
1 1121 assert_eq!(slot.len(), 1);
10 1122 let value = slot.value(0);
▶︎ ▶︎ 5 1123 assert_eq!(6_i32, value);
▶︎ ▶︎ 1 1124 }
0 1125 _ => unreachable!(),
2 1126 }
5 1127 }
▶︎ ▶︎ ▶︎ 2 1128 }
▶︎ 2 1129
▶︎ 2 1130 #[test]
▶︎ 2 1131 fn test_dense_mixed_with_nulls() {
▶︎ 2 1132 let mut builder = UnionBuilder::new_dense();
▶︎ 2 1133 builder.append::<Int32Type>("a", 1).unwrap();
1 1134 builder.append::<Int64Type>("c", 3).unwrap();
2 1135 builder.append::<Int32Type>("a", 10).unwrap();
12 1136 builder.append_null::<Int32Type>("a").unwrap();
▶︎ 10 1137 builder.append::<Int32Type>("a", 6).unwrap();
▶︎ ▶︎ ▶︎ ▶︎ 10 1138 let union = builder.build().unwrap();
▶︎ 6 1139
5 1140 assert_eq!(5, union.len());
▶︎ 6 1141 for i in 0..union.len() {
▶︎ ▶︎ ▶︎ 5 1142 let slot = union.value(i);
▶︎ ▶︎ 5 1143 match i {
▶︎ ▶︎ 2 1144 0 => {
▶︎ 1 1145 let slot = slot.as_any().downcast_ref::<Int32Array>().unwrap();
▶︎ 1 1146 assert!(!slot.is_null(0));
2 1147 assert_eq!(slot.len(), 1);
▶︎ 2 1148 let value = slot.value(0);
▶︎ ▶︎ ▶︎ 2 1149 assert_eq!(1_i32, value);
▶︎ ▶︎ 2 1150 }
▶︎ ▶︎ 2 1151 1 => {
▶︎ 1 1152 let slot = slot.as_any().downcast_ref::<Int64Array>().unwrap();
▶︎ 1 1153 assert!(!slot.is_null(0));
2 1154 assert_eq!(slot.len(), 1);
▶︎ 2 1155 let value = slot.value(0);
▶︎ ▶︎ ▶︎ 2 1156 assert_eq!(3_i64, value);
▶︎ ▶︎ 2 1157 }
▶︎ ▶︎ 2 1158 2 => {
▶︎ 1 1159 let slot = slot.as_any().downcast_ref::<Int32Array>().unwrap();
▶︎ ▶︎ 2 1160 assert!(!slot.is_null(0));
1 1161 assert_eq!(slot.len(), 1);
▶︎ ▶︎ 2 1162 let value = slot.value(0);
▶︎ ▶︎ 2 1163 assert_eq!(10_i32, value);
▶︎ ▶︎ ▶︎ 2 1164 }
▶︎ ▶︎ ▶︎ 2 1165 3 => assert!(slot.is_null(0)),
▶︎ ▶︎ 2 1166 4 => {
▶︎ 1 1167 let slot = slot.as_any().downcast_ref::<Int32Array>().unwrap();
▶︎ 1 1168 assert!(!slot.is_null(0));
1 1169 assert_eq!(slot.len(), 1);
10 1170 let value = slot.value(0);
▶︎ ▶︎ 2 1171 assert_eq!(6_i32, value);
0 1172 }
▶︎ ▶︎ ▶︎ 5 1173 _ => unreachable!(),
▶︎ ▶︎ 1 1174 }
5 1175 }
▶︎ ▶︎ 1 1176 }
1 1177
1 1178 #[test]
1 1179 fn test_dense_mixed_with_nulls_and_offset() {
1 1180 let mut builder = UnionBuilder::new_dense();
1 1181 builder.append::<Int32Type>("a", 1).unwrap();
1 1182 builder.append::<Int64Type>("c", 3).unwrap();
1 1183 builder.append::<Int32Type>("a", 10).unwrap();
1 1184 builder.append_null::<Int32Type>("a").unwrap();
1 1185 builder.append::<Int32Type>("a", 6).unwrap();
1 1186 let union = builder.build().unwrap();
4 1187
3 1188 let slice = union.slice(2, 3);
3 1189 let new_union = slice.as_any().downcast_ref::<UnionArray>().unwrap();
1 1190
4 1191 assert_eq!(3, new_union.len());
▶︎ 4 1192 for i in 0..new_union.len() {
3 1193 let slot = new_union.value(i);
3 1194 match i {
1 1195 0 => {
▶︎ 1 1196 let slot = slot.as_any().downcast_ref::<Int32Array>().unwrap();
▶︎ ▶︎ ▶︎ 1 1197 assert!(!slot.is_null(0));
1 1198 assert_eq!(slot.len(), 1);
1 1199 let value = slot.value(0);
▶︎ 1 1200 assert_eq!(10_i32, value);
▶︎ 1 1201 }
▶︎ ▶︎ 1 1202 1 => assert!(slot.is_null(0)),
1 1203 2 => {
▶︎ 1 1204 let slot = slot.as_any().downcast_ref::<Int32Array>().unwrap();
▶︎ ▶︎ 1 1205 assert!(!slot.is_null(0));
1 1206 assert_eq!(slot.len(), 1);
3 1207 let value = slot.value(0);
▶︎ ▶︎ 1 1208 assert_eq!(6_i32, value);
0 1209 }
0 1210 _ => unreachable!(),
3 1211 }
▶︎ ▶︎ ▶︎ 3 1212 }
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1213 }
▶︎ 1 1214
1 1215 #[test]
▶︎ 1 1216 fn test_dense_mixed_with_str() {
▶︎ ▶︎ ▶︎ 1 1217 let string_array = StringArray::from(vec!["foo", "bar", "baz"]);
▶︎ ▶︎ ▶︎ 1 1218 let int_array = Int32Array::from(vec![5, 6]);
▶︎ ▶︎ 1 1219 let float_array = Float64Array::from(vec![10.0]);
1 1220
1 1221 let type_ids = [1, 0, 0, 2, 0, 1].into_iter().collect::<ScalarBuffer<i8>>();
1 1222 let offsets = [0, 0, 1, 0, 2, 1]
1 1223 .into_iter()
1 1224 .collect::<ScalarBuffer<i32>>();
1 1225
1 1226 let fields = [
1 1227 (0, Arc::new(Field::new("A", DataType::Utf8, false))),
1 1228 (1, Arc::new(Field::new("B", DataType::Int32, false))),
1 1229 (2, Arc::new(Field::new("C", DataType::Float64, false))),
1 1230 ]
1 1231 .into_iter()
1 1232 .collect::<UnionFields>();
1 1233 let children = [
1 1234 Arc::new(string_array) as Arc<dyn Array>,
1 1235 Arc::new(int_array),
▶︎ ▶︎ ▶︎ 1 1236 Arc::new(float_array),
0 1237 ]
1 1238 .into_iter()
1 1239 .collect();
▶︎ ▶︎ ▶︎ 7 1240 let array =
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 6 1241 UnionArray::try_new(fields, type_ids.clone(), Some(offsets.clone()), children).unwrap();
1242
1 1243 // Check type ids
7 1244 assert_eq!(*array.type_ids(), type_ids);
7 1245 for (i, id) in type_ids.iter().enumerate() {
7 1246 assert_eq!(id, &array.type_id(i));
6 1247 }
1248
1 1249 // Check offsets
7 1250 assert_eq!(*array.offsets().unwrap(), offsets);
7 1251 for (i, id) in offsets.iter().enumerate() {
6 1252 assert_eq!(*id as usize, array.value_offset(i));
1 1253 }
1 1254
1 1255 // Check values
1 1256 assert_eq!(6, array.len());
1 1257
1 1258 let slot = array.value(0);
1 1259 let value = slot.as_any().downcast_ref::<Int32Array>().unwrap().value(0);
1 1260 assert_eq!(5, value);
1 1261
1 1262 let slot = array.value(1);
1 1263 let value = slot
1264 .as_any()
1 1265 .downcast_ref::<StringArray>()
1 1266 .unwrap()
1 1267 .value(0);
1 1268 assert_eq!("foo", value);
1 1269
1 1270 let slot = array.value(2);
1 1271 let value = slot
1272 .as_any()
1 1273 .downcast_ref::<StringArray>()
1 1274 .unwrap()
1 1275 .value(0);
1 1276 assert_eq!("bar", value);
1 1277
1 1278 let slot = array.value(3);
1 1279 let value = slot
1280 .as_any()
1 1281 .downcast_ref::<Float64Array>()
1 1282 .unwrap()
1 1283 .value(0);
1 1284 assert_eq!(10.0, value);
1 1285
1 1286 let slot = array.value(4);
1 1287 let value = slot
1288 .as_any()
1 1289 .downcast_ref::<StringArray>()
1 1290 .unwrap()
1 1291 .value(0);
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1292 assert_eq!("baz", value);
1 1293
1 1294 let slot = array.value(5);
1 1295 let value = slot.as_any().downcast_ref::<Int32Array>().unwrap().value(0);
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1296 assert_eq!(6, value);
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1297 }
1 1298
1 1299 #[test]
1 1300 fn test_sparse_i32() {
1 1301 let mut builder = UnionBuilder::new_sparse();
1 1302 builder.append::<Int32Type>("a", 1).unwrap();
1 1303 builder.append::<Int32Type>("b", 2).unwrap();
1 1304 builder.append::<Int32Type>("c", 3).unwrap();
1 1305 builder.append::<Int32Type>("a", 4).unwrap();
1 1306 builder.append::<Int32Type>("c", 5).unwrap();
1 1307 builder.append::<Int32Type>("a", 6).unwrap();
1 1308 builder.append::<Int32Type>("b", 7).unwrap();
1 1309 let union = builder.build().unwrap();
1 1310
8 1311 let expected_type_ids = vec![0_i8, 1, 2, 0, 2, 0, 1];
7 1312 let expected_array_values = [1_i32, 2, 3, 4, 5, 6, 7];
1313
1 1314 // Check type ids
8 1315 assert_eq!(*union.type_ids(), expected_type_ids);
▶︎ 8 1316 for (i, id) in expected_type_ids.iter().enumerate() {
7 1317 assert_eq!(id, &union.type_id(i));
1318 }
1 1319
▶︎ 1 1320 // Check offsets, sparse union should only have a single buffer
▶︎ ▶︎ 1 1321 assert!(union.offsets().is_none());
1322
1 1323 // Check data
1 1324 assert_eq!(
1 1325 *union.child(0).as_primitive::<Int32Type>().values(),
1326 [1_i32, 0, 0, 4, 0, 6, 0],
1 1327 );
1 1328 assert_eq!(
1 1329 *union.child(1).as_primitive::<Int32Type>().values(),
1330 [0_i32, 2_i32, 0, 0, 0, 0, 7]
1 1331 );
1 1332 assert_eq!(
8 1333 *union.child(2).as_primitive::<Int32Type>().values(),
▶︎ 7 1334 [0_i32, 0, 3_i32, 0, 5, 0, 0]
7 1335 );
7 1336
8 1337 assert_eq!(expected_array_values.len(), union.len());
▶︎ 8 1338 for (i, expected_value) in expected_array_values.iter().enumerate() {
▶︎ ▶︎ 7 1339 assert!(!union.is_null(i));
7 1340 let slot = union.value(i);
▶︎ ▶︎ 7 1341 let slot = slot.as_any().downcast_ref::<Int32Array>().unwrap();
7 1342 assert_eq!(slot.len(), 1);
7 1343 let value = slot.value(0);
7 1344 assert_eq!(expected_value, &value);
▶︎ ▶︎ 7 1345 }
▶︎ ▶︎ ▶︎ ▶︎ 1 1346 }
1 1347
1 1348 #[test]
1 1349 fn test_sparse_mixed() {
1 1350 let mut builder = UnionBuilder::new_sparse();
1 1351 builder.append::<Int32Type>("a", 1).unwrap();
1 1352 builder.append::<Float64Type>("c", 3.0).unwrap();
1 1353 builder.append::<Int32Type>("a", 4).unwrap();
1 1354 builder.append::<Float64Type>("c", 5.0).unwrap();
1 1355 builder.append::<Int32Type>("a", 6).unwrap();
1 1356 let union = builder.build().unwrap();
6 1357
5 1358 let expected_type_ids = vec![0_i8, 1, 0, 1, 0];
1359
1 1360 // Check type ids
6 1361 assert_eq!(*union.type_ids(), expected_type_ids);
▶︎ 6 1362 for (i, id) in expected_type_ids.iter().enumerate() {
5 1363 assert_eq!(id, &union.type_id(i));
6 1364 }
5 1365
▶︎ ▶︎ 5 1366 // Check offsets, sparse union should only have a single buffer, i.e. no offsets
▶︎ ▶︎ 5 1367 assert!(union.offsets().is_none());
6 1368
6 1369 for i in 0..union.len() {
▶︎ 5 1370 let slot = union.value(i);
▶︎ ▶︎ 5 1371 assert!(!union.is_null(i));
5 1372 match i {
1 1373 0 => {
1 1374 let slot = slot.as_any().downcast_ref::<Int32Array>().unwrap();
1 1375 assert_eq!(slot.len(), 1);
1 1376 let value = slot.value(0);
1 1377 assert_eq!(1_i32, value);
1 1378 }
1 1379 1 => {
1 1380 let slot = slot.as_any().downcast_ref::<Float64Array>().unwrap();
1 1381 assert_eq!(slot.len(), 1);
1 1382 let value = slot.value(0);
1 1383 assert_eq!(value, 3_f64);
1 1384 }
1 1385 2 => {
1 1386 let slot = slot.as_any().downcast_ref::<Int32Array>().unwrap();
1 1387 assert_eq!(slot.len(), 1);
1 1388 let value = slot.value(0);
1 1389 assert_eq!(4_i32, value);
1 1390 }
1 1391 3 => {
1 1392 let slot = slot.as_any().downcast_ref::<Float64Array>().unwrap();
1 1393 assert_eq!(slot.len(), 1);
1 1394 let value = slot.value(0);
1 1395 assert_eq!(5_f64, value);
1 1396 }
1 1397 4 => {
1 1398 let slot = slot.as_any().downcast_ref::<Int32Array>().unwrap();
1 1399 assert_eq!(slot.len(), 1);
5 1400 let value = slot.value(0);
▶︎ ▶︎ 1 1401 assert_eq!(6_i32, value);
0 1402 }
0 1403 _ => unreachable!(),
5 1404 }
▶︎ ▶︎ 5 1405 }
▶︎ ▶︎ ▶︎ ▶︎ 1 1406 }
1 1407
1 1408 #[test]
1 1409 fn test_sparse_mixed_with_nulls() {
1 1410 let mut builder = UnionBuilder::new_sparse();
1 1411 builder.append::<Int32Type>("a", 1).unwrap();
1 1412 builder.append_null::<Int32Type>("a").unwrap();
1 1413 builder.append::<Float64Type>("c", 3.0).unwrap();
1 1414 builder.append::<Int32Type>("a", 4).unwrap();
1 1415 let union = builder.build().unwrap();
5 1416
4 1417 let expected_type_ids = vec![0_i8, 0, 1, 0];
1418
1 1419 // Check type ids
5 1420 assert_eq!(*union.type_ids(), expected_type_ids);
▶︎ 5 1421 for (i, id) in expected_type_ids.iter().enumerate() {
4 1422 assert_eq!(id, &union.type_id(i));
5 1423 }
4 1424
▶︎ 4 1425 // Check offsets, sparse union should only have a single buffer, i.e. no offsets
▶︎ ▶︎ 1 1426 assert!(union.offsets().is_none());
1 1427
▶︎ 5 1428 for i in 0..union.len() {
5 1429 let slot = union.value(i);
5 1430 match i {
4 1431 0 => {
4 1432 let slot = slot.as_any().downcast_ref::<Int32Array>().unwrap();
▶︎ ▶︎ 1 1433 assert!(!slot.is_null(0));
▶︎ 1 1434 assert_eq!(slot.len(), 1);
▶︎ 1 1435 let value = slot.value(0);
▶︎ 1 1436 assert_eq!(1_i32, value);
1 1437 }
▶︎ 1 1438 1 => assert!(slot.is_null(0)),
▶︎ 1 1439 2 => {
▶︎ 1 1440 let slot = slot.as_any().downcast_ref::<Float64Array>().unwrap();
▶︎ 1 1441 assert!(!slot.is_null(0));
▶︎ 1 1442 assert_eq!(slot.len(), 1);
▶︎ ▶︎ 1 1443 let value = slot.value(0);
1 1444 assert_eq!(value, 3_f64);
1 1445 }
1 1446 3 => {
1 1447 let slot = slot.as_any().downcast_ref::<Int32Array>().unwrap();
▶︎ 1 1448 assert!(!slot.is_null(0));
▶︎ 1 1449 assert_eq!(slot.len(), 1);
▶︎ 4 1450 let value = slot.value(0);
▶︎ ▶︎ 1 1451 assert_eq!(4_i32, value);
1 1452 }
1 1453 _ => unreachable!(),
1 1454 }
4 1455 }
▶︎ ▶︎ 4 1456 }
▶︎ ▶︎ 4 1457
▶︎ ▶︎ 1 1458 #[test]
1 1459 fn test_sparse_mixed_with_nulls_and_offset() {
1 1460 let mut builder = UnionBuilder::new_sparse();
1 1461 builder.append::<Int32Type>("a", 1).unwrap();
1 1462 builder.append_null::<Int32Type>("a").unwrap();
1 1463 builder.append::<Float64Type>("c", 3.0).unwrap();
1 1464 builder.append_null::<Float64Type>("c").unwrap();
1 1465 builder.append::<Int32Type>("a", 4).unwrap();
1 1466 let union = builder.build().unwrap();
5 1467
4 1468 let slice = union.slice(1, 4);
4 1469 let new_union = slice.as_any().downcast_ref::<UnionArray>().unwrap();
▶︎ 1 1470
1 1471 assert_eq!(4, new_union.len());
5 1472 for i in 0..new_union.len() {
▶︎ 4 1473 let slot = new_union.value(i);
4 1474 match i {
▶︎ 5 1475 0 => assert!(slot.is_null(0)),
5 1476 1 => {
4 1477 let slot = slot.as_primitive::<Float64Type>();
▶︎ ▶︎ ▶︎ 4 1478 assert!(!slot.is_null(0));
▶︎ 1 1479 assert_eq!(slot.len(), 1);
1 1480 let value = slot.value(0);
▶︎ ▶︎ 1 1481 assert_eq!(value, 3_f64);
▶︎ 1 1482 }
▶︎ 1 1483 2 => assert!(slot.is_null(0)),
1 1484 3 => {
1 1485 let slot = slot.as_primitive::<Int32Type>();
▶︎ ▶︎ 1 1486 assert!(!slot.is_null(0));
▶︎ 1 1487 assert_eq!(slot.len(), 1);
4 1488 let value = slot.value(0);
▶︎ ▶︎ ▶︎ 1 1489 assert_eq!(4_i32, value);
▶︎ 1 1490 }
2 1491 _ => unreachable!(),
2 1492 }
4 1493 }
▶︎ ▶︎ 12 1494 }
▶︎ 10 1495
▶︎ 10 1496 fn test_union_validity(union_array: &UnionArray) {
▶︎ ▶︎ 4 1497 assert_eq!(union_array.null_count(), 0);
▶︎ ▶︎ 2 1498
12 1499 for i in 0..union_array.len() {
▶︎ 10 1500 assert!(!union_array.is_null(i));
▶︎ 10 1501 assert!(union_array.is_valid(i));
12 1502 }
▶︎ 12 1503 }
▶︎ ▶︎ 10 1504
▶︎ 10 1505 #[test]
2 1506 fn test_union_array_validity() {
2 1507 let mut builder = UnionBuilder::new_sparse();
1 1508 builder.append::<Int32Type>("a", 1).unwrap();
1 1509 builder.append_null::<Int32Type>("a").unwrap();
1 1510 builder.append::<Float64Type>("c", 3.0).unwrap();
1 1511 builder.append_null::<Float64Type>("c").unwrap();
1 1512 builder.append::<Int32Type>("a", 4).unwrap();
1 1513 let union = builder.build().unwrap();
1 1514
1 1515 test_union_validity(&union);
1 1516
1 1517 let mut builder = UnionBuilder::new_dense();
1 1518 builder.append::<Int32Type>("a", 1).unwrap();
1 1519 builder.append_null::<Int32Type>("a").unwrap();
1 1520 builder.append::<Float64Type>("c", 3.0).unwrap();
▶︎ ▶︎ ▶︎ ▶︎ 1 1521 builder.append_null::<Float64Type>("c").unwrap();
1 1522 builder.append::<Int32Type>("a", 4).unwrap();
1 1523 let union = builder.build().unwrap();
1 1524
1 1525 test_union_validity(&union);
▶︎ ▶︎ ▶︎ ▶︎ 1 1526 }
1 1527
1 1528 #[test]
▶︎ ▶︎ ▶︎ ▶︎ 1 1529 fn test_type_check() {
▶︎ ▶︎ ▶︎ ▶︎ 1 1530 let mut builder = UnionBuilder::new_sparse();
1 1531 builder.append::<Float32Type>("a", 1.0).unwrap();
1 1532 let err = builder.append::<Int32Type>("a", 1).unwrap_err().to_string();
1 1533 assert!(
1 1534 err.contains(
1 1535 "Attempt to write col \"a\" with type Int32 doesn't match existing type Float32"
1 1536 ),
1 1537 "{}",
1 1538 err
1539 );
2 1540 }
2 1541
2 1542 #[test]
2 1543 fn slice_union_array() {
2 1544 // [1, null, 3.0, null, 4]
2 1545 fn create_union(mut builder: UnionBuilder) -> UnionArray {
2 1546 builder.append::<Int32Type>("a", 1).unwrap();
▶︎ 2 1547 builder.append_null::<Int32Type>("a").unwrap();
2 1548 builder.append::<Float64Type>("c", 3.0).unwrap();
2 1549 builder.append_null::<Float64Type>("c").unwrap();
▶︎ ▶︎ 2 1550 builder.append::<Int32Type>("a", 4).unwrap();
2 1551 builder.build().unwrap()
▶︎ 2 1552 }
2 1553
2 1554 fn create_batch(union: UnionArray) -> RecordBatch {
▶︎ ▶︎ ▶︎ 2 1555 let schema = Schema::new(vec![Field::new(
▶︎ ▶︎ ▶︎ ▶︎ 2 1556 "struct_array",
▶︎ 2 1557 union.data_type().clone(),
▶︎ ▶︎ 2 1558 true,
▶︎ ▶︎ 2 1559 )]);
2 1560
▶︎ ▶︎ ▶︎ 2 1561 RecordBatch::try_new(Arc::new(schema), vec![Arc::new(union)]).unwrap()
▶︎ 2 1562 }
1563
▶︎ ▶︎ ▶︎ 2 1564 fn test_slice_union(record_batch_slice: RecordBatch) {
▶︎ ▶︎ ▶︎ ▶︎ 2 1565 let union_slice = record_batch_slice
▶︎ 2 1566 .column(0)
2 1567 .as_any()
2 1568 .downcast_ref::<UnionArray>()
2 1569 .unwrap();
2 1570
2 1571 assert_eq!(union_slice.type_id(0), 0);
2 1572 assert_eq!(union_slice.type_id(1), 1);
▶︎ 2 1573 assert_eq!(union_slice.type_id(2), 1);
2 1574
2 1575 let slot = union_slice.value(0);
2 1576 let array = slot.as_primitive::<Int32Type>();
2 1577 assert_eq!(array.len(), 1);
▶︎ ▶︎ 2 1578 assert!(array.is_null(0));
2 1579
2 1580 let slot = union_slice.value(1);
▶︎ 2 1581 let array = slot.as_primitive::<Float64Type>();
▶︎ 2 1582 assert_eq!(array.len(), 1);
▶︎ 2 1583 assert!(array.is_valid(0));
▶︎ 2 1584 assert_eq!(array.value(0), 3.0);
2 1585
▶︎ 2 1586 let slot = union_slice.value(2);
▶︎ 2 1587 let array = slot.as_primitive::<Float64Type>();
2 1588 assert_eq!(array.len(), 1);
▶︎ 2 1589 assert!(array.is_null(0));
2 1590 }
2 1591
▶︎ 2 1592 // Sparse Union
▶︎ 2 1593 let builder = UnionBuilder::new_sparse();
2 1594 let record_batch = create_batch(create_union(builder));
1 1595 // [null, 3.0, null]
1 1596 let record_batch_slice = record_batch.slice(1, 3);
1 1597 test_slice_union(record_batch_slice);
1 1598
1 1599 // Dense Union
1 1600 let builder = UnionBuilder::new_dense();
1 1601 let record_batch = create_batch(create_union(builder));
1602 // [null, 3.0, null]
1 1603 let record_batch_slice = record_batch.slice(1, 3);
1 1604 test_slice_union(record_batch_slice);
1 1605 }
1 1606
▶︎ ▶︎ 1 1607 #[test]
1 1608 fn test_custom_type_ids() {
1 1609 let data_type = DataType::Union(
1 1610 UnionFields::new(
1 1611 vec![8, 4, 9],
▶︎ ▶︎ ▶︎ 1 1612 vec![
1 1613 Field::new("strings", DataType::Utf8, false),
1 1614 Field::new("integers", DataType::Int32, false),
▶︎ ▶︎ 1 1615 Field::new("floats", DataType::Float64, false),
▶︎ ▶︎ ▶︎ 1 1616 ],
▶︎ ▶︎ 1 1617 ),
▶︎ 1 1618 UnionMode::Dense,
1 1619 );
▶︎ 1 1620
▶︎ ▶︎ ▶︎ 1 1621 let string_array = StringArray::from(vec!["foo", "bar", "baz"]);
▶︎ 1 1622 let int_array = Int32Array::from(vec![5, 6, 4]);
▶︎ 1 1623 let float_array = Float64Array::from(vec![10.0]);
▶︎ 1 1624
▶︎ ▶︎ ▶︎ ▶︎ 1 1625 let type_ids = Buffer::from_vec(vec![4_i8, 8, 4, 8, 9, 4, 8]);
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1626 let value_offsets = Buffer::from_vec(vec![0_i32, 0, 1, 1, 0, 2, 2]);
▶︎ 1 1627
1 1628 let data = ArrayData::builder(data_type)
▶︎ 1 1629 .len(7)
▶︎ ▶︎ ▶︎ ▶︎ 1 1630 .buffers(vec![type_ids, value_offsets])
▶︎ ▶︎ 1 1631 .child_data(vec![
1 1632 string_array.into_data(),
▶︎ ▶︎ 1 1633 int_array.into_data(),
▶︎ ▶︎ ▶︎ ▶︎ 1 1634 float_array.into_data(),
▶︎ ▶︎ ▶︎ 1 1635 ])
1 1636 .build()
1 1637 .unwrap();
▶︎ 1 1638
▶︎ 1 1639 let array = UnionArray::from(data);
1640
1 1641 let v = array.value(0);
1 1642 assert_eq!(v.data_type(), &DataType::Int32);
1 1643 assert_eq!(v.len(), 1);
1 1644 assert_eq!(v.as_primitive::<Int32Type>().value(0), 5);
1 1645
1 1646 let v = array.value(1);
1 1647 assert_eq!(v.data_type(), &DataType::Utf8);
1 1648 assert_eq!(v.len(), 1);
1 1649 assert_eq!(v.as_string::<i32>().value(0), "foo");
1 1650
1 1651 let v = array.value(2);
1 1652 assert_eq!(v.data_type(), &DataType::Int32);
1 1653 assert_eq!(v.len(), 1);
1 1654 assert_eq!(v.as_primitive::<Int32Type>().value(0), 6);
1 1655
1 1656 let v = array.value(3);
1 1657 assert_eq!(v.data_type(), &DataType::Utf8);
1 1658 assert_eq!(v.len(), 1);
1 1659 assert_eq!(v.as_string::<i32>().value(0), "bar");
1 1660
1 1661 let v = array.value(4);
1 1662 assert_eq!(v.data_type(), &DataType::Float64);
1 1663 assert_eq!(v.len(), 1);
1 1664 assert_eq!(v.as_primitive::<Float64Type>().value(0), 10.0);
1 1665
1 1666 let v = array.value(5);
1 1667 assert_eq!(v.data_type(), &DataType::Int32);
1 1668 assert_eq!(v.len(), 1);
1 1669 assert_eq!(v.as_primitive::<Int32Type>().value(0), 4);
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1670
1 1671 let v = array.value(6);
1 1672 assert_eq!(v.data_type(), &DataType::Utf8);
1 1673 assert_eq!(v.len(), 1);
1 1674 assert_eq!(v.as_string::<i32>().value(0), "baz");
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1675 }
1 1676
1 1677 #[test]
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1678 fn into_parts() {
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1679 let mut builder = UnionBuilder::new_dense();
1 1680 builder.append::<Int32Type>("a", 1).unwrap();
1 1681 builder.append::<Int8Type>("b", 2).unwrap();
1 1682 builder.append::<Int32Type>("a", 3).unwrap();
1 1683 let dense_union = builder.build().unwrap();
1 1684
1 1685 let field = [
1 1686 &Arc::new(Field::new("a", DataType::Int32, false)),
1 1687 &Arc::new(Field::new("b", DataType::Int8, false)),
2 1688 ];
1 1689 let (union_fields, type_ids, offsets, children) = dense_union.into_parts();
1 1690 assert_eq!(
1 1691 union_fields
1 1692 .iter()
▶︎ 2 1693 .map(|(_, field)| field)
1 1694 .collect::<Vec<_>>(),
1 1695 field
2 1696 );
▶︎ 2 1697 assert_eq!(type_ids, [0, 1, 0]);
▶︎ 1 1698 assert!(offsets.is_some());
1 1699 assert_eq!(offsets.as_ref().unwrap(), &[0, 0, 1]);
1 1700
▶︎ 1 1701 let result = UnionArray::try_new(union_fields, type_ids, offsets, children);
▶︎ ▶︎ 1 1702 assert!(result.is_ok());
1 1703 assert_eq!(result.unwrap().len(), 3);
1 1704
▶︎ 1 1705 let mut builder = UnionBuilder::new_sparse();
▶︎ 1 1706 builder.append::<Int32Type>("a", 1).unwrap();
1 1707 builder.append::<Int8Type>("b", 2).unwrap();
▶︎ 1 1708 builder.append::<Int32Type>("a", 3).unwrap();
1 1709 let sparse_union = builder.build().unwrap();
1 1710
▶︎ 1 1711 let (union_fields, type_ids, offsets, children) = sparse_union.into_parts();
1 1712 assert_eq!(type_ids, [0, 1, 0]);
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1713 assert!(offsets.is_none());
1 1714
1 1715 let result = UnionArray::try_new(union_fields, type_ids, offsets, children);
▶︎ ▶︎ 1 1716 assert!(result.is_ok());
▶︎ 1 1717 assert_eq!(result.unwrap().len(), 3);
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1718 }
▶︎ 1 1719
▶︎ 1 1720 #[test]
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1721 fn into_parts_custom_type_ids() {
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1722 let set_field_type_ids: [i8; 3] = [8, 4, 9];
1 1723 let data_type = DataType::Union(
1 1724 UnionFields::new(
1 1725 set_field_type_ids,
1 1726 [
1 1727 Field::new("strings", DataType::Utf8, false),
1 1728 Field::new("integers", DataType::Int32, false),
▶︎ 1 1729 Field::new("floats", DataType::Float64, false),
▶︎ 1 1730 ],
▶︎ 1 1731 ),
1 1732 UnionMode::Dense,
▶︎ 1 1733 );
▶︎ 1 1734 let string_array = StringArray::from(vec!["foo", "bar", "baz"]);
▶︎ 1 1735 let int_array = Int32Array::from(vec![5, 6, 4]);
▶︎ ▶︎ ▶︎ 1 1736 let float_array = Float64Array::from(vec![10.0]);
▶︎ ▶︎ ▶︎ 1 1737 let type_ids = Buffer::from_vec(vec![4_i8, 8, 4, 8, 9, 4, 8]);
▶︎ ▶︎ ▶︎ 1 1738 let value_offsets = Buffer::from_vec(vec![0_i32, 0, 1, 1, 0, 2, 2]);
▶︎ ▶︎ 1 1739 let data = ArrayData::builder(data_type)
▶︎ 1 1740 .len(7)
▶︎ ▶︎ ▶︎ ▶︎ 1 1741 .buffers(vec![type_ids, value_offsets])
▶︎ ▶︎ ▶︎ 1 1742 .child_data(vec![
1 1743 string_array.into_data(),
▶︎ ▶︎ 1 1744 int_array.into_data(),
▶︎ ▶︎ ▶︎ ▶︎ 1 1745 float_array.into_data(),
▶︎ ▶︎ ▶︎ 1 1746 ])
1 1747 .build()
1 1748 .unwrap();
▶︎ 1 1749 let array = UnionArray::from(data);
▶︎ 1 1750
1 1751 let (union_fields, type_ids, offsets, children) = array.into_parts();
▶︎ 1 1752 assert_eq!(
1 1753 type_ids.iter().collect::<HashSet<_>>(),
1 1754 set_field_type_ids.iter().collect::<HashSet<_>>()
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1755 );
1 1756 let result = UnionArray::try_new(union_fields, type_ids, offsets, children);
▶︎ 1 1757 assert!(result.is_ok());
1 1758 let array = result.unwrap();
1 1759 assert_eq!(array.len(), 7);
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1760 }
▶︎ 1 1761
1 1762 #[test]
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1763 fn test_invalid() {
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1764 let fields = UnionFields::new(
1 1765 [3, 2],
▶︎ ▶︎ ▶︎ ▶︎ 1 1766 [
1 1767 Field::new("a", DataType::Utf8, false),
1 1768 Field::new("b", DataType::Utf8, false),
1 1769 ],
1 1770 );
▶︎ ▶︎ ▶︎ ▶︎ 1 1771 let children = vec![
1 1772 Arc::new(StringArray::from_iter_values(["a", "b"])) as _,
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1773 Arc::new(StringArray::from_iter_values(["c", "d"])) as _,
▶︎ ▶︎ ▶︎ ▶︎ 1 1774 ];
▶︎ ▶︎ ▶︎ ▶︎ 1 1775
1 1776 let type_ids = vec![3, 3, 2].into();
1 1777 let err =
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1778 UnionArray::try_new(fields.clone(), type_ids, None, children.clone()).unwrap_err();
1 1779 assert_eq!(
1 1780 err.to_string(),
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1781 "Invalid argument error: Sparse union child arrays must be equal in length to the length of the union"
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1782 );
1 1783
1 1784 let type_ids = vec![1, 2].into();
1785 let err =
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1786 UnionArray::try_new(fields.clone(), type_ids, None, children.clone()).unwrap_err();
1 1787 assert_eq!(
1 1788 err.to_string(),
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1789 "Invalid argument error: Type Ids values must match one of the field type ids"
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1790 );
1 1791
1 1792 let type_ids = vec![7, 2].into();
1 1793 let err = UnionArray::try_new(fields.clone(), type_ids, None, children).unwrap_err();
▶︎ ▶︎ ▶︎ ▶︎ 1 1794 assert_eq!(
1 1795 err.to_string(),
1 1796 "Invalid argument error: Type Ids values must match one of the field type ids"
1 1797 );
1 1798
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1799 let children = vec![
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1800 Arc::new(StringArray::from_iter_values(["a", "b"])) as _,
1 1801 Arc::new(StringArray::from_iter_values(["c"])) as _,
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1802 ];
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1803 let type_ids = ScalarBuffer::from(vec![3_i8, 3, 2]);
▶︎ 1 1804 let offsets = Some(vec![0, 1, 0].into());
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1805 UnionArray::try_new(fields.clone(), type_ids.clone(), offsets, children.clone()).unwrap();
1 1806
▶︎ ▶︎ 1 1807 let offsets = Some(vec![0, 1, 1].into());
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1808 let err = UnionArray::try_new(fields.clone(), type_ids.clone(), offsets, children.clone())
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1809 .unwrap_err();
▶︎ 1 1810
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1811 assert_eq!(
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1812 err.to_string(),
▶︎ 1 1813 "Invalid argument error: Offsets must be positive and within the length of the Array"
1 1814 );
1 1815
▶︎ 1 1816 let offsets = Some(vec![0, 1].into());
1817 let err =
▶︎ 1 1818 UnionArray::try_new(fields.clone(), type_ids.clone(), offsets, children).unwrap_err();
▶︎ 1 1819
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1820 assert_eq!(
▶︎ 1 1821 err.to_string(),
▶︎ 1 1822 "Invalid argument error: Type Ids and Offsets lengths must match"
1 1823 );
1 1824
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1825 let err = UnionArray::try_new(fields.clone(), type_ids, None, vec![]).unwrap_err();
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1826
1 1827 assert_eq!(
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1828 err.to_string(),
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1829 "Invalid argument error: Union fields length must match child arrays length"
1 1830 );
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1831 }
1 1832
1 1833 #[test]
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1834 fn test_logical_nulls_fast_paths() {
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1835 // fields.len() <= 1
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1836 let array = UnionArray::try_new(UnionFields::empty(), vec![].into(), None, vec![]).unwrap();
1 1837
1 1838 assert_eq!(array.logical_nulls(), None);
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1839
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1840 let fields = UnionFields::new(
1 1841 [1, 3],
1 1842 [
1 1843 Field::new("a", DataType::Int8, false), // non nullable
1 1844 Field::new("b", DataType::Int8, false), // non nullable
1 1845 ],
▶︎ ▶︎ 1 1846 );
1 1847 let array = UnionArray::try_new(
1 1848 fields,
1 1849 vec![1].into(),
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1850 None,
▶︎ ▶︎ 1 1851 vec![
1 1852 Arc::new(Int8Array::from_value(5, 1)),
1 1853 Arc::new(Int8Array::from_value(5, 1)),
▶︎ ▶︎ 1 1854 ],
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1855 )
1 1856 .unwrap();
1 1857
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1858 assert_eq!(array.logical_nulls(), None);
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1859
1 1860 let nullable_fields = UnionFields::new(
1 1861 [1, 3],
1 1862 [
1 1863 Field::new("a", DataType::Int8, true), // nullable but without nulls
1 1864 Field::new("b", DataType::Int8, true), // nullable but without nulls
1 1865 ],
▶︎ ▶︎ 1 1866 );
1 1867 let array = UnionArray::try_new(
1 1868 nullable_fields.clone(),
1 1869 vec![1, 1].into(),
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1870 None,
▶︎ ▶︎ 1 1871 vec![
1 1872 Arc::new(Int8Array::from_value(-5, 2)), // nullable but without nulls
1 1873 Arc::new(Int8Array::from_value(-5, 2)), // nullable but without nulls
▶︎ ▶︎ 1 1874 ],
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1875 )
1 1876 .unwrap();
1 1877
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1878 assert_eq!(array.logical_nulls(), None);
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1879
1 1880 let array = UnionArray::try_new(
1 1881 nullable_fields.clone(),
1 1882 vec![1, 1].into(),
1 1883 None,
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1884 vec![
1 1885 // every children is completly null
1 1886 Arc::new(Int8Array::new_null(2)), // all null, same len as it's parent
▶︎ ▶︎ 1 1887 Arc::new(Int8Array::new_null(2)), // all null, same len as it's parent
▶︎ ▶︎ 1 1888 ],
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1889 )
1 1890 .unwrap();
1 1891
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1892 assert_eq!(array.logical_nulls(), Some(NullBuffer::new_null(2)));
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1893
1 1894 let array = UnionArray::try_new(
1 1895 nullable_fields.clone(),
1 1896 vec![1, 1].into(),
▶︎ 1 1897 Some(vec![0, 1].into()),
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1898 vec![
1 1899 // every children is completly null
▶︎ 1 1900 Arc::new(Int8Array::new_null(3)), // bigger that parent
▶︎ ▶︎ ▶︎ 1 1901 Arc::new(Int8Array::new_null(3)), // bigger that parent
▶︎ ▶︎ 1 1902 ],
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1903 )
1 1904 .unwrap();
1 1905
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1906 assert_eq!(array.logical_nulls(), Some(NullBuffer::new_null(2)));
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1907
1 1908 let array = UnionArray::try_new(
1 1909 nullable_fields.clone(),
1 1910 vec![1, 3].into(),
1 1911 None,
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1912 vec![
1 1913 // none all null
1 1914 Arc::new(Int8Array::from_iter([None, Some(-5)])),
▶︎ ▶︎ 1 1915 Arc::new(Int8Array::from_iter([Some(-5), None])),
▶︎ ▶︎ 1 1916 ],
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1917 )
1 1918 .unwrap();
1 1919
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1920 assert_eq!(array.logical_nulls(), Some(NullBuffer::new_null(2)));
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1921 }
▶︎ 1 1922
1 1923 #[test]
1 1924 fn test_dense_union_logical_nulls_gather() {
1 1925 // union of [{A=1}, {A=2}, {B=3.2}, {B=}, {C=}, {C=}]
▶︎ 1 1926 let int_array = Int32Array::from(vec![1, 2]);
▶︎ 1 1927 let float_array = Float64Array::from(vec![Some(3.2), None]);
1 1928 let str_array = StringArray::new_null(1);
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1929 let type_ids = [1, 1, 3, 3, 4, 4].into_iter().collect::<ScalarBuffer<i8>>();
▶︎ ▶︎ 1 1930 let offsets = [0, 1, 0, 1, 0, 0]
▶︎ 1 1931 .into_iter()
1 1932 .collect::<ScalarBuffer<i32>>();
1 1933
▶︎ ▶︎ ▶︎ ▶︎ 1 1934 let children = vec![
1 1935 Arc::new(int_array) as Arc<dyn Array>,
1 1936 Arc::new(float_array),
▶︎ ▶︎ ▶︎ ▶︎ 1 1937 Arc::new(str_array),
▶︎ ▶︎ ▶︎ ▶︎ 1 1938 ];
1 1939
1 1940 let array = UnionArray::try_new(union_fields(), type_ids, Some(offsets), children).unwrap();
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1941
1 1942 let result = array.logical_nulls();
1 1943
1 1944 let expected = NullBuffer::from(vec![true, true, true, false, false, false]);
1 1945 assert_eq!(Some(expected), result);
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1946 }
▶︎ 1 1947
▶︎ 1 1948 #[test]
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1949 fn test_sparse_union_logical_nulls_mask_all_nulls_skip_one() {
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1950 // union of [{A=}, {A=}, {B=3.2}, {B=}, {C="a"}, {C=}]
▶︎ ▶︎ ▶︎ ▶︎ 1 1951 let int_array = Int32Array::new_null(6);
▶︎ 1 1952 let float_array = Float64Array::from(vec![None, None, Some(3.2), None, None, None]);
▶︎ 1 1953 let str_array = StringArray::from(vec![None, None, None, None, None, Some("a")]);
1 1954 let type_ids = [1, 1, 3, 3, 4, 4].into_iter().collect::<ScalarBuffer<i8>>();
▶︎ 1 1955
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1956 let children = vec![
▶︎ 1 1957 Arc::new(int_array) as Arc<dyn Array>,
1 1958 Arc::new(float_array),
▶︎ ▶︎ ▶︎ ▶︎ 1 1959 Arc::new(str_array),
▶︎ ▶︎ ▶︎ ▶︎ 1 1960 ];
1 1961
1 1962 let array = UnionArray::try_new(union_fields(), type_ids, None, children).unwrap();
1 1963
1 1964 let result = array.logical_nulls();
1 1965
1 1966 let expected = NullBuffer::from(vec![false, false, true, false, false, true]);
1 1967 assert_eq!(Some(expected), result);
1 1968
1 1969 //like above, but repeated to genereate two exact bitmasks and a non empty remainder
1 1970 let len = 2 * 64 + 32;
1 1971
1 1972 let int_array = Int32Array::new_null(len);
1 1973 let float_array =
1 1974 Float64Array::from_iter([None, None, Some(3.2)].into_iter().cycle().take(len));
1 1975 let str_array =
1 1976 StringArray::from_iter([None, Some("a"), None].into_iter().cycle().take(len));
1 1977 let type_ids = ScalarBuffer::from_iter([1, 1, 3, 3, 4, 4].into_iter().cycle().take(len));
▶︎ ▶︎ 1 1978
1 1979 let array = UnionArray::try_new(
1 1980 union_fields(),
1 1981 type_ids,
1 1982 None,
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1983 vec![
1 1984 Arc::new(int_array),
1 1985 Arc::new(float_array),
▶︎ ▶︎ 1 1986 Arc::new(str_array),
▶︎ ▶︎ 1 1987 ],
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1988 )
1 1989 .unwrap();
1 1990
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1991 let result = array.logical_nulls();
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1992
1 1993 let expected = NullBuffer::from_iter(
1 1994 [false, false, true, false, true, false]
1 1995 .into_iter()
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 1996 .cycle()
1 1997 .take(len),
1 1998 );
1 1999 assert_eq!(array.len(), len);
1 2000 assert_eq!(Some(expected), result);
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 2001 }
▶︎ 1 2002
1 2003 #[test]
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 2004 fn test_sparse_union_logical_mask_mixed_nulls_skip_fully_valid() {
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 2005 // union of [{A=2}, {A=2}, {B=3.2}, {B=}, {C=}, {C=}]
▶︎ ▶︎ ▶︎ ▶︎ 1 2006 let int_array = Int32Array::from_value(2, 6);
▶︎ 1 2007 let float_array = Float64Array::from(vec![None, None, Some(3.2), None, None, None]);
1 2008 let str_array = StringArray::new_null(6);
1 2009 let type_ids = [1, 1, 3, 3, 4, 4].into_iter().collect::<ScalarBuffer<i8>>();
▶︎ 1 2010
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 2011 let children = vec![
1 2012 Arc::new(int_array) as Arc<dyn Array>,
1 2013 Arc::new(float_array),
▶︎ ▶︎ ▶︎ ▶︎ 1 2014 Arc::new(str_array),
▶︎ ▶︎ ▶︎ ▶︎ 1 2015 ];
1 2016
1 2017 let array = UnionArray::try_new(union_fields(), type_ids, None, children).unwrap();
1 2018
1 2019 let result = array.logical_nulls();
1 2020
1 2021 let expected = NullBuffer::from(vec![true, true, true, false, false, false]);
1 2022 assert_eq!(Some(expected), result);
1 2023
1 2024 //like above, but repeated to genereate two exact bitmasks and a non empty remainder
1 2025 let len = 2 * 64 + 32;
1 2026
▶︎ ▶︎ ▶︎ ▶︎ 1 2027 let int_array = Int32Array::from_value(2, len);
1 2028 let float_array = Float64Array::from_iter([None, Some(3.2)].into_iter().cycle().take(len));
1 2029 let str_array = StringArray::from_iter([None, Some("a")].into_iter().cycle().take(len));
1 2030 let type_ids = ScalarBuffer::from_iter([1, 1, 3, 3, 4, 4].into_iter().cycle().take(len));
1 2031
▶︎ ▶︎ ▶︎ ▶︎ 1 2032 let children = vec![
1 2033 Arc::new(int_array) as Arc<dyn Array>,
1 2034 Arc::new(float_array),
▶︎ ▶︎ ▶︎ ▶︎ 1 2035 Arc::new(str_array),
▶︎ ▶︎ ▶︎ ▶︎ 1 2036 ];
1 2037
1 2038 let array = UnionArray::try_new(union_fields(), type_ids, None, children).unwrap();
1 2039
1 2040 let result = array.logical_nulls();
1 2041
1 2042 let expected = NullBuffer::from_iter(
1 2043 [true, true, false, true, false, true]
1 2044 .into_iter()
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 2045 .cycle()
1 2046 .take(len),
1 2047 );
1 2048 assert_eq!(array.len(), len);
1 2049 assert_eq!(Some(expected), result);
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 2050 }
1 2051
1 2052 #[test]
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 2053 fn test_sparse_union_logical_mask_mixed_nulls_skip_fully_null() {
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 2054 // union of [{A=}, {A=}, {B=4.2}, {B=4.2}, {C=}, {C=}]
▶︎ ▶︎ ▶︎ ▶︎ 1 2055 let int_array = Int32Array::new_null(6);
1 2056 let float_array = Float64Array::from_value(4.2, 6);
1 2057 let str_array = StringArray::new_null(6);
1 2058 let type_ids = [1, 1, 3, 3, 4, 4].into_iter().collect::<ScalarBuffer<i8>>();
1 2059
▶︎ ▶︎ ▶︎ ▶︎ 1 2060 let children = vec![
1 2061 Arc::new(int_array) as Arc<dyn Array>,
1 2062 Arc::new(float_array),
▶︎ ▶︎ ▶︎ ▶︎ 1 2063 Arc::new(str_array),
▶︎ ▶︎ ▶︎ ▶︎ 1 2064 ];
1 2065
1 2066 let array = UnionArray::try_new(union_fields(), type_ids, None, children).unwrap();
1 2067
1 2068 let result = array.logical_nulls();
1 2069
1 2070 let expected = NullBuffer::from(vec![false, false, true, true, false, false]);
1 2071 assert_eq!(Some(expected), result);
1 2072
1 2073 //like above, but repeated to genereate two exact bitmasks and a non empty remainder
1 2074 let len = 2 * 64 + 32;
1 2075
▶︎ ▶︎ ▶︎ ▶︎ 1 2076 let int_array = Int32Array::new_null(len);
1 2077 let float_array = Float64Array::from_value(4.2, len);
1 2078 let str_array = StringArray::new_null(len);
1 2079 let type_ids = ScalarBuffer::from_iter([1, 1, 3, 3, 4, 4].into_iter().cycle().take(len));
1 2080
▶︎ ▶︎ ▶︎ ▶︎ 1 2081 let children = vec![
1 2082 Arc::new(int_array) as Arc<dyn Array>,
1 2083 Arc::new(float_array),
▶︎ ▶︎ ▶︎ ▶︎ 1 2084 Arc::new(str_array),
▶︎ ▶︎ ▶︎ ▶︎ 1 2085 ];
1 2086
1 2087 let array = UnionArray::try_new(union_fields(), type_ids, None, children).unwrap();
1 2088
1 2089 let result = array.logical_nulls();
1 2090
1 2091 let expected = NullBuffer::from_iter(
1 2092 [false, false, true, true, false, false]
1 2093 .into_iter()
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 2094 .cycle()
1 2095 .take(len),
1 2096 );
1 2097 assert_eq!(array.len(), len);
1 2098 assert_eq!(Some(expected), result);
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 2099 }
1 2100
▶︎ 1 2101 #[test]
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 2102 fn test_sparse_union_logical_nulls_gather() {
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 2103 let n_fields = 50;
1 2104
1 2105 let non_null = Int32Array::from_value(2, 4);
▶︎ 1 2106 let mixed = Int32Array::from(vec![None, None, Some(1), None]);
50 2107 let fully_null = Int32Array::new_null(4);
50 2108
▶︎ 1 2109 let array = UnionArray::try_new(
▶︎ 50 2110 (1..)
1 2111 .step_by(2)
50 2112 .map(|i| {
50 2113 (
1 2114 i,
50 2115 Arc::new(Field::new(format!("f{i}"), DataType::Int32, true)),
50 2116 )
50 2117 })
50 2118 .take(n_fields)
50 2119 .collect(),
50 2120 vec![1, 3, 3, 5].into(),
50 2121 None,
1 2122 [
1 2123 Arc::new(non_null) as ArrayRef,
1 2124 Arc::new(mixed),
1 2125 Arc::new(fully_null),
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 2126 ]
1 2127 .into_iter()
1 2128 .cycle()
1 2129 .take(n_fields)
0 2130 .collect(),
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 2131 )
2132 .unwrap();
1 2133
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 2134 let result = array.logical_nulls();
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 1 2135
7 2136 let expected = NullBuffer::from(vec![true, false, true, false]);
7 2137
7 2138 assert_eq!(Some(expected), result);
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 7 2139 }
7 2140
7 2141 fn union_fields() -> UnionFields {
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 7 2142 [
▶︎ ▶︎ ▶︎ ▶︎ ▶︎ 7 2143 (1, Arc::new(Field::new("A", DataType::Int32, true))),
7 2144 (3, Arc::new(Field::new("B", DataType::Float64, true))),
7 2145 (4, Arc::new(Field::new("C", DataType::Utf8, true))),
7 2146 ]
7 2147 .into_iter()
7 2148 .collect()
7 2149 }
0 2150 }
7 2152 /* EOF */
7 2153 /* EOF */

functions

Function Calls Returns Blocks Branches
arrow_array::​array::​union_array::​UnionArray::​new_unchecked::​hc1bd76a5025567fb 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​try_new::​h0e12aa520385636d 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​try_new::​{{closure}}::​h6fedda4c1d150e72 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​try_new::​{{closure}}::​h807f46048af7dd12 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​child::​h947987e1be951040 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​type_id::​hcaa54ecbffb1f787 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​type_ids::​h1063cd558b172cbe 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​offsets::​h79750e0faed84580 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​value_offset::​h3201c164f9b171a6 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​value::​hc268c36276f5e07c 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​type_names::​h1afebc02b9d2bb08 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​type_names::​{{closure}}::​hcf3635540b4eb77b 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​is_dense::​h55778480d92a5d42 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​slice::​h0a74ba1993997ba4 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​slice::​{{closure}}::​h0f45eaebac8d35fc 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​slice::​{{closure}}::​{{closure}}::​h34dee7d844ba3b0e 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​into_parts::​h19eced1c1727862c 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​into_parts::​{{closure}}::​h6894376777b2887a 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_without_nulls::​ha8182a355c8aa42d 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_without_nulls::​{{closure}}::​h5dde3b5a57b2b391 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_without_nulls::​{{closure}}::​h651f85002cf1327d 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_without_nulls::​{{closure}}::​{{closure}}::​h7513bde860d86569 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_without_nulls::​{{closure}}::​h2ed5b61db73db2a6 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_without_nulls::​{{closure}}::​{{closure}}::​h50f5f8e1cb0edc58 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​he4cb12953b32d36e 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​hd419779c58aa4b6a 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​haa067c497170c0be 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​h15ca77b06ce114b0 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​h7250e1ba51ec8733 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​{{closure}}::​h872bb721deda6492 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​hec604f52dc26d456 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​{{closure}}::​h6efb0bf5cb159f6b 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_all_with_nulls_skip_one::​hc60209537fcba41a 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_all_with_nulls_skip_one::​{{closure}}::​ha48df2d04730b1b8 0 —% 0.00% 0.00%
arrow_array::​ array::​union_array::​UnionArray::​ mask_sparse_all_with_nulls_skip_one::​{{closure}}::​{{closure}}::​ h4c8e12c71c998170 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_all_with_nulls_skip_one::​{{closure}}::​hbb05aad90aa91552 0 —% 0.00% —%
arrow_array::​ array::​union_array::​UnionArray::​ mask_sparse_all_with_nulls_skip_one::​{{closure}}::​{{closure}}::​ h20b95090513c78bc 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​h1183830b5b7dbb7c 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​h1254666b9aca59cb 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​h66914ab04ad1026d 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​h2e21dc27eaddf854 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​h3547eebd4793424b 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​ha1ad40ecd2042376 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​h7c6004c8653c7e72 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​hd041c8a6a3ce678c 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​hf9d32dff9c086aa2 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​h306f363365a043ed 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​h7b8d2115bf540efc 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​hf4566dfe97f0d760 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​gather_nulls::​hbbf64f3676747c0b 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​gather_nulls::​{{closure}}::​he1c41f4f104cd078 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​gather_nulls::​{{closure}}::​h4b51baf6fc7eb3dc 0 —% 0.00% 0.00%
<arrow_array::​ array::​union_array::​UnionArray as core::​convert::​From<arrow_data::​data::​ArrayData>>::​from::​ h181967753b795155 0 —% 0.00% 0.00%
<arrow_array::​ array::​union_array::​UnionArray as core::​convert::​From<arrow_data::​data::​ArrayData>>::​from::​ {{closure}}::​h5a1ec52855a16e53 0 —% 0.00% —%
arrow_array::​ array::​union_array::​<impl core::​convert::​From<arrow_array::​array::​union_array::​ UnionArray> for arrow_data::​data::​ArrayData>::​from::​h920729ebfd15ac9d 0 —% 0.00% 0.00%
arrow_array::​ array::​union_array::​<impl core::​convert::​From<arrow_array::​array::​union_array::​ UnionArray> for arrow_data::​data::​ArrayData>::​from::​{{closure}}::​ h47046fc71413d167 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​as_any::​h5b32b0c8d3f72c9b 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​to_data::​h820342a2f247f351 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​into_data::​h8306af2a8e4fd959 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​data_type::​h42343898e952a67a 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​slice::​hd861108b26030398 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​len::​h8c6d4c3247f8db99 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​is_empty::​hbf28dba83e87a24d 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​offset::​h5cffc4274ec63f6c 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​nulls::​h5992a11866fa286d 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​h50490d720f361981 0 —% 0.00% 0.00%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ h87b1061f289c70d3 0 —% 0.00% 0.00%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ haacac98198427e4e 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ h661a5fa0c5370762 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ h401888126ce20de6 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ h59d12a414116b8c2 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ h5900decab8a9d4a3 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ hff52589e90846269 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​is_null::​h6fbc04046d3a2b11 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​is_valid::​h649c65c0887492b3 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​null_count::​h040f80a4f7df4054 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_buffer_memory_size::​ h95a5bbb605931252 0 —% 0.00% 0.00%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_buffer_memory_size::​ {{closure}}::​h39cd0c9863a7ed03 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_buffer_memory_size::​ {{closure}}::​{{closure}}::​h67084978df6887ca 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_array_memory_size::​ h471deb7833f0031d 0 —% 0.00% 0.00%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_array_memory_size::​{{closure}}::​ h827949ffa7ecb628 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_array_memory_size::​{{closure}}::​ {{closure}}::​hbdb7153d38f600dd 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as core::​fmt::​Debug>::​fmt::​h83b28644a20fc64a 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​selection_mask::​h334fdf1a1b3dc086 0 —% 0.00% —%
arrow_array::​array::​union_array::​selection_mask::​{{closure}}::​hd88bf6b0732511ec 0 —% 0.00% —%
arrow_array::​array::​union_array::​without_nulls_selected::​h610f1e186644af15 0 —% 0.00% —%
arrow_array::​array::​union_array::​without_nulls_selected::​{{closure}}::​hab82f6d030c2f8b4 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as core::​clone::​Clone>::​clone::​h75a45450edac0cb1 0 —% 0.00% 0.00%
<arrow_array::​array::​union_array::​Mask as core::​clone::​Clone>::​clone::​h96ed649201d06db5 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​new_unchecked::​h36517d66ca3794f4 68 100.00% 46.15% 36.54%
arrow_array::​array::​union_array::​UnionArray::​try_new::​h8c586dc2e3dd05d6 80 100.00% 76.14% 58.62%
arrow_array::​array::​union_array::​UnionArray::​try_new::​{{closure}}::​h45ba5bb76d9d9bad 257 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​try_new::​{{closure}}::​h36c7355a66b836ea 2178 100.00% 83.33% 50.00%
arrow_array::​array::​union_array::​UnionArray::​child::​hce65e76392a03143 2356 100.00% 80.00% 50.00%
arrow_array::​array::​union_array::​UnionArray::​type_id::​h5a8527b938ac329b 4300 100.00% 71.43% 50.00%
arrow_array::​array::​union_array::​UnionArray::​type_ids::​h52700b41791f2de1 12 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​offsets::​hf0a8bbf83ad4cce5 12 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​value_offset::​heb6c9f52efa13328 4256 100.00% 72.73% 66.67%
arrow_array::​array::​union_array::​UnionArray::​value::​h2c2c7f3de50d846d 2182 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​type_names::​hefa49e1b2cfc6ab0 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​type_names::​{{closure}}::​h170231b91de88fdf 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​is_dense::​h0b6cb2adcb5822dd 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​slice::​h09925b857248f268 8 100.00% 42.86% 41.67%
arrow_array::​array::​union_array::​UnionArray::​slice::​{{closure}}::​h433b86864ac210d8 8 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​slice::​{{closure}}::​{{closure}}::​h52f1ec40875d7fae 8 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​into_parts::​h6a925564ccb23a03 6 100.00% 29.03% 23.08%
arrow_array::​array::​union_array::​UnionArray::​into_parts::​{{closure}}::​hd39d09a790ddd844 14 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_without_nulls::​h2dc7c1c3af616694 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_without_nulls::​{{closure}}::​h599038a0b4d4fad4 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_without_nulls::​{{closure}}::​hbbd15f18491afe92 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_without_nulls::​{{closure}}::​{{closure}}::​ha4af34327e5b8941 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_without_nulls::​{{closure}}::​h17d1f9e0d42d2182 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_without_nulls::​{{closure}}::​{{closure}}::​h53fa1bcf4dfb9130 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​h240e0768fa69649e 4 100.00% 52.63% 38.64%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​h2c47ff6fa002ddc7 12 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​ha1fe04a0f1e6a4c9 8 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​hd4f16fbc2394c999 8 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​h4523a8952728fe28 4 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​{{closure}}::​hf56a2b75cc63f994 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​h026945f9d8915f0f 4 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​{{closure}}::​h075037d056dc5eda 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_all_with_nulls_skip_one::​h5bd9c28fdd6db581 2 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_all_with_nulls_skip_one::​{{closure}}::​h14553a30c58ddbdb 0 —% 0.00% 0.00%
arrow_array::​ array::​union_array::​UnionArray::​ mask_sparse_all_with_nulls_skip_one::​{{closure}}::​{{closure}}::​ hc176793a7e579bc9 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_all_with_nulls_skip_one::​{{closure}}::​hfa839a5643235971 2 100.00% 100.00% —%
arrow_array::​ array::​union_array::​UnionArray::​ mask_sparse_all_with_nulls_skip_one::​{{closure}}::​{{closure}}::​ hc12ce01957802229 4 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​h0d5c2bbf7f4616e6 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​h20ceed6ce1c52edd 2 100.00% 54.72% 40.00%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​hbc652904d044d13b 4 100.00% 54.72% 40.00%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​h3290d91e64d5b2b3 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​h672e28a67bd6734c 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​hc26378c425546ed7 4 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​h1e0d805297bcffc6 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​h3f95682d467f0106 4 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​hf6c6ad2ca6a276f5 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​h62014ff252d86855 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​hac673c20414f88e8 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​hf9fbca0b28a7b7ec 4 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​gather_nulls::​h08ff57ffe36b5fdf 12 100.00% 63.27% 56.82%
arrow_array::​array::​union_array::​UnionArray::​gather_nulls::​{{closure}}::​h8ee7a8c02f594637 12 100.00% 80.00% 50.00%
arrow_array::​array::​union_array::​UnionArray::​gather_nulls::​{{closure}}::​h236d0d59f23358fb 672 100.00% 80.00% 50.00%
<arrow_array::​ array::​union_array::​UnionArray as core::​convert::​From<arrow_data::​data::​ArrayData>>::​from::​ h68c09739a61cd0e5 76 100.00% 51.69% 50.00%
<arrow_array::​ array::​union_array::​UnionArray as core::​convert::​From<arrow_data::​data::​ArrayData>>::​from::​ {{closure}}::​hdb12f952444f9962 268 100.00% 100.00% —%
arrow_array::​ array::​union_array::​<impl core::​convert::​From<arrow_array::​array::​union_array::​ UnionArray> for arrow_data::​data::​ArrayData>::​from::​h1c3fda04601bb870 4 100.00% 38.46% 33.87%
arrow_array::​ array::​union_array::​<impl core::​convert::​From<arrow_array::​array::​union_array::​ UnionArray> for arrow_data::​data::​ArrayData>::​from::​{{closure}}::​ hc1628785e2140bd4 8 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​as_any::​he566b253791efa08 12 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​to_data::​hd3371bd8a589834f 4 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​into_data::​h30e85eb2dc35b2ea 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​data_type::​h286067170107f9dc 40 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​slice::​h7a5d39ec2dc94cd9 4 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​len::​hbe31af8392654e2e 4324 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​is_empty::​hb7d0238f8a7cc4f3 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​offset::​hdd2e777288e6f319 54 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​nulls::​hfcedf77546a6fd92 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​h692466b66b6bff4b 28 100.00% 76.06% 49.47%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ h58c73ff8daf9748f 162 100.00% 85.71% 100.00%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ hc36cc3ee6503f344 110 100.00% 100.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ hfbf33dcb828132b2 110 100.00% 100.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ h5da866bd323bde98 6 100.00% 100.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ h10c9fcaa32e0548d 2 100.00% 100.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ hfe79b83c78ced105 64 100.00% 100.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ h31a920fafe7ba83a 54 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​is_null::​hc29f5bb58ac20424 2116 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​is_valid::​h447f9cb4920b7e61 20 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​null_count::​hae455f72a7279a3e 8 100.00% 100.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_buffer_memory_size::​ h2809390a4eed6266 0 —% 0.00% 0.00%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_buffer_memory_size::​ {{closure}}::​heebfb7be8c2594df 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_buffer_memory_size::​ {{closure}}::​{{closure}}::​h01196f357d1d6a03 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_array_memory_size::​ h3f4f457370b7ca02 0 —% 0.00% 0.00%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_array_memory_size::​{{closure}}::​ h02538c6ae3316045 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_array_memory_size::​{{closure}}::​ {{closure}}::​he444357c149e26a1 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as core::​fmt::​Debug>::​fmt::​h1faf5bc397169f19 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​selection_mask::​hb95ac02ac948714f 12 100.00% 100.00% —%
arrow_array::​array::​union_array::​selection_mask::​{{closure}}::​h5b56a701298b0690 340 100.00% 100.00% —%
arrow_array::​array::​union_array::​without_nulls_selected::​hb6fa385ba31b5a37 8 100.00% 100.00% —%
arrow_array::​array::​union_array::​without_nulls_selected::​{{closure}}::​hd04fc72b28d914c8 8 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_union_validity::​hf0ce18e5e3fc8a0f 2 100.00% 66.67% 62.50%
arrow_array::​array::​union_array::​tests::​union_fields::​h8947e313d26ed4ed 7 100.00% 50.00% 40.00%
<arrow_array::​array::​union_array::​UnionArray as core::​clone::​Clone>::​clone::​h0d0ece15a1e2ebd7 4 100.00% 37.50% 37.50%
<arrow_array::​array::​union_array::​Mask as core::​clone::​Clone>::​clone::​hb5ec1919762727d3 0 —% 0.00% —%
arrow_array::​array::​union_array::​tests::​test_dense_i32::​{{closure}}::​h6e1a7add9473da79 2 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_dense_i32::​h04c4263448742b2e 2 100.00% 67.18% 51.20%
arrow_array::​array::​union_array::​tests::​test_dense_i32_large::​{{closure}}::​h47c679f96df8c4a4 2 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_dense_i32_large::​hb4cd98b6aa4eb6a8 2 100.00% 61.46% 51.85%
arrow_array::​array::​union_array::​tests::​test_dense_i32_large::​{{closure}}::​h435e39e1e434c49c 2048 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_dense_mixed::​{{closure}}::​h4d7a70a36653ff0c 2 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_dense_mixed::​hdde118ac57433b3e 2 100.00% 61.17% 51.61%
arrow_array::​array::​union_array::​tests::​test_dense_mixed_with_nulls::​{{closure}}::​hd9a8af4b9ce059c9 0 —% 0.00% —%
arrow_array::​array::​union_array::​tests::​test_dense_mixed_with_nulls::​h231eed3b22b02cf0 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​tests::​test_dense_mixed_with_nulls_and_offset::​{{closure}}::​h4d62012886afd3c6 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_dense_mixed_with_nulls_and_offset::​h7668680a257fb73e 1 100.00% 59.30% 51.02%
arrow_array::​array::​union_array::​tests::​test_dense_mixed_with_str::​{{closure}}::​hcbe4a7a3364a2892 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_dense_mixed_with_str::​hffe542e8f127004a 1 100.00% 53.43% 47.32%
arrow_array::​array::​union_array::​tests::​test_sparse_i32::​{{closure}}::​h3b91b5df3fe9524c 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_sparse_i32::​h0a9eb8dce60981d0 1 100.00% 66.67% 50.71%
arrow_array::​array::​union_array::​tests::​test_sparse_mixed::​{{closure}}::​h0e0f5ef2aa772de4 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_sparse_mixed::​h1282cbf8931bc920 1 100.00% 62.99% 51.92%
arrow_array::​array::​union_array::​tests::​test_sparse_mixed_with_nulls::​{{closure}}::​hd2055ac7a6875a49 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_sparse_mixed_with_nulls::​h38ac73c642bece84 1 100.00% 60.87% 51.85%
arrow_array::​array::​union_array::​tests::​test_sparse_mixed_with_nulls_and_offset::​{{closure}}::​h3fdebb76b1942224 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_sparse_mixed_with_nulls_and_offset::​h12df46ae6f5b0964 1 100.00% 56.98% 51.58%
arrow_array::​array::​union_array::​tests::​test_union_array_validity::​{{closure}}::​h14d8205f40eaa02f 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_union_array_validity::​h03a798f7198a9af4 1 100.00% 68.09% 45.31%
arrow_array::​array::​union_array::​tests::​test_type_check::​{{closure}}::​h4a0bff8058a62d5e 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_type_check::​he299ca6124eb574e 1 100.00% 52.00% 41.67%
arrow_array::​array::​union_array::​tests::​slice_union_array::​{{closure}}::​hcbbc28b52447d956 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​slice_union_array::​h3f355e39a5cb9d22 1 100.00% 61.11% 44.44%
arrow_array::​array::​union_array::​tests::​slice_union_array::​create_union::​h485cadcf4a435dbc 2 100.00% 75.00% 42.86%
arrow_array::​array::​union_array::​tests::​slice_union_array::​create_batch::​h78e0550337ca3e24 2 100.00% 50.00% 36.84%
arrow_array::​array::​union_array::​tests::​slice_union_array::​test_slice_union::​h0aa645d23a7a799c 2 100.00% 51.43% 48.53%
arrow_array::​array::​union_array::​tests::​test_custom_type_ids::​{{closure}}::​he7b5cfbc29e5fcaa 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_custom_type_ids::​hebdfd7288b98faff 1 100.00% 47.98% 45.31%
arrow_array::​array::​union_array::​tests::​into_parts::​{{closure}}::​h6c6e715c9b087509 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​into_parts::​he9a57983207d9e27 1 100.00% 41.96% 40.14%
arrow_array::​array::​union_array::​tests::​into_parts::​{{closure}}::​hf811835e5f42b529 2 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​into_parts_custom_type_ids::​{{closure}}::​h4696b6b1fc4f1b75 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​into_parts_custom_type_ids::​hd228368b8f0047d4 1 100.00% 39.58% 39.13%
arrow_array::​array::​union_array::​tests::​test_invalid::​{{closure}}::​hac6f5b1c413343ae 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_invalid::​h0a210181d2c2a5e4 1 100.00% 37.92% 37.79%
arrow_array::​array::​union_array::​tests::​test_logical_nulls_fast_paths::​{{closure}}::​h387942921ffb9101 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_logical_nulls_fast_paths::​hbe23f6c75c3a0f9d 1 100.00% 40.62% 41.30%
arrow_array::​array::​union_array::​tests::​test_dense_union_logical_nulls_gather::​{{closure}}::​h9abcd06c692b05d9 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_dense_union_logical_nulls_gather::​h764e9ede257c5fa6 1 100.00% 38.75% 35.90%
arrow_array::​ array::​union_array::​tests::​ test_sparse_union_logical_nulls_mask_all_nulls_skip_one::​{{closure}}::​ h5ef2bd30d3e7c1c0 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_sparse_union_logical_nulls_mask_all_nulls_skip_one::​hd11412cafb392126 1 100.00% 39.63% 38.75%
arrow_array::​ array::​union_array::​tests::​ test_sparse_union_logical_mask_mixed_nulls_skip_fully_valid::​ {{closure}}::​h36c7907c1fdc7c71 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_sparse_union_logical_mask_mixed_nulls_skip_fully_valid::​hc66b26d900b0aad9 1 100.00% 40.00% 38.31%
arrow_array::​ array::​union_array::​tests::​ test_sparse_union_logical_mask_mixed_nulls_skip_fully_null::​ {{closure}}::​h9ee1218c7eca03e2 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_sparse_union_logical_mask_mixed_nulls_skip_fully_null::​hc34261edb427fdeb 1 100.00% 36.55% 36.76%
arrow_array::​array::​union_array::​tests::​test_sparse_union_logical_nulls_gather::​{{closure}}::​hbaf743de2d5d6406 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_sparse_union_logical_nulls_gather::​h022806951a88d14a 1 100.00% 40.74% 38.46%
arrow_array::​array::​union_array::​tests::​test_sparse_union_logical_nulls_gather::​{{closure}}::​h33b0f45047412b55 50 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​new_unchecked::​h5b05c70761364390 65 100.00% 46.15% 51.92%
arrow_array::​array::​union_array::​UnionArray::​try_new::​h21618cc389322f55 62 100.00% 56.96% 53.92%
arrow_array::​array::​union_array::​UnionArray::​try_new::​{{closure}}::​hedbe1f5e763cf707 102 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​try_new::​{{closure}}::​h52c59cb60895c315 109 100.00% 83.33% 50.00%
arrow_array::​array::​union_array::​UnionArray::​child::​hf7fa9b256bf23a5a 95 100.00% 80.00% 50.00%
arrow_array::​array::​union_array::​UnionArray::​type_id::​hbe6a58baccdce622 48 100.00% 71.43% 50.00%
arrow_array::​array::​union_array::​UnionArray::​type_ids::​heee9ef9cd540c76c 27 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​offsets::​h87ad62752be584f6 58 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​value_offset::​h753a347bf4842e40 32 100.00% 72.73% 66.67%
arrow_array::​array::​union_array::​UnionArray::​value::​h9536add5dfa8418f 32 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​type_names::​hf61f66e5b1249ad4 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​type_names::​{{closure}}::​hb9d865c30e93b1e8 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​is_dense::​heb10f439abf5fc87 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​slice::​h5fdd70d8d7722294 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​slice::​{{closure}}::​hc5a9b8015b2a0a25 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​slice::​{{closure}}::​{{closure}}::​h2040b7f32927e319 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​into_parts::​hf448e905c6d401a8 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​into_parts::​{{closure}}::​h47f5178d7e9f3a76 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as core::​convert::​From<arrow_data::​data::​ArrayData>>::​from::​ h0557581b09372bac 80 100.00% 51.69% 48.96%
<arrow_array::​ array::​union_array::​UnionArray as core::​convert::​From<arrow_data::​data::​ArrayData>>::​from::​ {{closure}}::​h57ccecc9005deb2b 131 100.00% 100.00% —%
arrow_array::​ array::​union_array::​<impl core::​convert::​From<arrow_array::​array::​union_array::​ UnionArray> for arrow_data::​data::​ArrayData>::​from::​he690e58bf17d1364 21 100.00% 38.46% 33.87%
arrow_array::​ array::​union_array::​<impl core::​convert::​From<arrow_array::​array::​union_array::​ UnionArray> for arrow_data::​data::​ArrayData>::​from::​{{closure}}::​ h4e952475c5184c6a 28 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​as_any::​h3fbc2bafab7ccc8e 20 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​to_data::​h3280654c8bc21b80 20 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​into_data::​hb9d4ac894a96460f 1 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​data_type::​hbf84d4e7ebbdf670 89 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​slice::​hd9e76faa799a405e 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​len::​he2edeef54b5b4d27 136 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​is_empty::​hf4f72e7732fa8431 34 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​offset::​h75238bacca107e37 9 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​nulls::​hc58d1827d270e04b 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​is_null::​hf0cff83720d6f2f7 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​is_valid::​h9fc2d0a7e4afbb3a 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​null_count::​h595613cf9c1bfebc 3 100.00% 100.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_buffer_memory_size::​ hda26d37be29fb37a 0 —% 0.00% 0.00%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_buffer_memory_size::​ {{closure}}::​h3584be34b3d004f1 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_buffer_memory_size::​ {{closure}}::​{{closure}}::​h9c7f789e686ddebc 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_array_memory_size::​ h96bcdc6613c45549 0 —% 0.00% 0.00%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_array_memory_size::​{{closure}}::​ h1a3cfd3a26b683bc 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_array_memory_size::​{{closure}}::​ {{closure}}::​hff7ce700c4c3f662 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as core::​fmt::​Debug>::​fmt::​h908f6236795cb8a1 0 —% 0.00% 0.00%
<arrow_array::​array::​union_array::​UnionArray as core::​clone::​Clone>::​clone::​h53ecaa43a85c27c6 20 100.00% 37.50% 37.50%
arrow_array::​array::​union_array::​UnionArray::​new_unchecked::​h36517d66ca3794f4 33 100.00% 46.15% 51.92%
arrow_array::​array::​union_array::​UnionArray::​try_new::​h8c586dc2e3dd05d6 40 100.00% 76.14% 55.17%
arrow_array::​array::​union_array::​UnionArray::​try_new::​{{closure}}::​h45ba5bb76d9d9bad 130 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​try_new::​{{closure}}::​h36c7355a66b836ea 1089 100.00% 83.33% 50.00%
arrow_array::​array::​union_array::​UnionArray::​child::​hce65e76392a03143 1178 100.00% 80.00% 50.00%
arrow_array::​array::​union_array::​UnionArray::​type_id::​h5a8527b938ac329b 2149 100.00% 71.43% 50.00%
arrow_array::​array::​union_array::​UnionArray::​type_ids::​h52700b41791f2de1 6 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​offsets::​hf0a8bbf83ad4cce5 6 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​value_offset::​heb6c9f52efa13328 2128 100.00% 72.73% 66.67%
arrow_array::​array::​union_array::​UnionArray::​value::​h2c2c7f3de50d846d 1091 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​type_names::​hefa49e1b2cfc6ab0 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​type_names::​{{closure}}::​h170231b91de88fdf 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​is_dense::​h0b6cb2adcb5822dd 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​slice::​h09925b857248f268 4 100.00% 42.86% 41.67%
arrow_array::​array::​union_array::​UnionArray::​slice::​{{closure}}::​h433b86864ac210d8 4 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​slice::​{{closure}}::​{{closure}}::​h52f1ec40875d7fae 4 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​into_parts::​h6a925564ccb23a03 3 100.00% 29.03% 23.08%
arrow_array::​array::​union_array::​UnionArray::​into_parts::​{{closure}}::​hd39d09a790ddd844 7 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_without_nulls::​h2dc7c1c3af616694 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​h240e0768fa69649e 2 100.00% 52.63% 38.64%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​h2c47ff6fa002ddc7 6 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​ha1fe04a0f1e6a4c9 4 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​hd4f16fbc2394c999 4 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​h4523a8952728fe28 2 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​{{closure}}::​hf56a2b75cc63f994 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​h026945f9d8915f0f 2 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​{{closure}}::​h075037d056dc5eda 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_all_with_nulls_skip_one::​h5bd9c28fdd6db581 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_all_with_nulls_skip_one::​{{closure}}::​h14553a30c58ddbdb 0 —% 0.00% —%
arrow_array::​ array::​union_array::​UnionArray::​ mask_sparse_all_with_nulls_skip_one::​{{closure}}::​{{closure}}::​ hc176793a7e579bc9 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_all_with_nulls_skip_one::​{{closure}}::​hfa839a5643235971 1 100.00% 100.00% —%
arrow_array::​ array::​union_array::​UnionArray::​ mask_sparse_all_with_nulls_skip_one::​{{closure}}::​{{closure}}::​ hc12ce01957802229 2 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​h20ceed6ce1c52edd 1 100.00% 54.72% 40.00%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​hbc652904d044d13b 2 100.00% 54.72% 40.00%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​h672e28a67bd6734c 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​hc26378c425546ed7 2 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​h3f95682d467f0106 2 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​hf6c6ad2ca6a276f5 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​hac673c20414f88e8 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​hf9fbca0b28a7b7ec 2 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​gather_nulls::​h08ff57ffe36b5fdf 6 100.00% 63.27% 56.82%
arrow_array::​array::​union_array::​UnionArray::​gather_nulls::​{{closure}}::​h8ee7a8c02f594637 6 100.00% 80.00% 50.00%
arrow_array::​array::​union_array::​UnionArray::​gather_nulls::​{{closure}}::​h236d0d59f23358fb 336 100.00% 80.00% 50.00%
<arrow_array::​ array::​union_array::​UnionArray as core::​convert::​From<arrow_data::​data::​ArrayData>>::​from::​ h68c09739a61cd0e5 38 100.00% 51.69% 46.88%
<arrow_array::​ array::​union_array::​UnionArray as core::​convert::​From<arrow_data::​data::​ArrayData>>::​from::​ {{closure}}::​hdb12f952444f9962 134 100.00% 100.00% —%
arrow_array::​ array::​union_array::​<impl core::​convert::​From<arrow_array::​array::​union_array::​ UnionArray> for arrow_data::​data::​ArrayData>::​from::​h1c3fda04601bb870 2 100.00% 38.46% 33.87%
arrow_array::​ array::​union_array::​<impl core::​convert::​From<arrow_array::​array::​union_array::​ UnionArray> for arrow_data::​data::​ArrayData>::​from::​{{closure}}::​ hc1628785e2140bd4 4 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​as_any::​he566b253791efa08 6 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​to_data::​hd3371bd8a589834f 2 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​into_data::​h30e85eb2dc35b2ea 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​data_type::​h286067170107f9dc 20 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​slice::​h7a5d39ec2dc94cd9 2 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​len::​hbe31af8392654e2e 2162 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​is_empty::​hb7d0238f8a7cc4f3 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​offset::​hdd2e777288e6f319 27 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​nulls::​hfcedf77546a6fd92 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​h692466b66b6bff4b 14 100.00% 76.06% 49.47%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ h58c73ff8daf9748f 81 100.00% 85.71% 100.00%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ hc36cc3ee6503f344 55 100.00% 100.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ hfbf33dcb828132b2 55 100.00% 100.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ h5da866bd323bde98 3 100.00% 100.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ h10c9fcaa32e0548d 1 100.00% 100.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ hfe79b83c78ced105 32 100.00% 100.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ h31a920fafe7ba83a 27 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​is_null::​hc29f5bb58ac20424 1058 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​is_valid::​h447f9cb4920b7e61 10 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​null_count::​hae455f72a7279a3e 4 100.00% 100.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_buffer_memory_size::​ h2809390a4eed6266 0 —% 0.00% 0.00%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_buffer_memory_size::​ {{closure}}::​heebfb7be8c2594df 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_buffer_memory_size::​ {{closure}}::​{{closure}}::​h01196f357d1d6a03 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_array_memory_size::​ h3f4f457370b7ca02 0 —% 0.00% 0.00%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_array_memory_size::​{{closure}}::​ h02538c6ae3316045 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_array_memory_size::​{{closure}}::​ {{closure}}::​he444357c149e26a1 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as core::​fmt::​Debug>::​fmt::​h1faf5bc397169f19 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​selection_mask::​hb95ac02ac948714f 6 100.00% 100.00% —%
arrow_array::​array::​union_array::​selection_mask::​{{closure}}::​h5b56a701298b0690 170 100.00% 100.00% —%
arrow_array::​array::​union_array::​without_nulls_selected::​hb6fa385ba31b5a37 4 100.00% 100.00% —%
arrow_array::​array::​union_array::​without_nulls_selected::​{{closure}}::​hd04fc72b28d914c8 4 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_union_validity::​hf0ce18e5e3fc8a0f 2 100.00% 66.67% 62.50%
arrow_array::​array::​union_array::​tests::​union_fields::​h8947e313d26ed4ed 7 100.00% 50.00% 40.00%
<arrow_array::​array::​union_array::​UnionArray as core::​clone::​Clone>::​clone::​h0d0ece15a1e2ebd7 2 100.00% 37.50% 37.50%
<arrow_array::​array::​union_array::​Mask as core::​clone::​Clone>::​clone::​hb5ec1919762727d3 0 —% 0.00% —%
arrow_array::​array::​union_array::​tests::​test_dense_i32::​{{closure}}::​h6e1a7add9473da79 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_dense_i32::​h04c4263448742b2e 1 100.00% 67.18% 51.20%
arrow_array::​array::​union_array::​tests::​test_dense_i32_large::​{{closure}}::​h47c679f96df8c4a4 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_dense_i32_large::​hb4cd98b6aa4eb6a8 1 100.00% 61.46% 51.85%
arrow_array::​array::​union_array::​tests::​test_dense_i32_large::​{{closure}}::​h435e39e1e434c49c 1024 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_dense_mixed::​{{closure}}::​h4d7a70a36653ff0c 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_dense_mixed::​hdde118ac57433b3e 1 100.00% 61.17% 51.61%
arrow_array::​array::​union_array::​tests::​test_dense_mixed_with_nulls::​{{closure}}::​hd9a8af4b9ce059c9 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_dense_mixed_with_nulls::​h231eed3b22b02cf0 1 100.00% 59.26% 51.59%
arrow_array::​array::​union_array::​tests::​test_dense_mixed_with_nulls_and_offset::​{{closure}}::​h4d62012886afd3c6 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_dense_mixed_with_nulls_and_offset::​h7668680a257fb73e 1 100.00% 59.30% 51.02%
arrow_array::​array::​union_array::​tests::​test_dense_mixed_with_str::​{{closure}}::​hcbe4a7a3364a2892 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_dense_mixed_with_str::​hffe542e8f127004a 1 100.00% 53.43% 47.32%
arrow_array::​array::​union_array::​tests::​test_sparse_i32::​{{closure}}::​h3b91b5df3fe9524c 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_sparse_i32::​h0a9eb8dce60981d0 1 100.00% 66.67% 50.71%
arrow_array::​array::​union_array::​tests::​test_sparse_mixed::​{{closure}}::​h0e0f5ef2aa772de4 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_sparse_mixed::​h1282cbf8931bc920 1 100.00% 62.99% 51.92%
arrow_array::​array::​union_array::​tests::​test_sparse_mixed_with_nulls::​{{closure}}::​hd2055ac7a6875a49 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_sparse_mixed_with_nulls::​h38ac73c642bece84 1 100.00% 60.87% 51.85%
arrow_array::​array::​union_array::​tests::​test_sparse_mixed_with_nulls_and_offset::​{{closure}}::​h3fdebb76b1942224 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_sparse_mixed_with_nulls_and_offset::​h12df46ae6f5b0964 1 100.00% 56.98% 51.58%
arrow_array::​array::​union_array::​tests::​test_union_array_validity::​{{closure}}::​h14d8205f40eaa02f 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_union_array_validity::​h03a798f7198a9af4 1 100.00% 68.09% 45.31%
arrow_array::​array::​union_array::​tests::​test_type_check::​{{closure}}::​h4a0bff8058a62d5e 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_type_check::​he299ca6124eb574e 1 100.00% 52.00% 41.67%
arrow_array::​array::​union_array::​tests::​slice_union_array::​{{closure}}::​hcbbc28b52447d956 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​slice_union_array::​h3f355e39a5cb9d22 1 100.00% 61.11% 44.44%
arrow_array::​array::​union_array::​tests::​slice_union_array::​create_union::​h485cadcf4a435dbc 2 100.00% 75.00% 42.86%
arrow_array::​array::​union_array::​tests::​slice_union_array::​create_batch::​h78e0550337ca3e24 2 100.00% 50.00% 36.84%
arrow_array::​array::​union_array::​tests::​slice_union_array::​test_slice_union::​h0aa645d23a7a799c 2 100.00% 51.43% 48.53%
arrow_array::​array::​union_array::​tests::​test_custom_type_ids::​{{closure}}::​he7b5cfbc29e5fcaa 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_custom_type_ids::​hebdfd7288b98faff 1 100.00% 47.98% 45.31%
arrow_array::​array::​union_array::​tests::​into_parts::​{{closure}}::​h6c6e715c9b087509 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​into_parts::​he9a57983207d9e27 1 100.00% 41.96% 40.14%
arrow_array::​array::​union_array::​tests::​into_parts::​{{closure}}::​hf811835e5f42b529 2 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​into_parts_custom_type_ids::​{{closure}}::​h4696b6b1fc4f1b75 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​into_parts_custom_type_ids::​hd228368b8f0047d4 1 100.00% 39.58% 39.13%
arrow_array::​array::​union_array::​tests::​test_invalid::​{{closure}}::​hac6f5b1c413343ae 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_invalid::​h0a210181d2c2a5e4 1 100.00% 37.92% 37.79%
arrow_array::​array::​union_array::​tests::​test_logical_nulls_fast_paths::​{{closure}}::​h387942921ffb9101 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_logical_nulls_fast_paths::​hbe23f6c75c3a0f9d 1 100.00% 40.62% 41.30%
arrow_array::​array::​union_array::​tests::​test_dense_union_logical_nulls_gather::​{{closure}}::​h9abcd06c692b05d9 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_dense_union_logical_nulls_gather::​h764e9ede257c5fa6 1 100.00% 38.75% 35.90%
arrow_array::​ array::​union_array::​tests::​ test_sparse_union_logical_nulls_mask_all_nulls_skip_one::​{{closure}}::​ h5ef2bd30d3e7c1c0 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_sparse_union_logical_nulls_mask_all_nulls_skip_one::​hd11412cafb392126 1 100.00% 39.63% 38.75%
arrow_array::​ array::​union_array::​tests::​ test_sparse_union_logical_mask_mixed_nulls_skip_fully_valid::​ {{closure}}::​h36c7907c1fdc7c71 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_sparse_union_logical_mask_mixed_nulls_skip_fully_valid::​hc66b26d900b0aad9 1 100.00% 40.00% 38.31%
arrow_array::​ array::​union_array::​tests::​ test_sparse_union_logical_mask_mixed_nulls_skip_fully_null::​ {{closure}}::​h9ee1218c7eca03e2 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_sparse_union_logical_mask_mixed_nulls_skip_fully_null::​hc34261edb427fdeb 1 100.00% 36.55% 36.76%
arrow_array::​array::​union_array::​tests::​test_sparse_union_logical_nulls_gather::​{{closure}}::​hbaf743de2d5d6406 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_sparse_union_logical_nulls_gather::​h022806951a88d14a 1 100.00% 40.74% 38.46%
arrow_array::​array::​union_array::​tests::​test_sparse_union_logical_nulls_gather::​{{closure}}::​h33b0f45047412b55 50 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​new_unchecked::​h6545eac2010692f3 6 100.00% 46.15% 36.54%
arrow_array::​array::​union_array::​UnionArray::​try_new::​h46fe6f5ef76a28d2 6 100.00% 59.09% 42.24%
arrow_array::​array::​union_array::​UnionArray::​try_new::​{{closure}}::​h8c9434bdcf573b9f 10 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​try_new::​{{closure}}::​h4a4d7c84bdc0fd87 8 100.00% 83.33% 50.00%
arrow_array::​array::​union_array::​UnionArray::​child::​h8ec2b65a4e9b11bd 6 100.00% 80.00% 50.00%
arrow_array::​array::​union_array::​UnionArray::​type_id::​h5a87cd299bdd53db 12 100.00% 71.43% 50.00%
arrow_array::​array::​union_array::​UnionArray::​type_ids::​h358ba86a06896d08 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​offsets::​hb17fa1750f47ace9 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​value_offset::​h5d2b19f00b4fa4ac 12 100.00% 72.73% 66.67%
arrow_array::​array::​union_array::​UnionArray::​value::​h2eec57ef95fd4260 6 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​type_names::​hd672141871925ca0 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​type_names::​{{closure}}::​he40c3583f0620527 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​is_dense::​h777c944ea1d7479c 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​slice::​hb98e46588c9ce5ba 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​slice::​{{closure}}::​h682435174c26f8b9 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​slice::​{{closure}}::​{{closure}}::​heee1ce294fd7d067 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​into_parts::​h3c1b890997784b6f 1 100.00% 29.03% 23.08%
arrow_array::​array::​union_array::​UnionArray::​into_parts::​{{closure}}::​ha5ba22003e2387b5 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_without_nulls::​hef30729aa7e78476 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_without_nulls::​{{closure}}::​h23ade88dea142853 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_without_nulls::​{{closure}}::​h94cd9ee662185aca 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_without_nulls::​{{closure}}::​{{closure}}::​hd77f08af528309f0 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_without_nulls::​{{closure}}::​h48436b3fe2afe73b 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_without_nulls::​{{closure}}::​{{closure}}::​h07b57460f6f9d4ea 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​h01aa03fa40bcf62f 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​h8341b32cf567a374 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​h4485518cf517cc5a 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​heb0e48695938865b 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​ha1e72bb1cb8f8c29 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​{{closure}}::​hc863859e5ff2bec8 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​hf86a1aecedebe7b5 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​{{closure}}::​hbfc668b309501d19 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_all_with_nulls_skip_one::​h2aa3e04ffae434ef 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_all_with_nulls_skip_one::​{{closure}}::​h932cbbcb80428623 0 —% 0.00% 0.00%
arrow_array::​ array::​union_array::​UnionArray::​ mask_sparse_all_with_nulls_skip_one::​{{closure}}::​{{closure}}::​ hf40cec30012a7d86 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_all_with_nulls_skip_one::​{{closure}}::​he6635a9f79ff165e 0 —% 0.00% —%
arrow_array::​ array::​union_array::​UnionArray::​ mask_sparse_all_with_nulls_skip_one::​{{closure}}::​{{closure}}::​ h2f878367b01adcf6 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​h3d43ade319bbcdd1 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​h8cde4f5fdd59561c 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​h9efe8bce3635b3eb 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​h8c9efaacd43897c3 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​hd81cff4d55600ad7 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​hd9e86747ea17c4c8 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​h0127978e38c4d67a 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​h130c91a9b24f6301 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​h8ed0c8c428bc652d 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​h1525e5c1f2903098 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​h49eae5fc12f708e1 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​h9620085ba5ce695d 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​gather_nulls::​hb70837484369369f 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​gather_nulls::​{{closure}}::​hedc6b487fd3237af 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​gather_nulls::​{{closure}}::​ha96ba7467b4ddc61 0 —% 0.00% 0.00%
<arrow_array::​ array::​union_array::​UnionArray as core::​convert::​From<arrow_data::​data::​ArrayData>>::​from::​ h5dce0bef162438cd 6 100.00% 51.69% 42.71%
<arrow_array::​ array::​union_array::​UnionArray as core::​convert::​From<arrow_data::​data::​ArrayData>>::​from::​ {{closure}}::​hea4fc95e8a4ce783 10 100.00% 100.00% —%
arrow_array::​ array::​union_array::​<impl core::​convert::​From<arrow_array::​array::​union_array::​ UnionArray> for arrow_data::​data::​ArrayData>::​from::​he574e3746bf359b1 0 —% 0.00% 0.00%
arrow_array::​ array::​union_array::​<impl core::​convert::​From<arrow_array::​array::​union_array::​ UnionArray> for arrow_data::​data::​ArrayData>::​from::​{{closure}}::​ ha8fa2a393e8f41e2 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​as_any::​h6748cfa32b620f40 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​to_data::​h17ccfb8cb5fb5cfa 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​into_data::​h9ff39ec48442ccc8 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​data_type::​h9a69a375b75a2b50 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​slice::​h18319614cf3cdc24 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​len::​h55323bc97ddca8e0 12 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​is_empty::​h54cd2f98e5a35f3b 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​offset::​ha3403666194aaa13 6 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​nulls::​h0c355ecdc737a7a4 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​h29a0ec8fd6667b35 0 —% 0.00% 0.00%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ he6bffb1bc5e0ece3 0 —% 0.00% 0.00%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ h9b09d894dcce6234 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ hab548f9302af1c09 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ h56c62afece7414f9 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ h6783477ef87d8d23 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ h49d3d231c1831a7b 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ he0c9fbd466614ba4 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​is_null::​h213bd79d133ef812 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​is_valid::​had04e4034a24a577 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​null_count::​h67348f51fb12c40e 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_buffer_memory_size::​ hc3f50b008cd01eb9 0 —% 0.00% 0.00%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_buffer_memory_size::​ {{closure}}::​h5a010a5d4a08d8b2 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_buffer_memory_size::​ {{closure}}::​{{closure}}::​h1cca4d6887c2ddd7 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_array_memory_size::​ h42a654f130b8df1b 0 —% 0.00% 0.00%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_array_memory_size::​{{closure}}::​ ha3079aabef472bfd 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_array_memory_size::​{{closure}}::​ {{closure}}::​he25d9b21ed0b5d7a 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as core::​fmt::​Debug>::​fmt::​he8a0b36546a39b7d 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​selection_mask::​h8f8226eb6d4500f1 0 —% 0.00% —%
arrow_array::​array::​union_array::​selection_mask::​{{closure}}::​hada823623363be4a 0 —% 0.00% —%
arrow_array::​array::​union_array::​without_nulls_selected::​hafd994462934a258 0 —% 0.00% —%
arrow_array::​array::​union_array::​without_nulls_selected::​{{closure}}::​h7e0137777ec3927a 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as core::​clone::​Clone>::​clone::​he29f379bffa97d8b 0 —% 0.00% 0.00%
<arrow_array::​array::​union_array::​Mask as core::​clone::​Clone>::​clone::​h8b020d2afd2d9d1d 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​new_unchecked::​h6545eac2010692f3 6 100.00% 46.15% 36.54%
arrow_array::​array::​union_array::​UnionArray::​try_new::​h46fe6f5ef76a28d2 6 100.00% 59.09% 42.24%
arrow_array::​array::​union_array::​UnionArray::​try_new::​{{closure}}::​h8c9434bdcf573b9f 10 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​try_new::​{{closure}}::​h4a4d7c84bdc0fd87 8 100.00% 83.33% 50.00%
arrow_array::​array::​union_array::​UnionArray::​child::​h8ec2b65a4e9b11bd 6 100.00% 80.00% 50.00%
arrow_array::​array::​union_array::​UnionArray::​type_id::​h5a87cd299bdd53db 12 100.00% 71.43% 50.00%
arrow_array::​array::​union_array::​UnionArray::​type_ids::​h358ba86a06896d08 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​offsets::​hb17fa1750f47ace9 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​value_offset::​h5d2b19f00b4fa4ac 12 100.00% 72.73% 66.67%
arrow_array::​array::​union_array::​UnionArray::​value::​h2eec57ef95fd4260 6 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​type_names::​hd672141871925ca0 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​type_names::​{{closure}}::​he40c3583f0620527 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​is_dense::​h777c944ea1d7479c 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​slice::​hb98e46588c9ce5ba 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​slice::​{{closure}}::​h682435174c26f8b9 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​slice::​{{closure}}::​{{closure}}::​heee1ce294fd7d067 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​into_parts::​h3c1b890997784b6f 1 100.00% 29.03% 23.08%
arrow_array::​array::​union_array::​UnionArray::​into_parts::​{{closure}}::​ha5ba22003e2387b5 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_without_nulls::​hef30729aa7e78476 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_without_nulls::​{{closure}}::​h23ade88dea142853 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_without_nulls::​{{closure}}::​h94cd9ee662185aca 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_without_nulls::​{{closure}}::​{{closure}}::​hd77f08af528309f0 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_without_nulls::​{{closure}}::​h48436b3fe2afe73b 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_without_nulls::​{{closure}}::​{{closure}}::​h07b57460f6f9d4ea 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​h01aa03fa40bcf62f 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​h8341b32cf567a374 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​h4485518cf517cc5a 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​heb0e48695938865b 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​ha1e72bb1cb8f8c29 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​{{closure}}::​hc863859e5ff2bec8 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​hf86a1aecedebe7b5 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​{{closure}}::​hbfc668b309501d19 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_all_with_nulls_skip_one::​h2aa3e04ffae434ef 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_all_with_nulls_skip_one::​{{closure}}::​h932cbbcb80428623 0 —% 0.00% 0.00%
arrow_array::​ array::​union_array::​UnionArray::​ mask_sparse_all_with_nulls_skip_one::​{{closure}}::​{{closure}}::​ hf40cec30012a7d86 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_all_with_nulls_skip_one::​{{closure}}::​he6635a9f79ff165e 0 —% 0.00% —%
arrow_array::​ array::​union_array::​UnionArray::​ mask_sparse_all_with_nulls_skip_one::​{{closure}}::​{{closure}}::​ h2f878367b01adcf6 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​h3d43ade319bbcdd1 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​h8cde4f5fdd59561c 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​h9efe8bce3635b3eb 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​h8c9efaacd43897c3 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​hd81cff4d55600ad7 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​hd9e86747ea17c4c8 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​h0127978e38c4d67a 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​h130c91a9b24f6301 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​h8ed0c8c428bc652d 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​h1525e5c1f2903098 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​h49eae5fc12f708e1 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​h9620085ba5ce695d 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​gather_nulls::​hb70837484369369f 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​gather_nulls::​{{closure}}::​hedc6b487fd3237af 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​gather_nulls::​{{closure}}::​ha96ba7467b4ddc61 0 —% 0.00% 0.00%
<arrow_array::​ array::​union_array::​UnionArray as core::​convert::​From<arrow_data::​data::​ArrayData>>::​from::​ h5dce0bef162438cd 6 100.00% 51.69% 42.71%
<arrow_array::​ array::​union_array::​UnionArray as core::​convert::​From<arrow_data::​data::​ArrayData>>::​from::​ {{closure}}::​hea4fc95e8a4ce783 10 100.00% 100.00% —%
arrow_array::​ array::​union_array::​<impl core::​convert::​From<arrow_array::​array::​union_array::​ UnionArray> for arrow_data::​data::​ArrayData>::​from::​he574e3746bf359b1 0 —% 0.00% 0.00%
arrow_array::​ array::​union_array::​<impl core::​convert::​From<arrow_array::​array::​union_array::​ UnionArray> for arrow_data::​data::​ArrayData>::​from::​{{closure}}::​ ha8fa2a393e8f41e2 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​as_any::​h6748cfa32b620f40 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​to_data::​h17ccfb8cb5fb5cfa 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​into_data::​h9ff39ec48442ccc8 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​data_type::​h9a69a375b75a2b50 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​slice::​h18319614cf3cdc24 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​len::​h55323bc97ddca8e0 12 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​is_empty::​h54cd2f98e5a35f3b 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​offset::​ha3403666194aaa13 6 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​nulls::​h0c355ecdc737a7a4 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​h29a0ec8fd6667b35 0 —% 0.00% 0.00%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ he6bffb1bc5e0ece3 0 —% 0.00% 0.00%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ h9b09d894dcce6234 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ hab548f9302af1c09 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ h56c62afece7414f9 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ h6783477ef87d8d23 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ h49d3d231c1831a7b 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ he0c9fbd466614ba4 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​is_null::​h213bd79d133ef812 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​is_valid::​had04e4034a24a577 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​null_count::​h67348f51fb12c40e 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_buffer_memory_size::​ hc3f50b008cd01eb9 0 —% 0.00% 0.00%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_buffer_memory_size::​ {{closure}}::​h5a010a5d4a08d8b2 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_buffer_memory_size::​ {{closure}}::​{{closure}}::​h1cca4d6887c2ddd7 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_array_memory_size::​ h42a654f130b8df1b 0 —% 0.00% 0.00%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_array_memory_size::​{{closure}}::​ ha3079aabef472bfd 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_array_memory_size::​{{closure}}::​ {{closure}}::​he25d9b21ed0b5d7a 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as core::​fmt::​Debug>::​fmt::​he8a0b36546a39b7d 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​selection_mask::​h8f8226eb6d4500f1 0 —% 0.00% —%
arrow_array::​array::​union_array::​selection_mask::​{{closure}}::​hada823623363be4a 0 —% 0.00% —%
arrow_array::​array::​union_array::​without_nulls_selected::​hafd994462934a258 0 —% 0.00% —%
arrow_array::​array::​union_array::​without_nulls_selected::​{{closure}}::​h7e0137777ec3927a 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as core::​clone::​Clone>::​clone::​he29f379bffa97d8b 0 —% 0.00% 0.00%
<arrow_array::​array::​union_array::​Mask as core::​clone::​Clone>::​clone::​h8b020d2afd2d9d1d 0 —% 0.00% —%
arrow_array::​array::​union_array::​tests::​test_union_validity::​hf0ce18e5e3fc8a0f 2 100.00% 66.67% 62.50%
arrow_array::​array::​union_array::​tests::​union_fields::​h8947e313d26ed4ed 7 100.00% 50.00% 40.00%
arrow_array::​array::​union_array::​tests::​test_dense_mixed_with_nulls::​{{closure}}::​hd9a8af4b9ce059c9 2 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_dense_mixed_with_nulls::​h231eed3b22b02cf0 2 100.00% 59.26% 51.59%
arrow_array::​array::​union_array::​tests::​test_dense_mixed_with_nulls_and_offset::​{{closure}}::​h4d62012886afd3c6 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_dense_mixed_with_nulls_and_offset::​h7668680a257fb73e 1 100.00% 59.30% 51.02%
arrow_array::​array::​union_array::​tests::​test_dense_mixed_with_str::​{{closure}}::​hcbe4a7a3364a2892 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_dense_mixed_with_str::​hffe542e8f127004a 1 100.00% 53.43% 47.32%
arrow_array::​array::​union_array::​tests::​test_sparse_i32::​{{closure}}::​h3b91b5df3fe9524c 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_sparse_i32::​h0a9eb8dce60981d0 1 100.00% 66.67% 50.71%
arrow_array::​array::​union_array::​tests::​test_sparse_mixed::​{{closure}}::​h0e0f5ef2aa772de4 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_sparse_mixed::​h1282cbf8931bc920 1 100.00% 62.99% 51.92%
arrow_array::​array::​union_array::​tests::​test_sparse_mixed_with_nulls::​{{closure}}::​hd2055ac7a6875a49 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_sparse_mixed_with_nulls::​h38ac73c642bece84 1 100.00% 60.87% 51.85%
arrow_array::​array::​union_array::​tests::​test_sparse_mixed_with_nulls_and_offset::​{{closure}}::​h3fdebb76b1942224 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_sparse_mixed_with_nulls_and_offset::​h12df46ae6f5b0964 1 100.00% 56.98% 51.58%
arrow_array::​array::​union_array::​tests::​test_union_array_validity::​{{closure}}::​h14d8205f40eaa02f 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_union_array_validity::​h03a798f7198a9af4 1 100.00% 68.09% 45.31%
arrow_array::​array::​union_array::​tests::​test_type_check::​{{closure}}::​h4a0bff8058a62d5e 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_type_check::​he299ca6124eb574e 1 100.00% 52.00% 41.67%
arrow_array::​array::​union_array::​tests::​slice_union_array::​{{closure}}::​hcbbc28b52447d956 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​slice_union_array::​h3f355e39a5cb9d22 1 100.00% 61.11% 44.44%
arrow_array::​array::​union_array::​tests::​slice_union_array::​create_union::​h485cadcf4a435dbc 2 100.00% 75.00% 42.86%
arrow_array::​array::​union_array::​tests::​slice_union_array::​create_batch::​h78e0550337ca3e24 2 100.00% 50.00% 36.84%
arrow_array::​array::​union_array::​tests::​slice_union_array::​test_slice_union::​h0aa645d23a7a799c 2 100.00% 51.43% 48.53%
arrow_array::​array::​union_array::​tests::​test_custom_type_ids::​{{closure}}::​he7b5cfbc29e5fcaa 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_custom_type_ids::​hebdfd7288b98faff 1 100.00% 47.98% 45.31%
arrow_array::​array::​union_array::​tests::​into_parts::​{{closure}}::​h6c6e715c9b087509 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​into_parts::​he9a57983207d9e27 1 100.00% 41.96% 40.14%
arrow_array::​array::​union_array::​tests::​into_parts::​{{closure}}::​hf811835e5f42b529 2 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​into_parts_custom_type_ids::​{{closure}}::​h4696b6b1fc4f1b75 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​into_parts_custom_type_ids::​hd228368b8f0047d4 1 100.00% 39.58% 39.13%
arrow_array::​array::​union_array::​tests::​test_invalid::​{{closure}}::​hac6f5b1c413343ae 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_invalid::​h0a210181d2c2a5e4 1 100.00% 37.92% 37.79%
arrow_array::​array::​union_array::​tests::​test_logical_nulls_fast_paths::​{{closure}}::​h387942921ffb9101 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_logical_nulls_fast_paths::​hbe23f6c75c3a0f9d 1 100.00% 40.62% 41.30%
arrow_array::​array::​union_array::​tests::​test_dense_union_logical_nulls_gather::​{{closure}}::​h9abcd06c692b05d9 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_dense_union_logical_nulls_gather::​h764e9ede257c5fa6 1 100.00% 38.75% 35.90%
arrow_array::​ array::​union_array::​tests::​ test_sparse_union_logical_nulls_mask_all_nulls_skip_one::​{{closure}}::​ h5ef2bd30d3e7c1c0 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_sparse_union_logical_nulls_mask_all_nulls_skip_one::​hd11412cafb392126 1 100.00% 39.63% 38.75%
arrow_array::​ array::​union_array::​tests::​ test_sparse_union_logical_mask_mixed_nulls_skip_fully_valid::​ {{closure}}::​h36c7907c1fdc7c71 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_sparse_union_logical_mask_mixed_nulls_skip_fully_valid::​hc66b26d900b0aad9 1 100.00% 40.00% 38.31%
arrow_array::​ array::​union_array::​tests::​ test_sparse_union_logical_mask_mixed_nulls_skip_fully_null::​ {{closure}}::​h9ee1218c7eca03e2 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_sparse_union_logical_mask_mixed_nulls_skip_fully_null::​hc34261edb427fdeb 1 100.00% 36.55% 36.76%
arrow_array::​array::​union_array::​tests::​test_sparse_union_logical_nulls_gather::​{{closure}}::​hbaf743de2d5d6406 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_sparse_union_logical_nulls_gather::​h022806951a88d14a 1 100.00% 40.74% 38.46%
arrow_array::​array::​union_array::​tests::​test_sparse_union_logical_nulls_gather::​{{closure}}::​h33b0f45047412b55 50 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​new_unchecked::​h36517d66ca3794f4 34 100.00% 46.15% 36.54%
arrow_array::​array::​union_array::​UnionArray::​try_new::​h8c586dc2e3dd05d6 39 100.00% 76.14% 56.90%
arrow_array::​array::​union_array::​UnionArray::​try_new::​{{closure}}::​h45ba5bb76d9d9bad 130 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​try_new::​{{closure}}::​h36c7355a66b836ea 1089 100.00% 83.33% 50.00%
arrow_array::​array::​union_array::​UnionArray::​child::​hce65e76392a03143 1178 100.00% 80.00% 50.00%
arrow_array::​array::​union_array::​UnionArray::​type_id::​h5a8527b938ac329b 2150 100.00% 71.43% 50.00%
arrow_array::​array::​union_array::​UnionArray::​type_ids::​h52700b41791f2de1 6 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​offsets::​hf0a8bbf83ad4cce5 6 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​value_offset::​heb6c9f52efa13328 2128 100.00% 72.73% 66.67%
arrow_array::​array::​union_array::​UnionArray::​value::​h2c2c7f3de50d846d 1091 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​type_names::​hefa49e1b2cfc6ab0 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​type_names::​{{closure}}::​h170231b91de88fdf 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​is_dense::​h0b6cb2adcb5822dd 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​slice::​h09925b857248f268 4 100.00% 42.86% 41.67%
arrow_array::​array::​union_array::​UnionArray::​slice::​{{closure}}::​h433b86864ac210d8 4 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​slice::​{{closure}}::​{{closure}}::​h52f1ec40875d7fae 4 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​into_parts::​h6a925564ccb23a03 3 100.00% 29.03% 23.08%
arrow_array::​array::​union_array::​UnionArray::​into_parts::​{{closure}}::​hd39d09a790ddd844 7 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_without_nulls::​h2dc7c1c3af616694 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_without_nulls::​{{closure}}::​h599038a0b4d4fad4 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_without_nulls::​{{closure}}::​hbbd15f18491afe92 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_without_nulls::​{{closure}}::​{{closure}}::​ha4af34327e5b8941 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_without_nulls::​{{closure}}::​h17d1f9e0d42d2182 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_without_nulls::​{{closure}}::​{{closure}}::​h53fa1bcf4dfb9130 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​h240e0768fa69649e 2 100.00% 52.63% 38.64%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​h2c47ff6fa002ddc7 6 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​ha1fe04a0f1e6a4c9 4 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​hd4f16fbc2394c999 4 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​h4523a8952728fe28 2 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​{{closure}}::​hf56a2b75cc63f994 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​h026945f9d8915f0f 2 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_skip_fully_null::​{{closure}}::​{{closure}}::​h075037d056dc5eda 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_all_with_nulls_skip_one::​h5bd9c28fdd6db581 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_all_with_nulls_skip_one::​{{closure}}::​h14553a30c58ddbdb 0 —% 0.00% 0.00%
arrow_array::​ array::​union_array::​UnionArray::​ mask_sparse_all_with_nulls_skip_one::​{{closure}}::​{{closure}}::​ hc176793a7e579bc9 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_all_with_nulls_skip_one::​{{closure}}::​hfa839a5643235971 1 100.00% 100.00% —%
arrow_array::​ array::​union_array::​UnionArray::​ mask_sparse_all_with_nulls_skip_one::​{{closure}}::​{{closure}}::​ hc12ce01957802229 2 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​h0d5c2bbf7f4616e6 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​h20ceed6ce1c52edd 1 100.00% 54.72% 40.00%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​hbc652904d044d13b 2 100.00% 54.72% 40.00%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​h3290d91e64d5b2b3 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​h672e28a67bd6734c 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​hc26378c425546ed7 2 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​h1e0d805297bcffc6 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​h3f95682d467f0106 2 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​hf6c6ad2ca6a276f5 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​h62014ff252d86855 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​hac673c20414f88e8 0 —% 0.00% —%
arrow_array::​array::​union_array::​UnionArray::​mask_sparse_helper::​{{closure}}::​hf9fbca0b28a7b7ec 2 100.00% 100.00% —%
arrow_array::​array::​union_array::​UnionArray::​gather_nulls::​h08ff57ffe36b5fdf 6 100.00% 63.27% 56.82%
arrow_array::​array::​union_array::​UnionArray::​gather_nulls::​{{closure}}::​h8ee7a8c02f594637 6 100.00% 80.00% 50.00%
arrow_array::​array::​union_array::​UnionArray::​gather_nulls::​{{closure}}::​h236d0d59f23358fb 322 100.00% 80.00% 50.00%
<arrow_array::​ array::​union_array::​UnionArray as core::​convert::​From<arrow_data::​data::​ArrayData>>::​from::​ h68c09739a61cd0e5 38 100.00% 51.69% 44.79%
<arrow_array::​ array::​union_array::​UnionArray as core::​convert::​From<arrow_data::​data::​ArrayData>>::​from::​ {{closure}}::​hdb12f952444f9962 132 100.00% 100.00% —%
arrow_array::​ array::​union_array::​<impl core::​convert::​From<arrow_array::​array::​union_array::​ UnionArray> for arrow_data::​data::​ArrayData>::​from::​h1c3fda04601bb870 2 100.00% 38.46% 33.87%
arrow_array::​ array::​union_array::​<impl core::​convert::​From<arrow_array::​array::​union_array::​ UnionArray> for arrow_data::​data::​ArrayData>::​from::​{{closure}}::​ hc1628785e2140bd4 4 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​as_any::​he566b253791efa08 6 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​to_data::​hd3371bd8a589834f 2 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​into_data::​h30e85eb2dc35b2ea 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​data_type::​h286067170107f9dc 20 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​slice::​h7a5d39ec2dc94cd9 2 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​len::​hbe31af8392654e2e 2162 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​is_empty::​hb7d0238f8a7cc4f3 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​offset::​hdd2e777288e6f319 27 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​nulls::​hfcedf77546a6fd92 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​h692466b66b6bff4b 14 100.00% 76.06% 49.47%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ h58c73ff8daf9748f 81 100.00% 85.71% 100.00%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ hc36cc3ee6503f344 55 100.00% 100.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ hfbf33dcb828132b2 55 100.00% 100.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ h5da866bd323bde98 3 100.00% 100.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ h10c9fcaa32e0548d 1 100.00% 100.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ hfe79b83c78ced105 32 100.00% 100.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​logical_nulls::​{{closure}}::​ h31a920fafe7ba83a 27 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​is_null::​hc29f5bb58ac20424 1058 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​is_valid::​h447f9cb4920b7e61 10 100.00% 100.00% —%
<arrow_array::​array::​union_array::​UnionArray as arrow_array::​array::​Array>::​null_count::​hae455f72a7279a3e 4 100.00% 100.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_buffer_memory_size::​ h2809390a4eed6266 0 —% 0.00% 0.00%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_buffer_memory_size::​ {{closure}}::​heebfb7be8c2594df 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_buffer_memory_size::​ {{closure}}::​{{closure}}::​h01196f357d1d6a03 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_array_memory_size::​ h3f4f457370b7ca02 0 —% 0.00% 0.00%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_array_memory_size::​{{closure}}::​ h02538c6ae3316045 0 —% 0.00% —%
<arrow_array::​ array::​union_array::​UnionArray as arrow_array::​array::​Array>::​get_array_memory_size::​{{closure}}::​ {{closure}}::​he444357c149e26a1 0 —% 0.00% —%
<arrow_array::​array::​union_array::​UnionArray as core::​fmt::​Debug>::​fmt::​h1faf5bc397169f19 0 —% 0.00% 0.00%
arrow_array::​array::​union_array::​selection_mask::​hb95ac02ac948714f 6 100.00% 100.00% —%
arrow_array::​array::​union_array::​selection_mask::​{{closure}}::​h5b56a701298b0690 170 100.00% 100.00% —%
arrow_array::​array::​union_array::​without_nulls_selected::​hb6fa385ba31b5a37 4 100.00% 100.00% —%
arrow_array::​array::​union_array::​without_nulls_selected::​{{closure}}::​hd04fc72b28d914c8 4 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_union_validity::​hf0ce18e5e3fc8a0f 2 100.00% 66.67% 62.50%
arrow_array::​array::​union_array::​tests::​union_fields::​h8947e313d26ed4ed 7 100.00% 50.00% 40.00%
<arrow_array::​array::​union_array::​UnionArray as core::​clone::​Clone>::​clone::​h0d0ece15a1e2ebd7 2 100.00% 37.50% 37.50%
<arrow_array::​array::​union_array::​Mask as core::​clone::​Clone>::​clone::​hb5ec1919762727d3 0 —% 0.00% —%
arrow_array::​array::​union_array::​tests::​test_dense_i32::​{{closure}}::​h6e1a7add9473da79 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_dense_i32::​h04c4263448742b2e 1 100.00% 67.18% 51.20%
arrow_array::​array::​union_array::​tests::​test_dense_i32_large::​{{closure}}::​h47c679f96df8c4a4 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_dense_i32_large::​hb4cd98b6aa4eb6a8 1 100.00% 61.46% 51.85%
arrow_array::​array::​union_array::​tests::​test_dense_i32_large::​{{closure}}::​h435e39e1e434c49c 1024 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_dense_mixed::​{{closure}}::​h4d7a70a36653ff0c 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_dense_mixed::​hdde118ac57433b3e 1 100.00% 61.17% 51.61%
arrow_array::​array::​union_array::​tests::​test_dense_mixed_with_nulls::​{{closure}}::​hd9a8af4b9ce059c9 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_dense_mixed_with_nulls::​h231eed3b22b02cf0 1 100.00% 59.26% 51.59%
arrow_array::​array::​union_array::​tests::​test_dense_mixed_with_nulls_and_offset::​{{closure}}::​h4d62012886afd3c6 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_dense_mixed_with_nulls_and_offset::​h7668680a257fb73e 1 100.00% 59.30% 51.02%
arrow_array::​array::​union_array::​tests::​test_dense_mixed_with_str::​{{closure}}::​hcbe4a7a3364a2892 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_dense_mixed_with_str::​hffe542e8f127004a 1 100.00% 53.43% 47.32%
arrow_array::​array::​union_array::​tests::​test_sparse_i32::​{{closure}}::​h3b91b5df3fe9524c 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_sparse_i32::​h0a9eb8dce60981d0 1 100.00% 66.67% 50.71%
arrow_array::​array::​union_array::​tests::​test_sparse_mixed::​{{closure}}::​h0e0f5ef2aa772de4 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_sparse_mixed::​h1282cbf8931bc920 1 100.00% 62.99% 51.92%
arrow_array::​array::​union_array::​tests::​test_sparse_mixed_with_nulls::​{{closure}}::​hd2055ac7a6875a49 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_sparse_mixed_with_nulls::​h38ac73c642bece84 1 100.00% 60.87% 51.85%
arrow_array::​array::​union_array::​tests::​test_sparse_mixed_with_nulls_and_offset::​{{closure}}::​h3fdebb76b1942224 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_sparse_mixed_with_nulls_and_offset::​h12df46ae6f5b0964 1 100.00% 56.98% 51.58%
arrow_array::​array::​union_array::​tests::​test_union_array_validity::​{{closure}}::​h14d8205f40eaa02f 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_union_array_validity::​h03a798f7198a9af4 1 100.00% 68.09% 45.31%
arrow_array::​array::​union_array::​tests::​test_type_check::​{{closure}}::​h4a0bff8058a62d5e 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_type_check::​he299ca6124eb574e 1 100.00% 52.00% 41.67%
arrow_array::​array::​union_array::​tests::​slice_union_array::​{{closure}}::​hcbbc28b52447d956 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​slice_union_array::​h3f355e39a5cb9d22 1 100.00% 61.11% 44.44%
arrow_array::​array::​union_array::​tests::​slice_union_array::​create_union::​h485cadcf4a435dbc 2 100.00% 75.00% 42.86%
arrow_array::​array::​union_array::​tests::​slice_union_array::​create_batch::​h78e0550337ca3e24 2 100.00% 50.00% 36.84%
arrow_array::​array::​union_array::​tests::​slice_union_array::​test_slice_union::​h0aa645d23a7a799c 2 100.00% 51.43% 48.53%
arrow_array::​array::​union_array::​tests::​test_custom_type_ids::​{{closure}}::​he7b5cfbc29e5fcaa 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_custom_type_ids::​hebdfd7288b98faff 1 100.00% 47.98% 45.31%
arrow_array::​array::​union_array::​tests::​into_parts::​{{closure}}::​h6c6e715c9b087509 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​into_parts::​he9a57983207d9e27 1 100.00% 41.96% 40.14%
arrow_array::​array::​union_array::​tests::​into_parts::​{{closure}}::​hf811835e5f42b529 2 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​into_parts_custom_type_ids::​{{closure}}::​h4696b6b1fc4f1b75 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​into_parts_custom_type_ids::​hd228368b8f0047d4 1 100.00% 39.58% 39.13%
arrow_array::​array::​union_array::​tests::​test_invalid::​{{closure}}::​hac6f5b1c413343ae 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_invalid::​h0a210181d2c2a5e4 1 100.00% 37.92% 37.79%
arrow_array::​array::​union_array::​tests::​test_logical_nulls_fast_paths::​{{closure}}::​h387942921ffb9101 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_logical_nulls_fast_paths::​hbe23f6c75c3a0f9d 1 100.00% 40.62% 41.30%
arrow_array::​array::​union_array::​tests::​test_dense_union_logical_nulls_gather::​{{closure}}::​h9abcd06c692b05d9 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_dense_union_logical_nulls_gather::​h764e9ede257c5fa6 1 100.00% 38.75% 35.90%
arrow_array::​ array::​union_array::​tests::​ test_sparse_union_logical_nulls_mask_all_nulls_skip_one::​{{closure}}::​ h5ef2bd30d3e7c1c0 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_sparse_union_logical_nulls_mask_all_nulls_skip_one::​hd11412cafb392126 1 100.00% 39.63% 38.75%
arrow_array::​ array::​union_array::​tests::​ test_sparse_union_logical_mask_mixed_nulls_skip_fully_valid::​ {{closure}}::​h36c7907c1fdc7c71 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_sparse_union_logical_mask_mixed_nulls_skip_fully_valid::​hc66b26d900b0aad9 1 100.00% 40.00% 38.31%
arrow_array::​ array::​union_array::​tests::​ test_sparse_union_logical_mask_mixed_nulls_skip_fully_null::​ {{closure}}::​h9ee1218c7eca03e2 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_sparse_union_logical_mask_mixed_nulls_skip_fully_null::​hc34261edb427fdeb 1 100.00% 36.55% 36.76%
arrow_array::​array::​union_array::​tests::​test_sparse_union_logical_nulls_gather::​{{closure}}::​hbaf743de2d5d6406 1 100.00% 100.00% —%
arrow_array::​array::​union_array::​tests::​test_sparse_union_logical_nulls_gather::​h022806951a88d14a 1 100.00% 40.74% 38.46%
arrow_array::​array::​union_array::​tests::​test_sparse_union_logical_nulls_gather::​{{closure}}::​h33b0f45047412b55 50 100.00% 100.00% —%