"cheap" validation of an `ArrayData`. Ensures buffers are sufficiently sized to store `len` + `offset` total elements of `data_type` and performs other inexpensive consistency checks. This check is "cheap" in the sense that it does not validate the contents of the buffers (e.g. that all offsets for UTF8 arrays are within the bounds of the values buffer). See [ArrayData::validate_data] to validat
(&self)
| 842 | /// See [ArrayData::validate_data] to validate fully the offset content |
| 843 | /// and the validity of utf8 data |
| 844 | pub fn validate(&self) -> Result<(), ArrowError> { |
| 845 | // Need at least this much space in each buffer |
| 846 | let len_plus_offset = checked_len_plus_offset(&self.data_type, self.len, self.offset)?; |
| 847 | |
| 848 | // Check that the data layout conforms to the spec |
| 849 | let layout = layout(&self.data_type); |
| 850 | |
| 851 | if !layout.can_contain_null_mask && self.nulls.is_some() { |
| 852 | return Err(ArrowError::InvalidArgumentError(format!( |
| 853 | "Arrays of type {:?} cannot contain a null bitmask", |
| 854 | self.data_type, |
| 855 | ))); |
| 856 | } |
| 857 | |
| 858 | // Check data buffers length for view types and other types |
| 859 | if self.buffers.len() < layout.buffers.len() |
| 860 | || (!layout.variadic && self.buffers.len() != layout.buffers.len()) |
| 861 | { |
| 862 | return Err(ArrowError::InvalidArgumentError(format!( |
| 863 | "Expected {} buffers in array of type {:?}, got {}", |
| 864 | layout.buffers.len(), |
| 865 | self.data_type, |
| 866 | self.buffers.len(), |
| 867 | ))); |
| 868 | } |
| 869 | |
| 870 | for (i, (buffer, spec)) in self.buffers.iter().zip(layout.buffers.iter()).enumerate() { |
| 871 | match spec { |
| 872 | BufferSpec::FixedWidth { |
| 873 | byte_width, |
| 874 | alignment, |
| 875 | } => { |
| 876 | let min_buffer_size = len_plus_offset.saturating_mul(*byte_width); |
| 877 | |
| 878 | if buffer.len() < min_buffer_size { |
| 879 | return Err(ArrowError::InvalidArgumentError(format!( |
| 880 | "Need at least {} bytes in buffers[{}] in array of type {:?}, but got {}", |
| 881 | min_buffer_size, |
| 882 | i, |
| 883 | self.data_type, |
| 884 | buffer.len() |
| 885 | ))); |
| 886 | } |
| 887 | |
| 888 | let align_offset = buffer.as_ptr().align_offset(*alignment); |
| 889 | if align_offset != 0 { |
| 890 | return Err(ArrowError::InvalidArgumentError(format!( |
| 891 | "Misaligned buffers[{i}] in array of type {:?}, offset from expected alignment of {alignment} by {}", |
| 892 | self.data_type, |
| 893 | align_offset.min(alignment - align_offset) |
| 894 | ))); |
| 895 | } |
| 896 | } |
| 897 | BufferSpec::VariableWidth => { |
| 898 | // not cheap to validate (need to look at the |
| 899 | // data). Partially checked in validate_offsets |
| 900 | // called below. Can check with `validate_full` |
| 901 | } |