Converts this into an [`ArrayRef`] with the provided `data_type` and `null_buffer`
(
self,
null_buffer: Option<Buffer>,
data_type: &ArrowType,
)
| 124 | |
| 125 | /// Converts this into an [`ArrayRef`] with the provided `data_type` and `null_buffer` |
| 126 | pub fn into_array( |
| 127 | self, |
| 128 | null_buffer: Option<Buffer>, |
| 129 | data_type: &ArrowType, |
| 130 | ) -> Result<ArrayRef> { |
| 131 | assert!(matches!(data_type, ArrowType::Dictionary(_, _))); |
| 132 | |
| 133 | match self { |
| 134 | Self::Dict { keys, values } => { |
| 135 | // Validate keys unless dictionary is empty |
| 136 | if !values.is_empty() { |
| 137 | let min = K::from_usize(0).unwrap(); |
| 138 | let max = K::from_usize(values.len()).unwrap(); |
| 139 | |
| 140 | // using copied and fold gets auto-vectorized since rust 1.70 |
| 141 | // all/any would allow early exit on invalid values |
| 142 | // but in the happy case all values have to be checked anyway |
| 143 | if !keys |
| 144 | .as_slice() |
| 145 | .iter() |
| 146 | .copied() |
| 147 | .fold(true, |a, x| a && x >= min && x < max) |
| 148 | { |
| 149 | return Err(general_err!( |
| 150 | "dictionary key beyond bounds of dictionary: 0..{}", |
| 151 | values.len() |
| 152 | )); |
| 153 | } |
| 154 | } |
| 155 | |
| 156 | let ArrowType::Dictionary(_, value_type) = data_type else { |
| 157 | unreachable!() |
| 158 | }; |
| 159 | let values = if let ArrowType::FixedSizeBinary(size) = **value_type { |
| 160 | let binary = values.as_binary::<i32>(); |
| 161 | Arc::new(FixedSizeBinaryArray::new( |
| 162 | size, |
| 163 | binary.values().clone(), |
| 164 | binary.nulls().cloned(), |
| 165 | )) as _ |
| 166 | } else { |
| 167 | values |
| 168 | }; |
| 169 | |
| 170 | let builder = ArrayDataBuilder::new(data_type.clone()) |
| 171 | .len(keys.len()) |
| 172 | .add_buffer(Buffer::from_vec(keys)) |
| 173 | .add_child_data(values.into_data()) |
| 174 | .null_bit_buffer(null_buffer); |
| 175 | |
| 176 | let data = match cfg!(debug_assertions) { |
| 177 | true => builder.build().unwrap(), |
| 178 | false => unsafe { builder.build_unchecked() }, |
| 179 | }; |
| 180 | |
| 181 | Ok(make_array(data)) |
| 182 | } |
| 183 | Self::Values { values } => { |