Attempts to create a new `UnionArray`, validating the inputs provided. The order of child arrays child array order must match the fields order
(
fields: UnionFields,
type_ids: ScalarBuffer<i8>,
offsets: Option<ScalarBuffer<i32>>,
children: Vec<ArrayRef>,
)
| 175 | /// |
| 176 | /// The order of child arrays child array order must match the fields order |
| 177 | pub fn try_new( |
| 178 | fields: UnionFields, |
| 179 | type_ids: ScalarBuffer<i8>, |
| 180 | offsets: Option<ScalarBuffer<i32>>, |
| 181 | children: Vec<ArrayRef>, |
| 182 | ) -> Result<Self, ArrowError> { |
| 183 | // There must be a child array for every field. |
| 184 | if fields.len() != children.len() { |
| 185 | return Err(ArrowError::InvalidArgumentError( |
| 186 | "Union fields length must match child arrays length".to_string(), |
| 187 | )); |
| 188 | } |
| 189 | |
| 190 | if let Some(offsets) = &offsets { |
| 191 | // There must be an offset value for every type id value. |
| 192 | if offsets.len() != type_ids.len() { |
| 193 | return Err(ArrowError::InvalidArgumentError( |
| 194 | "Type Ids and Offsets lengths must match".to_string(), |
| 195 | )); |
| 196 | } |
| 197 | } else { |
| 198 | // Sparse union child arrays must be equal in length to the length of the union |
| 199 | for child in &children { |
| 200 | if child.len() != type_ids.len() { |
| 201 | return Err(ArrowError::InvalidArgumentError( |
| 202 | "Sparse union child arrays must be equal in length to the length of the union".to_string(), |
| 203 | )); |
| 204 | } |
| 205 | } |
| 206 | } |
| 207 | |
| 208 | // Create mapping from type id to array lengths. |
| 209 | let max_id = fields.iter().map(|(i, _)| i).max().unwrap_or_default() as usize; |
| 210 | let mut array_lens = vec![i32::MIN; max_id + 1]; |
| 211 | for (cd, (field_id, _)) in children.iter().zip(fields.iter()) { |
| 212 | array_lens[field_id as usize] = cd.len() as i32; |
| 213 | } |
| 214 | |
| 215 | // Type id values must match one of the fields. |
| 216 | for id in &type_ids { |
| 217 | match array_lens.get(*id as usize) { |
| 218 | Some(x) if *x != i32::MIN => {} |
| 219 | _ => { |
| 220 | return Err(ArrowError::InvalidArgumentError( |
| 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. |
| 228 | if let Some(offsets) = &offsets { |
| 229 | let mut iter = type_ids.iter().zip(offsets.iter()); |
| 230 | if iter.any(|(type_id, &offset)| offset < 0 || offset >= array_lens[*type_id as usize]) |
| 231 | { |
| 232 | return Err(ArrowError::InvalidArgumentError( |
| 233 | "Offsets must be non-negative and within the length of the Array".to_owned(), |
| 234 | )); |