1use crate::array::print_long_array;
19use crate::iterator::FixedSizeBinaryIter;
20use crate::{Array, ArrayAccessor, ArrayRef, FixedSizeListArray, Scalar};
21use arrow_buffer::buffer::NullBuffer;
22use arrow_buffer::{ArrowNativeType, Buffer, MutableBuffer, bit_util};
23use arrow_data::{ArrayData, ArrayDataBuilder};
24use arrow_schema::{ArrowError, DataType};
25use std::any::Any;
26use std::sync::Arc;
27
28#[derive(Clone)]
90pub struct FixedSizeBinaryArray {
91 data_type: DataType,
93 value_data: Buffer,
95 nulls: Option<NullBuffer>,
97 len: usize,
99 value_size: usize,
108}
109
110impl FixedSizeBinaryArray {
111 pub fn new(value_length: i32, values: Buffer, nulls: Option<NullBuffer>) -> Self {
118 Self::try_new(value_length, values, nulls).unwrap()
119 }
120
121 pub fn new_scalar(value: impl AsRef<[u8]>) -> Scalar<Self> {
123 let v = value.as_ref();
124 let value_length =
125 i32::try_from(v.len()).expect("FixedSizeBinaryArray value length exceeds i32");
126 Scalar::new(Self::new(value_length, Buffer::from(v), None))
127 }
128
129 pub fn try_new(
141 value_length: i32,
142 values: Buffer,
143 nulls: Option<NullBuffer>,
144 ) -> Result<Self, ArrowError> {
145 let value_size = value_length.to_usize().ok_or_else(|| {
146 ArrowError::InvalidArgumentError(format!(
147 "Value length cannot be negative, got {value_length}"
148 ))
149 })?;
150
151 let len = match values.len().checked_div(value_size) {
152 Some(len) => len,
153 None => nulls.as_ref().map(|n| n.len()).unwrap_or(0),
154 };
155
156 Self::try_new_with_len(value_length, values, nulls, len)
157 }
158
159 pub fn try_new_with_len(
171 value_length: i32,
172 values: Buffer,
173 nulls: Option<NullBuffer>,
174 len: usize,
175 ) -> Result<Self, ArrowError> {
176 let data_type = DataType::FixedSizeBinary(value_length);
177 let value_size = value_length.to_usize().ok_or_else(|| {
178 ArrowError::InvalidArgumentError(format!(
179 "Value length cannot be negative, got {value_length}"
180 ))
181 })?;
182
183 if let Some(nulls) = &nulls {
184 if nulls.len() != len {
185 return Err(ArrowError::InvalidArgumentError(format!(
186 "Incorrect length of null buffer for FixedSizeBinaryArray, expected {} got {}",
187 len,
188 nulls.len(),
189 )));
190 }
191 }
192
193 if value_size != 0 && values.len() / value_size != len {
194 return Err(ArrowError::InvalidArgumentError(format!(
195 "Incorrect length of values buffer for FixedSizeBinaryArray, expected {} got {}",
196 len,
197 values.len() / value_size,
198 )));
199 }
200
201 if value_size == 0 && !values.is_empty() {
202 return Err(ArrowError::InvalidArgumentError(
203 "Buffer cannot have non-zero length if the value length is zero".to_owned(),
204 ));
205 }
206
207 Ok(Self {
208 data_type,
209 value_data: values,
210 value_size,
211 nulls,
212 len,
213 })
214 }
215
216 pub fn new_null(value_length: i32, len: usize) -> Self {
226 const BITS_IN_A_BYTE: usize = 8;
227 let value_size = value_length.to_usize().unwrap();
228 let capacity_in_bytes = value_size.checked_mul(len).unwrap();
229 let capacity_in_bits = capacity_in_bytes.checked_mul(BITS_IN_A_BYTE).unwrap();
230 Self {
231 data_type: DataType::FixedSizeBinary(value_length),
232 value_data: MutableBuffer::new_null(capacity_in_bits).into(),
233 nulls: Some(NullBuffer::new_null(len)),
234 value_size,
235 len,
236 }
237 }
238
239 pub fn into_parts(self) -> (i32, Buffer, Option<NullBuffer>) {
241 let value_length = self.value_length();
242 (value_length, self.value_data, self.nulls)
243 }
244
245 pub fn value(&self, i: usize) -> &[u8] {
253 let len = self.len();
254 assert!(
255 i < len,
256 "Trying to access an element at index {i} from a FixedSizeBinaryArray of length {len}",
257 );
258 let position = i * self.value_size;
259 unsafe {
260 std::slice::from_raw_parts(self.value_data.as_ptr().add(position), self.value_size)
261 }
262 }
263
264 pub unsafe fn value_unchecked(&self, i: usize) -> &[u8] {
274 let position = i * self.value_size;
275 unsafe {
276 std::slice::from_raw_parts(self.value_data.as_ptr().add(position), self.value_size)
277 }
278 }
279
280 #[deprecated(since = "59.0.0", note = "Use i * value_size() instead")]
288 #[inline]
289 pub fn value_offset(&self, i: usize) -> i32 {
290 self.value_length() * i as i32
291 }
292
293 #[inline]
301 pub fn value_length(&self) -> i32 {
302 self.value_size as i32
304 }
305
306 #[inline]
312 pub fn value_size(&self) -> usize {
313 self.value_size
314 }
315
316 #[inline]
321 pub fn values(&self) -> &Buffer {
322 &self.value_data
323 }
324
325 pub fn value_data(&self) -> &[u8] {
327 self.value_data.as_slice()
328 }
329
330 pub fn slice(&self, offset: usize, len: usize) -> Self {
332 assert!(
333 offset.saturating_add(len) <= self.len,
334 "the length + offset of the sliced FixedSizeBinaryArray cannot exceed the existing length"
335 );
336 let offset_bytes = offset
337 .checked_mul(self.value_size)
338 .expect("offset overflow");
339 let len_bytes = len.checked_mul(self.value_size).expect("offset overflow");
340
341 Self {
342 data_type: self.data_type.clone(),
343 nulls: self.nulls.as_ref().map(|n| n.slice(offset, len)),
344 value_size: self.value_size,
345 value_data: self.value_data.slice_with_length(offset_bytes, len_bytes),
346 len,
347 }
348 }
349
350 #[deprecated(
373 since = "28.0.0",
374 note = "This function will fail if the iterator produces only None values; prefer `try_from_sparse_iter_with_size`"
375 )]
376 pub fn try_from_sparse_iter<T, U>(mut iter: T) -> Result<Self, ArrowError>
377 where
378 T: Iterator<Item = Option<U>>,
379 U: AsRef<[u8]>,
380 {
381 let mut len = 0;
382 let mut value_size = None;
383 let mut byte = 0;
384
385 let iter_size_hint = iter.size_hint().0;
386 let mut null_buf = MutableBuffer::new(bit_util::ceil(iter_size_hint, 8));
387 let mut buffer = MutableBuffer::new(0);
388
389 let mut prepend = 0;
390 iter.try_for_each(|item| -> Result<(), ArrowError> {
391 if byte == 0 {
393 null_buf.push(0u8);
394 byte = 8;
395 }
396 byte -= 1;
397
398 if let Some(slice) = item {
399 let slice = slice.as_ref();
400 if let Some(size) = value_size {
401 if size != slice.len() {
402 return Err(ArrowError::InvalidArgumentError(format!(
403 "Nested array size mismatch: one is {}, and the other is {}",
404 size,
405 slice.len()
406 )));
407 }
408 } else {
409 let len = slice.len();
410 value_size = Some(len);
411 if let Some(capacity) = iter_size_hint.checked_mul(len) {
415 buffer.reserve(capacity);
416 }
417 let prepend_zeros = slice.len().checked_mul(prepend).ok_or_else(|| {
418 ArrowError::InvalidArgumentError(format!(
419 "FixedSizeBinaryArray error: value size {} * prepend {prepend} exceeds usize",
420 slice.len()
421 ))
422 })?;
423 buffer.extend_zeros(prepend_zeros);
424 }
425 bit_util::set_bit(null_buf.as_slice_mut(), len);
426 buffer.extend_from_slice(slice);
427 } else if let Some(size) = value_size {
428 buffer.extend_zeros(size);
429 } else {
430 prepend += 1;
431 }
432
433 len += 1;
434
435 Ok(())
436 })?;
437
438 if len == 0 {
439 return Err(ArrowError::InvalidArgumentError(
440 "Input iterable argument has no data".to_owned(),
441 ));
442 }
443
444 let nulls = NullBuffer::from_unsliced_buffer(null_buf, len);
445
446 let value_size = value_size.unwrap_or(0);
447 let value_length = value_size.try_into().map_err(|_| {
448 ArrowError::InvalidArgumentError(format!(
449 "FixedSizeBinaryArray value length exceeds i32, got {value_size}"
450 ))
451 })?;
452 Ok(Self {
453 data_type: DataType::FixedSizeBinary(value_length),
454 value_data: buffer.into(),
455 nulls,
456 value_size,
457 len,
458 })
459 }
460
461 pub fn try_from_sparse_iter_with_size<T, U>(
486 mut iter: T,
487 value_length: i32,
488 ) -> Result<Self, ArrowError>
489 where
490 T: Iterator<Item = Option<U>>,
491 U: AsRef<[u8]>,
492 {
493 let value_size = value_length.to_usize().ok_or_else(|| {
494 ArrowError::InvalidArgumentError(format!(
495 "Value length cannot be negative, got {value_length}"
496 ))
497 })?;
498 let mut len = 0;
499 let mut byte = 0;
500
501 let iter_size_hint = iter.size_hint().0;
502 let mut null_buf = MutableBuffer::new(bit_util::ceil(iter_size_hint, 8));
503 let capacity = iter_size_hint.checked_mul(value_size).ok_or_else(|| {
504 ArrowError::InvalidArgumentError(format!(
505 "FixedSizeBinaryArray error: value size {value_size} * len hint {iter_size_hint} exceeds usize"
506 ))
507 })?;
508 let mut buffer = MutableBuffer::new(capacity);
509
510 iter.try_for_each(|item| -> Result<(), ArrowError> {
511 if byte == 0 {
513 null_buf.push(0u8);
514 byte = 8;
515 }
516 byte -= 1;
517
518 if let Some(slice) = item {
519 let slice = slice.as_ref();
520 if value_size != slice.len() {
521 return Err(ArrowError::InvalidArgumentError(format!(
522 "Nested array size mismatch: one is {}, and the other is {}",
523 value_length,
524 slice.len()
525 )));
526 }
527
528 bit_util::set_bit(null_buf.as_slice_mut(), len);
529 buffer.extend_from_slice(slice);
530 } else {
531 buffer.extend_zeros(value_size);
532 }
533
534 len += 1;
535
536 Ok(())
537 })?;
538
539 let nulls = NullBuffer::from_unsliced_buffer(null_buf, len);
540
541 Ok(Self {
542 data_type: DataType::FixedSizeBinary(value_length),
543 value_data: buffer.into(),
544 nulls,
545 len,
546 value_size,
547 })
548 }
549
550 pub fn try_from_iter<T, U>(mut iter: T) -> Result<Self, ArrowError>
568 where
569 T: Iterator<Item = U>,
570 U: AsRef<[u8]>,
571 {
572 let mut len = 0;
573 let mut value_size = None;
574 let iter_size_hint = iter.size_hint().0;
575 let mut buffer = MutableBuffer::new(0);
576
577 iter.try_for_each(|item| -> Result<(), ArrowError> {
578 let slice = item.as_ref();
579 if let Some(value_size) = value_size {
580 if value_size != slice.len() {
581 return Err(ArrowError::InvalidArgumentError(format!(
582 "Nested array size mismatch: one is {value_size}, and the other is {}",
583 slice.len()
584 )));
585 }
586 } else {
587 let len = slice.len();
588 value_size = Some(len);
589 if let Some(capacity) = iter_size_hint.checked_mul(len) {
590 buffer.reserve(capacity);
591 }
592 }
593
594 buffer.extend_from_slice(slice);
595
596 len += 1;
597
598 Ok(())
599 })?;
600
601 if len == 0 {
602 return Err(ArrowError::InvalidArgumentError(
603 "Input iterable argument has no data".to_owned(),
604 ));
605 }
606
607 let value_size = value_size.unwrap_or(0);
608 let value_length = value_size.try_into().map_err(|_| {
609 ArrowError::InvalidArgumentError(format!(
610 "FixedSizeBinaryArray value length exceeds i32, got {value_size}"
611 ))
612 })?;
613 Ok(Self {
614 data_type: DataType::FixedSizeBinary(value_length),
615 value_data: buffer.into(),
616 nulls: None,
617 value_size,
618 len,
619 })
620 }
621
622 pub fn iter(&self) -> FixedSizeBinaryIter<'_> {
624 FixedSizeBinaryIter::new(self)
625 }
626}
627
628impl From<ArrayData> for FixedSizeBinaryArray {
629 fn from(data: ArrayData) -> Self {
630 let (data_type, len, nulls, offset, buffers, _child_data) = data.into_parts();
631
632 assert_eq!(
633 buffers.len(),
634 1,
635 "FixedSizeBinaryArray data should contain 1 buffer only (values)"
636 );
637 let value_length = match data_type {
638 DataType::FixedSizeBinary(len) => len,
639 _ => panic!("Expected data type to be FixedSizeBinary"),
640 };
641
642 let value_size = value_length
643 .to_usize()
644 .expect("FixedSizeBinaryArray value length must be non-negative");
645 let value_data = buffers[0].slice_with_length(
646 offset.checked_mul(value_size).expect("offset overflow"),
647 len.checked_mul(value_size).expect("length overflow"),
648 );
649
650 Self {
651 data_type,
652 nulls,
653 len,
654 value_data,
655 value_size,
656 }
657 }
658}
659
660impl From<FixedSizeBinaryArray> for ArrayData {
661 fn from(array: FixedSizeBinaryArray) -> Self {
662 let builder = ArrayDataBuilder::new(array.data_type)
663 .len(array.len)
664 .buffers(vec![array.value_data])
665 .nulls(array.nulls);
666
667 unsafe { builder.build_unchecked() }
668 }
669}
670
671impl From<FixedSizeListArray> for FixedSizeBinaryArray {
673 fn from(v: FixedSizeListArray) -> Self {
674 let value_len = v.value_length();
675 let v = v.into_data();
676 assert_eq!(
677 v.child_data().len(),
678 1,
679 "FixedSizeBinaryArray can only be created from list array of u8 values \
680 (i.e. FixedSizeList<PrimitiveArray<u8>>)."
681 );
682 let child_data = &v.child_data()[0];
683
684 assert_eq!(
685 child_data.child_data().len(),
686 0,
687 "FixedSizeBinaryArray can only be created from list array of u8 values \
688 (i.e. FixedSizeList<PrimitiveArray<u8>>)."
689 );
690 assert_eq!(
691 child_data.data_type(),
692 &DataType::UInt8,
693 "FixedSizeBinaryArray can only be created from FixedSizeList<u8> arrays, mismatched data types."
694 );
695 assert_eq!(
696 child_data.null_count(),
697 0,
698 "The child array cannot contain null values."
699 );
700
701 let builder = ArrayData::builder(DataType::FixedSizeBinary(value_len))
702 .len(v.len())
703 .offset(v.offset())
704 .add_buffer(child_data.buffers()[0].slice(child_data.offset()))
705 .nulls(v.nulls().cloned());
706
707 let data = unsafe { builder.build_unchecked() };
708 Self::from(data)
709 }
710}
711
712impl TryFrom<Vec<Option<&[u8]>>> for FixedSizeBinaryArray {
713 type Error = ArrowError;
714
715 fn try_from(v: Vec<Option<&[u8]>>) -> Result<Self, Self::Error> {
716 #[allow(deprecated)]
717 Self::try_from_sparse_iter(v.into_iter())
718 }
719}
720
721impl TryFrom<Vec<&[u8]>> for FixedSizeBinaryArray {
722 type Error = ArrowError;
723
724 fn try_from(v: Vec<&[u8]>) -> Result<Self, Self::Error> {
725 Self::try_from_iter(v.into_iter())
726 }
727}
728
729impl<const N: usize> TryFrom<Vec<Option<&[u8; N]>>> for FixedSizeBinaryArray {
730 type Error = ArrowError;
731
732 fn try_from(v: Vec<Option<&[u8; N]>>) -> Result<Self, Self::Error> {
733 N.try_into()
734 .map_err(|_| {
735 ArrowError::InvalidArgumentError(format!(
736 "FixedSizeBinaryArray value length exceeds i32, got {N}"
737 ))
738 })
739 .and_then(|x| Self::try_from_sparse_iter_with_size(v.into_iter(), x))
740 }
741}
742
743impl<const N: usize> TryFrom<Vec<&[u8; N]>> for FixedSizeBinaryArray {
744 type Error = ArrowError;
745
746 fn try_from(v: Vec<&[u8; N]>) -> Result<Self, Self::Error> {
747 Self::try_from_iter(v.into_iter())
748 }
749}
750
751impl std::fmt::Debug for FixedSizeBinaryArray {
752 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
753 write!(f, "FixedSizeBinaryArray<{}>\n[\n", self.value_length())?;
754 print_long_array(self, f, |array, index, f| {
755 std::fmt::Debug::fmt(&array.value(index), f)
756 })?;
757 write!(f, "]")
758 }
759}
760
761unsafe impl Array for FixedSizeBinaryArray {
763 fn as_any(&self) -> &dyn Any {
764 self
765 }
766
767 fn to_data(&self) -> ArrayData {
768 self.clone().into()
769 }
770
771 fn into_data(self) -> ArrayData {
772 self.into()
773 }
774
775 fn data_type(&self) -> &DataType {
776 &self.data_type
777 }
778
779 fn slice(&self, offset: usize, length: usize) -> ArrayRef {
780 Arc::new(self.slice(offset, length))
781 }
782
783 fn len(&self) -> usize {
784 self.len
785 }
786
787 fn is_empty(&self) -> bool {
788 self.len == 0
789 }
790
791 fn shrink_to_fit(&mut self) {
792 self.value_data.shrink_to_fit();
793 if let Some(nulls) = &mut self.nulls {
794 nulls.shrink_to_fit();
795 }
796 }
797
798 fn offset(&self) -> usize {
799 0
802 }
803
804 fn nulls(&self) -> Option<&NullBuffer> {
805 self.nulls.as_ref()
806 }
807
808 fn logical_null_count(&self) -> usize {
809 self.null_count()
811 }
812
813 fn get_buffer_memory_size(&self) -> usize {
814 let mut sum = self.value_data.capacity();
815 if let Some(n) = &self.nulls {
816 sum += n.buffer().capacity();
817 }
818 sum
819 }
820
821 fn get_array_memory_size(&self) -> usize {
822 std::mem::size_of::<Self>() + self.get_buffer_memory_size()
823 }
824
825 #[cfg(feature = "pool")]
826 fn claim(&self, pool: &dyn arrow_buffer::MemoryPool) {
827 self.value_data.claim(pool);
828 if let Some(nulls) = &self.nulls {
829 nulls.claim(pool);
830 }
831 }
832}
833
834impl<'a> ArrayAccessor for &'a FixedSizeBinaryArray {
835 type Item = &'a [u8];
836
837 fn value(&self, index: usize) -> Self::Item {
838 FixedSizeBinaryArray::value(self, index)
839 }
840
841 unsafe fn value_unchecked(&self, index: usize) -> Self::Item {
842 unsafe { FixedSizeBinaryArray::value_unchecked(self, index) }
843 }
844}
845
846impl<'a> IntoIterator for &'a FixedSizeBinaryArray {
847 type Item = Option<&'a [u8]>;
848 type IntoIter = FixedSizeBinaryIter<'a>;
849
850 fn into_iter(self) -> Self::IntoIter {
851 FixedSizeBinaryIter::<'a>::new(self)
852 }
853}
854
855#[cfg(test)]
856mod tests {
857 use super::*;
858 use crate::RecordBatch;
859 use arrow_schema::{Field, Schema};
860
861 #[test]
862 fn test_fixed_size_binary_array() {
863 let values = b"hellotherearrow";
864
865 let array_data = ArrayData::builder(DataType::FixedSizeBinary(5))
866 .len(3)
867 .add_buffer(Buffer::from(values))
868 .build()
869 .unwrap();
870 let fixed_size_binary_array = FixedSizeBinaryArray::from(array_data);
871 assert_eq!(3, fixed_size_binary_array.len());
872 assert_eq!(0, fixed_size_binary_array.null_count());
873 assert_eq!(
874 [b'h', b'e', b'l', b'l', b'o'],
875 fixed_size_binary_array.value(0)
876 );
877 assert_eq!(
878 [b't', b'h', b'e', b'r', b'e'],
879 fixed_size_binary_array.value(1)
880 );
881 assert_eq!(
882 [b'a', b'r', b'r', b'o', b'w'],
883 fixed_size_binary_array.value(2)
884 );
885 assert_eq!(5, fixed_size_binary_array.value_length());
886 for i in 0..3 {
887 assert!(fixed_size_binary_array.is_valid(i));
888 assert!(!fixed_size_binary_array.is_null(i));
889 }
890
891 let array_data = ArrayData::builder(DataType::FixedSizeBinary(5))
893 .len(2)
894 .offset(1)
895 .add_buffer(Buffer::from(values))
896 .build()
897 .unwrap();
898 let fixed_size_binary_array = FixedSizeBinaryArray::from(array_data);
899 assert_eq!(
900 [b't', b'h', b'e', b'r', b'e'],
901 fixed_size_binary_array.value(0)
902 );
903 assert_eq!(
904 [b'a', b'r', b'r', b'o', b'w'],
905 fixed_size_binary_array.value(1)
906 );
907 assert_eq!(2, fixed_size_binary_array.len());
908 assert_eq!(5, fixed_size_binary_array.value_length());
909 }
910
911 #[test]
912 fn test_fixed_size_binary_array_from_fixed_size_list_array() {
913 let values = [0_u8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
914 let values_data = ArrayData::builder(DataType::UInt8)
915 .len(12)
916 .offset(2)
917 .add_buffer(Buffer::from_slice_ref(values))
918 .build()
919 .unwrap();
920 let array_data = unsafe {
922 ArrayData::builder(DataType::FixedSizeList(
923 Arc::new(Field::new_list_field(DataType::UInt8, false)),
924 4,
925 ))
926 .len(2)
927 .offset(1)
928 .add_child_data(values_data)
929 .null_bit_buffer(Some(Buffer::from_slice_ref([0b101])))
930 .build_unchecked()
931 };
932 let list_array = FixedSizeListArray::from(array_data);
933 let binary_array = FixedSizeBinaryArray::from(list_array);
934
935 assert_eq!(2, binary_array.len());
936 assert_eq!(1, binary_array.null_count());
937 assert!(binary_array.is_null(0));
938 assert!(binary_array.is_valid(1));
939 assert_eq!(&[10, 11, 12, 13], binary_array.value(1));
940 }
941
942 #[test]
943 #[should_panic(
944 expected = "FixedSizeBinaryArray can only be created from FixedSizeList<u8> arrays"
945 )]
946 #[cfg(not(feature = "force_validate"))]
949 fn test_fixed_size_binary_array_from_incorrect_fixed_size_list_array() {
950 let values: [u32; 12] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
951 let values_data = ArrayData::builder(DataType::UInt32)
952 .len(12)
953 .add_buffer(Buffer::from_slice_ref(values))
954 .build()
955 .unwrap();
956
957 let array_data = unsafe {
958 ArrayData::builder(DataType::FixedSizeList(
959 Arc::new(Field::new_list_field(DataType::Binary, false)),
960 4,
961 ))
962 .len(3)
963 .add_child_data(values_data)
964 .build_unchecked()
965 };
966 let list_array = FixedSizeListArray::from(array_data);
967 drop(FixedSizeBinaryArray::from(list_array));
968 }
969
970 #[test]
971 #[should_panic(expected = "The child array cannot contain null values.")]
972 fn test_fixed_size_binary_array_from_fixed_size_list_array_with_child_nulls_failed() {
973 let values = [0_u8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
974 let values_data = ArrayData::builder(DataType::UInt8)
975 .len(12)
976 .add_buffer(Buffer::from_slice_ref(values))
977 .null_bit_buffer(Some(Buffer::from_slice_ref([0b101010101010])))
978 .build()
979 .unwrap();
980
981 let array_data = unsafe {
982 ArrayData::builder(DataType::FixedSizeList(
983 Arc::new(Field::new_list_field(DataType::UInt8, false)),
984 4,
985 ))
986 .len(3)
987 .add_child_data(values_data)
988 .build_unchecked()
989 };
990 let list_array = FixedSizeListArray::from(array_data);
991 drop(FixedSizeBinaryArray::from(list_array));
992 }
993
994 #[test]
995 fn test_fixed_size_binary_array_fmt_debug() {
996 let values = b"hellotherearrow";
997
998 let array_data = ArrayData::builder(DataType::FixedSizeBinary(5))
999 .len(3)
1000 .add_buffer(Buffer::from(values))
1001 .build()
1002 .unwrap();
1003 let arr = FixedSizeBinaryArray::from(array_data);
1004 assert_eq!(
1005 "FixedSizeBinaryArray<5>\n[\n [104, 101, 108, 108, 111],\n [116, 104, 101, 114, 101],\n [97, 114, 114, 111, 119],\n]",
1006 format!("{arr:?}")
1007 );
1008 }
1009
1010 #[test]
1011 fn test_fixed_size_binary_array_from_iter() {
1012 let input_arg = vec![vec![1, 2], vec![3, 4], vec![5, 6]];
1013 let arr = FixedSizeBinaryArray::try_from_iter(input_arg.into_iter()).unwrap();
1014
1015 assert_eq!(2, arr.value_length());
1016 assert_eq!(3, arr.len())
1017 }
1018
1019 #[test]
1020 fn test_all_none_fixed_size_binary_array_from_sparse_iter() {
1021 let none_option: Option<[u8; 32]> = None;
1022 let input_arg = vec![none_option, none_option, none_option];
1023 #[allow(deprecated)]
1024 let arr = FixedSizeBinaryArray::try_from_sparse_iter(input_arg.into_iter()).unwrap();
1025 assert_eq!(0, arr.value_length());
1026 assert_eq!(3, arr.len())
1027 }
1028
1029 #[test]
1030 fn test_fixed_size_binary_array_from_sparse_iter() {
1031 let input_arg = vec![
1032 None,
1033 Some(vec![7, 8]),
1034 Some(vec![9, 10]),
1035 None,
1036 Some(vec![13, 14]),
1037 ];
1038 #[allow(deprecated)]
1039 let arr = FixedSizeBinaryArray::try_from_sparse_iter(input_arg.iter().cloned()).unwrap();
1040 assert_eq!(2, arr.value_length());
1041 assert_eq!(5, arr.len());
1042
1043 let arr =
1044 FixedSizeBinaryArray::try_from_sparse_iter_with_size(input_arg.into_iter(), 2).unwrap();
1045 assert_eq!(2, arr.value_length());
1046 assert_eq!(5, arr.len());
1047 }
1048
1049 #[test]
1050 fn test_fixed_size_binary_array_from_sparse_iter_with_size_all_none() {
1051 let input_arg = vec![None, None, None, None, None] as Vec<Option<Vec<u8>>>;
1052
1053 let arr = FixedSizeBinaryArray::try_from_sparse_iter_with_size(input_arg.into_iter(), 16)
1054 .unwrap();
1055 assert_eq!(16, arr.value_length());
1056 assert_eq!(5, arr.len())
1057 }
1058
1059 #[test]
1060 fn test_fixed_size_binary_array_from_vec() {
1061 let values = vec!["one".as_bytes(), b"two", b"six", b"ten"];
1062 let array = FixedSizeBinaryArray::try_from(values).unwrap();
1063 assert_eq!(array.len(), 4);
1064 assert_eq!(array.null_count(), 0);
1065 assert_eq!(array.logical_null_count(), 0);
1066 assert_eq!(array.value(0), b"one");
1067 assert_eq!(array.value(1), b"two");
1068 assert_eq!(array.value(2), b"six");
1069 assert_eq!(array.value(3), b"ten");
1070 assert!(!array.is_null(0));
1071 assert!(!array.is_null(1));
1072 assert!(!array.is_null(2));
1073 assert!(!array.is_null(3));
1074 }
1075
1076 #[test]
1077 fn test_fixed_size_binary_array_from_vec_incorrect_length() {
1078 let values = vec!["one".as_bytes(), b"two", b"three", b"four"];
1079 assert!(FixedSizeBinaryArray::try_from(values).is_err());
1080 }
1081
1082 #[test]
1083 fn test_fixed_size_binary_array_from_opt_vec() {
1084 let values = vec![
1085 Some("one".as_bytes()),
1086 Some(b"two"),
1087 None,
1088 Some(b"six"),
1089 Some(b"ten"),
1090 ];
1091 let array = FixedSizeBinaryArray::try_from(values).unwrap();
1092 assert_eq!(array.len(), 5);
1093 assert_eq!(array.value(0), b"one");
1094 assert_eq!(array.value(1), b"two");
1095 assert_eq!(array.value(3), b"six");
1096 assert_eq!(array.value(4), b"ten");
1097 assert!(!array.is_null(0));
1098 assert!(!array.is_null(1));
1099 assert!(array.is_null(2));
1100 assert!(!array.is_null(3));
1101 assert!(!array.is_null(4));
1102 }
1103
1104 #[test]
1105 fn test_fixed_size_binary_array_from_opt_vec_incorrect_length() {
1106 let values = vec![
1107 Some("one".as_bytes()),
1108 Some(b"two"),
1109 None,
1110 Some(b"three"),
1111 Some(b"four"),
1112 ];
1113 assert!(FixedSizeBinaryArray::try_from(values).is_err());
1114 }
1115
1116 #[test]
1117 fn fixed_size_binary_array_all_null() {
1118 let data = vec![None] as Vec<Option<String>>;
1119 let array =
1120 FixedSizeBinaryArray::try_from_sparse_iter_with_size(data.into_iter(), 0).unwrap();
1121 array
1122 .into_data()
1123 .validate_full()
1124 .expect("All null array has valid array data");
1125 }
1126
1127 #[test]
1128 fn fixed_size_binary_array_all_null_in_batch_with_schema() {
1130 let schema = Schema::new(vec![Field::new("a", DataType::FixedSizeBinary(2), true)]);
1131
1132 let none_option: Option<[u8; 2]> = None;
1133 let item = FixedSizeBinaryArray::try_from_sparse_iter_with_size(
1134 vec![none_option, none_option, none_option].into_iter(),
1135 2,
1136 )
1137 .unwrap();
1138
1139 RecordBatch::try_new(Arc::new(schema), vec![Arc::new(item)]).unwrap();
1141 }
1142
1143 #[test]
1144 #[should_panic(
1145 expected = "Trying to access an element at index 4 from a FixedSizeBinaryArray of length 3"
1146 )]
1147 fn test_fixed_size_binary_array_get_value_index_out_of_bound() {
1148 let values = vec![Some("one".as_bytes()), Some(b"two"), None];
1149 let array = FixedSizeBinaryArray::try_from(values).unwrap();
1150
1151 array.value(4);
1152 }
1153
1154 #[test]
1155 fn test_constructors() {
1156 let buffer = Buffer::from_vec(vec![0_u8; 10]);
1157 let a = FixedSizeBinaryArray::new(2, buffer.clone(), None);
1158 assert_eq!(a.len(), 5);
1159
1160 let nulls = NullBuffer::new_null(5);
1161 FixedSizeBinaryArray::new(2, buffer.clone(), Some(nulls));
1162
1163 let null_array = FixedSizeBinaryArray::new_null(4, 3);
1164 assert_eq!(null_array.len(), 3);
1165 assert_eq!(null_array.values().len(), 12);
1166
1167 let a = FixedSizeBinaryArray::new(3, buffer.clone(), None);
1168 assert_eq!(a.len(), 3);
1169
1170 let nulls = NullBuffer::new_null(3);
1171 FixedSizeBinaryArray::new(3, buffer.clone(), Some(nulls));
1172
1173 let err = FixedSizeBinaryArray::try_new(-1, buffer.clone(), None).unwrap_err();
1174
1175 assert_eq!(
1176 err.to_string(),
1177 "Invalid argument error: Value length cannot be negative, got -1"
1178 );
1179
1180 let nulls = NullBuffer::new_null(3);
1181 let err = FixedSizeBinaryArray::try_new(2, buffer.clone(), Some(nulls)).unwrap_err();
1182 assert_eq!(
1183 err.to_string(),
1184 "Invalid argument error: Incorrect length of null buffer for FixedSizeBinaryArray, expected 5 got 3"
1185 );
1186
1187 let zero_sized = FixedSizeBinaryArray::new(0, Buffer::default(), None);
1188 assert_eq!(zero_sized.len(), 0);
1189 assert_eq!(zero_sized.null_count(), 0);
1190 assert_eq!(zero_sized.values().len(), 0);
1191
1192 let nulls = NullBuffer::new_null(3);
1193 let zero_sized_with_nulls = FixedSizeBinaryArray::new(0, Buffer::default(), Some(nulls));
1194 assert_eq!(zero_sized_with_nulls.len(), 3);
1195 assert_eq!(zero_sized_with_nulls.null_count(), 3);
1196 assert_eq!(zero_sized_with_nulls.values().len(), 0);
1197
1198 let zero_sized_with_non_empty_buffer_err =
1199 FixedSizeBinaryArray::try_new(0, buffer, None).unwrap_err();
1200 assert_eq!(
1201 zero_sized_with_non_empty_buffer_err.to_string(),
1202 "Invalid argument error: Buffer cannot have non-zero length if the value length is zero"
1203 );
1204 }
1205
1206 #[test]
1207 fn test_try_new_with_len() {
1208 let buffer = Buffer::from_vec(vec![0_u8; 10]);
1209
1210 let a = FixedSizeBinaryArray::try_new_with_len(2, buffer.clone(), None, 5).unwrap();
1211 assert_eq!(a.len(), 5);
1212
1213 let nulls = NullBuffer::new_null(5);
1214 let a = FixedSizeBinaryArray::try_new_with_len(2, buffer, Some(nulls), 5).unwrap();
1215 assert_eq!(a.len(), 5);
1216 assert_eq!(a.null_count(), 5);
1217
1218 let a = FixedSizeBinaryArray::try_new_with_len(2, Buffer::default(), None, 0).unwrap();
1219 assert_eq!(a.len(), 0);
1220 }
1221
1222 #[test]
1223 fn test_try_new_with_len_zero_width() {
1224 let a = FixedSizeBinaryArray::try_new_with_len(0, Buffer::default(), None, 5).unwrap();
1226 assert_eq!(a.len(), 5);
1227 assert_eq!(a.null_count(), 0);
1228 assert_eq!(a.values().len(), 0);
1229
1230 let nulls = NullBuffer::new_null(3);
1231 let a =
1232 FixedSizeBinaryArray::try_new_with_len(0, Buffer::default(), Some(nulls), 3).unwrap();
1233 assert_eq!(a.len(), 3);
1234 assert_eq!(a.null_count(), 3);
1235 }
1236
1237 #[test]
1238 fn test_try_new_with_len_negative_value_length() {
1239 let buffer = Buffer::from_vec(vec![0_u8; 10]);
1240 let err = FixedSizeBinaryArray::try_new_with_len(-1, buffer, None, 5).unwrap_err();
1241 assert_eq!(
1242 err.to_string(),
1243 "Invalid argument error: Value length cannot be negative, got -1"
1244 );
1245 }
1246
1247 #[test]
1248 fn test_try_new_with_len_incorrect_null_buffer_length() {
1249 let buffer = Buffer::from_vec(vec![0_u8; 10]);
1250 let nulls = NullBuffer::new_null(3);
1251 let err = FixedSizeBinaryArray::try_new_with_len(2, buffer, Some(nulls), 5).unwrap_err();
1252 assert_eq!(
1253 err.to_string(),
1254 "Invalid argument error: Incorrect length of null buffer for FixedSizeBinaryArray, expected 5 got 3"
1255 );
1256 }
1257
1258 #[test]
1259 fn test_try_new_with_len_incorrect_values_buffer_length() {
1260 let buffer = Buffer::from_vec(vec![0_u8; 10]);
1261 let err = FixedSizeBinaryArray::try_new_with_len(2, buffer, None, 3).unwrap_err();
1262 assert_eq!(
1263 err.to_string(),
1264 "Invalid argument error: Incorrect length of values buffer for FixedSizeBinaryArray, expected 3 got 5"
1265 );
1266 }
1267
1268 #[test]
1269 fn test_try_new_with_len_zero_width_non_empty_buffer() {
1270 let buffer = Buffer::from_vec(vec![0_u8; 10]);
1271 let err = FixedSizeBinaryArray::try_new_with_len(0, buffer, None, 5).unwrap_err();
1272 assert_eq!(
1273 err.to_string(),
1274 "Invalid argument error: Buffer cannot have non-zero length if the value length is zero"
1275 );
1276 }
1277}