Check if any null positions in the `null_buffer` correspond to non-empty ranges in this [`OffsetBuffer`]. In variable-length array types (e.g., `StringArray`, `ListArray`), null entries may or may not have empty offset ranges. This method detects cases where a null entry has a non-empty range (i.e., `offsets[i] != offsets[i+1]`), which means the underlying data buffer contains data behind nulls.
(&self, null_buffer: Option<&NullBuffer>)
| 275 | /// |
| 276 | /// Panics if the length of the `null_buffer` does not equal `self.len() - 1`. |
| 277 | pub fn has_non_empty_nulls(&self, null_buffer: Option<&NullBuffer>) -> bool { |
| 278 | let Some(null_buffer) = null_buffer else { |
| 279 | return false; |
| 280 | }; |
| 281 | |
| 282 | assert_eq!( |
| 283 | self.len() - 1, |
| 284 | null_buffer.len(), |
| 285 | "The length of the offsets should be 1 more than the length of the null buffer" |
| 286 | ); |
| 287 | |
| 288 | if null_buffer.null_count() == 0 { |
| 289 | return false; |
| 290 | } |
| 291 | |
| 292 | // Offsets always have at least 1 value |
| 293 | let initial_offset = self[0]; |
| 294 | let last_offset = self[self.len() - 1]; |
| 295 | |
| 296 | // If all the values are null (offsets have 1 more value than the length of the array) |
| 297 | if null_buffer.null_count() == self.len() - 1 { |
| 298 | return last_offset != initial_offset; |
| 299 | } |
| 300 | |
| 301 | let mut valid_slices_iter = null_buffer.valid_slices(); |
| 302 | |
| 303 | // This is safe as we validated that are at least 1 valid value in the array |
| 304 | let (start, end) = valid_slices_iter.next().unwrap(); |
| 305 | |
| 306 | // If the nulls before have length greater than 0 |
| 307 | if self[start] != initial_offset { |
| 308 | return true; |
| 309 | } |
| 310 | |
| 311 | // End is exclusive, so it already point to the last offset value |
| 312 | // This is valid as the length of the array is always 1 less than the length of the offsets |
| 313 | let mut end_offset_of_last_valid_value = self[end]; |
| 314 | |
| 315 | for (start, end) in valid_slices_iter { |
| 316 | // If there is a null value that point to a non-empty value than the start offset of the valid value |
| 317 | // will be different that the end offset of the last valid value |
| 318 | if self[start] != end_offset_of_last_valid_value { |
| 319 | return true; |
| 320 | } |
| 321 | |
| 322 | // End is exclusive, so it already point to the last offset value |
| 323 | // This is valid as the length of the array is always 1 less than the length of the offsets |
| 324 | end_offset_of_last_valid_value = self[end]; |
| 325 | } |
| 326 | |
| 327 | end_offset_of_last_valid_value != last_offset |
| 328 | } |
| 329 | } |
| 330 | |
| 331 | impl<T: ArrowNativeType> Deref for OffsetBuffer<T> { |
no test coverage detected