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(
140 value_length: i32,
141 values: Buffer,
142 nulls: Option<NullBuffer>,
143 ) -> Result<Self, ArrowError> {
144 let data_type = DataType::FixedSizeBinary(value_length);
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) => {
153 if let Some(n) = nulls.as_ref() {
154 if n.len() != len {
155 return Err(ArrowError::InvalidArgumentError(format!(
156 "Incorrect length of null buffer for FixedSizeBinaryArray, expected {} got {}",
157 len,
158 n.len(),
159 )));
160 }
161 }
162
163 len
164 }
165 None => {
166 if !values.is_empty() {
167 return Err(ArrowError::InvalidArgumentError(
168 "Buffer cannot have non-zero length if the value length is zero".to_owned(),
169 ));
170 }
171
172 nulls.as_ref().map(|n| n.len()).unwrap_or(0)
174 }
175 };
176
177 Ok(Self {
178 data_type,
179 value_data: values,
180 value_size,
181 nulls,
182 len,
183 })
184 }
185
186 pub fn new_null(value_length: i32, len: usize) -> Self {
196 const BITS_IN_A_BYTE: usize = 8;
197 let value_size = value_length.to_usize().unwrap();
198 let capacity_in_bytes = value_size.checked_mul(len).unwrap();
199 let capacity_in_bits = capacity_in_bytes.checked_mul(BITS_IN_A_BYTE).unwrap();
200 Self {
201 data_type: DataType::FixedSizeBinary(value_length),
202 value_data: MutableBuffer::new_null(capacity_in_bits).into(),
203 nulls: Some(NullBuffer::new_null(len)),
204 value_size,
205 len,
206 }
207 }
208
209 pub fn into_parts(self) -> (i32, Buffer, Option<NullBuffer>) {
211 let value_length = self.value_length();
212 (value_length, self.value_data, self.nulls)
213 }
214
215 pub fn value(&self, i: usize) -> &[u8] {
223 let len = self.len();
224 assert!(
225 i < len,
226 "Trying to access an element at index {i} from a FixedSizeBinaryArray of length {len}",
227 );
228 let position = i * self.value_size;
229 unsafe {
230 std::slice::from_raw_parts(self.value_data.as_ptr().add(position), self.value_size)
231 }
232 }
233
234 pub unsafe fn value_unchecked(&self, i: usize) -> &[u8] {
244 let position = i * self.value_size;
245 unsafe {
246 std::slice::from_raw_parts(self.value_data.as_ptr().add(position), self.value_size)
247 }
248 }
249
250 #[deprecated(since = "59.0.0", note = "Use i * value_size() instead")]
258 #[inline]
259 pub fn value_offset(&self, i: usize) -> i32 {
260 self.value_length() * i as i32
261 }
262
263 #[inline]
271 pub fn value_length(&self) -> i32 {
272 self.value_size as i32
274 }
275
276 #[inline]
282 pub fn value_size(&self) -> usize {
283 self.value_size
284 }
285
286 #[inline]
291 pub fn values(&self) -> &Buffer {
292 &self.value_data
293 }
294
295 pub fn value_data(&self) -> &[u8] {
297 self.value_data.as_slice()
298 }
299
300 pub fn slice(&self, offset: usize, len: usize) -> Self {
302 assert!(
303 offset.saturating_add(len) <= self.len,
304 "the length + offset of the sliced FixedSizeBinaryArray cannot exceed the existing length"
305 );
306 let offset_bytes = offset
307 .checked_mul(self.value_size)
308 .expect("offset overflow");
309 let len_bytes = len.checked_mul(self.value_size).expect("offset overflow");
310
311 Self {
312 data_type: self.data_type.clone(),
313 nulls: self.nulls.as_ref().map(|n| n.slice(offset, len)),
314 value_size: self.value_size,
315 value_data: self.value_data.slice_with_length(offset_bytes, len_bytes),
316 len,
317 }
318 }
319
320 #[deprecated(
343 since = "28.0.0",
344 note = "This function will fail if the iterator produces only None values; prefer `try_from_sparse_iter_with_size`"
345 )]
346 pub fn try_from_sparse_iter<T, U>(mut iter: T) -> Result<Self, ArrowError>
347 where
348 T: Iterator<Item = Option<U>>,
349 U: AsRef<[u8]>,
350 {
351 let mut len = 0;
352 let mut value_size = None;
353 let mut byte = 0;
354
355 let iter_size_hint = iter.size_hint().0;
356 let mut null_buf = MutableBuffer::new(bit_util::ceil(iter_size_hint, 8));
357 let mut buffer = MutableBuffer::new(0);
358
359 let mut prepend = 0;
360 iter.try_for_each(|item| -> Result<(), ArrowError> {
361 if byte == 0 {
363 null_buf.push(0u8);
364 byte = 8;
365 }
366 byte -= 1;
367
368 if let Some(slice) = item {
369 let slice = slice.as_ref();
370 if let Some(size) = value_size {
371 if size != slice.len() {
372 return Err(ArrowError::InvalidArgumentError(format!(
373 "Nested array size mismatch: one is {}, and the other is {}",
374 size,
375 slice.len()
376 )));
377 }
378 } else {
379 let len = slice.len();
380 value_size = Some(len);
381 if let Some(capacity) = iter_size_hint.checked_mul(len) {
385 buffer.reserve(capacity);
386 }
387 let prepend_zeros = slice.len().checked_mul(prepend).ok_or_else(|| {
388 ArrowError::InvalidArgumentError(format!(
389 "FixedSizeBinaryArray error: value size {} * prepend {prepend} exceeds usize",
390 slice.len()
391 ))
392 })?;
393 buffer.extend_zeros(prepend_zeros);
394 }
395 bit_util::set_bit(null_buf.as_slice_mut(), len);
396 buffer.extend_from_slice(slice);
397 } else if let Some(size) = value_size {
398 buffer.extend_zeros(size);
399 } else {
400 prepend += 1;
401 }
402
403 len += 1;
404
405 Ok(())
406 })?;
407
408 if len == 0 {
409 return Err(ArrowError::InvalidArgumentError(
410 "Input iterable argument has no data".to_owned(),
411 ));
412 }
413
414 let nulls = NullBuffer::from_unsliced_buffer(null_buf, len);
415
416 let value_size = value_size.unwrap_or(0);
417 let value_length = value_size.try_into().map_err(|_| {
418 ArrowError::InvalidArgumentError(format!(
419 "FixedSizeBinaryArray value length exceeds i32, got {value_size}"
420 ))
421 })?;
422 Ok(Self {
423 data_type: DataType::FixedSizeBinary(value_length),
424 value_data: buffer.into(),
425 nulls,
426 value_size,
427 len,
428 })
429 }
430
431 pub fn try_from_sparse_iter_with_size<T, U>(
456 mut iter: T,
457 value_length: i32,
458 ) -> Result<Self, ArrowError>
459 where
460 T: Iterator<Item = Option<U>>,
461 U: AsRef<[u8]>,
462 {
463 let value_size = value_length.to_usize().ok_or_else(|| {
464 ArrowError::InvalidArgumentError(format!(
465 "Value length cannot be negative, got {value_length}"
466 ))
467 })?;
468 let mut len = 0;
469 let mut byte = 0;
470
471 let iter_size_hint = iter.size_hint().0;
472 let mut null_buf = MutableBuffer::new(bit_util::ceil(iter_size_hint, 8));
473 let capacity = iter_size_hint.checked_mul(value_size).ok_or_else(|| {
474 ArrowError::InvalidArgumentError(format!(
475 "FixedSizeBinaryArray error: value size {value_size} * len hint {iter_size_hint} exceeds usize"
476 ))
477 })?;
478 let mut buffer = MutableBuffer::new(capacity);
479
480 iter.try_for_each(|item| -> Result<(), ArrowError> {
481 if byte == 0 {
483 null_buf.push(0u8);
484 byte = 8;
485 }
486 byte -= 1;
487
488 if let Some(slice) = item {
489 let slice = slice.as_ref();
490 if value_size != slice.len() {
491 return Err(ArrowError::InvalidArgumentError(format!(
492 "Nested array size mismatch: one is {}, and the other is {}",
493 value_length,
494 slice.len()
495 )));
496 }
497
498 bit_util::set_bit(null_buf.as_slice_mut(), len);
499 buffer.extend_from_slice(slice);
500 } else {
501 buffer.extend_zeros(value_size);
502 }
503
504 len += 1;
505
506 Ok(())
507 })?;
508
509 let nulls = NullBuffer::from_unsliced_buffer(null_buf, len);
510
511 Ok(Self {
512 data_type: DataType::FixedSizeBinary(value_length),
513 value_data: buffer.into(),
514 nulls,
515 len,
516 value_size,
517 })
518 }
519
520 pub fn try_from_iter<T, U>(mut iter: T) -> Result<Self, ArrowError>
538 where
539 T: Iterator<Item = U>,
540 U: AsRef<[u8]>,
541 {
542 let mut len = 0;
543 let mut value_size = None;
544 let iter_size_hint = iter.size_hint().0;
545 let mut buffer = MutableBuffer::new(0);
546
547 iter.try_for_each(|item| -> Result<(), ArrowError> {
548 let slice = item.as_ref();
549 if let Some(value_size) = value_size {
550 if value_size != slice.len() {
551 return Err(ArrowError::InvalidArgumentError(format!(
552 "Nested array size mismatch: one is {value_size}, and the other is {}",
553 slice.len()
554 )));
555 }
556 } else {
557 let len = slice.len();
558 value_size = Some(len);
559 if let Some(capacity) = iter_size_hint.checked_mul(len) {
560 buffer.reserve(capacity);
561 }
562 }
563
564 buffer.extend_from_slice(slice);
565
566 len += 1;
567
568 Ok(())
569 })?;
570
571 if len == 0 {
572 return Err(ArrowError::InvalidArgumentError(
573 "Input iterable argument has no data".to_owned(),
574 ));
575 }
576
577 let value_size = value_size.unwrap_or(0);
578 let value_length = value_size.try_into().map_err(|_| {
579 ArrowError::InvalidArgumentError(format!(
580 "FixedSizeBinaryArray value length exceeds i32, got {value_size}"
581 ))
582 })?;
583 Ok(Self {
584 data_type: DataType::FixedSizeBinary(value_length),
585 value_data: buffer.into(),
586 nulls: None,
587 value_size,
588 len,
589 })
590 }
591
592 pub fn iter(&self) -> FixedSizeBinaryIter<'_> {
594 FixedSizeBinaryIter::new(self)
595 }
596}
597
598impl From<ArrayData> for FixedSizeBinaryArray {
599 fn from(data: ArrayData) -> Self {
600 let (data_type, len, nulls, offset, buffers, _child_data) = data.into_parts();
601
602 assert_eq!(
603 buffers.len(),
604 1,
605 "FixedSizeBinaryArray data should contain 1 buffer only (values)"
606 );
607 let value_length = match data_type {
608 DataType::FixedSizeBinary(len) => len,
609 _ => panic!("Expected data type to be FixedSizeBinary"),
610 };
611
612 let value_size = value_length
613 .to_usize()
614 .expect("FixedSizeBinaryArray value length must be non-negative");
615 let value_data = buffers[0].slice_with_length(
616 offset.checked_mul(value_size).expect("offset overflow"),
617 len.checked_mul(value_size).expect("length overflow"),
618 );
619
620 Self {
621 data_type,
622 nulls,
623 len,
624 value_data,
625 value_size,
626 }
627 }
628}
629
630impl From<FixedSizeBinaryArray> for ArrayData {
631 fn from(array: FixedSizeBinaryArray) -> Self {
632 let builder = ArrayDataBuilder::new(array.data_type)
633 .len(array.len)
634 .buffers(vec![array.value_data])
635 .nulls(array.nulls);
636
637 unsafe { builder.build_unchecked() }
638 }
639}
640
641impl From<FixedSizeListArray> for FixedSizeBinaryArray {
643 fn from(v: FixedSizeListArray) -> Self {
644 let value_len = v.value_length();
645 let v = v.into_data();
646 assert_eq!(
647 v.child_data().len(),
648 1,
649 "FixedSizeBinaryArray can only be created from list array of u8 values \
650 (i.e. FixedSizeList<PrimitiveArray<u8>>)."
651 );
652 let child_data = &v.child_data()[0];
653
654 assert_eq!(
655 child_data.child_data().len(),
656 0,
657 "FixedSizeBinaryArray can only be created from list array of u8 values \
658 (i.e. FixedSizeList<PrimitiveArray<u8>>)."
659 );
660 assert_eq!(
661 child_data.data_type(),
662 &DataType::UInt8,
663 "FixedSizeBinaryArray can only be created from FixedSizeList<u8> arrays, mismatched data types."
664 );
665 assert_eq!(
666 child_data.null_count(),
667 0,
668 "The child array cannot contain null values."
669 );
670
671 let builder = ArrayData::builder(DataType::FixedSizeBinary(value_len))
672 .len(v.len())
673 .offset(v.offset())
674 .add_buffer(child_data.buffers()[0].slice(child_data.offset()))
675 .nulls(v.nulls().cloned());
676
677 let data = unsafe { builder.build_unchecked() };
678 Self::from(data)
679 }
680}
681
682impl TryFrom<Vec<Option<&[u8]>>> for FixedSizeBinaryArray {
683 type Error = ArrowError;
684
685 fn try_from(v: Vec<Option<&[u8]>>) -> Result<Self, Self::Error> {
686 #[allow(deprecated)]
687 Self::try_from_sparse_iter(v.into_iter())
688 }
689}
690
691impl TryFrom<Vec<&[u8]>> for FixedSizeBinaryArray {
692 type Error = ArrowError;
693
694 fn try_from(v: Vec<&[u8]>) -> Result<Self, Self::Error> {
695 Self::try_from_iter(v.into_iter())
696 }
697}
698
699impl<const N: usize> TryFrom<Vec<Option<&[u8; N]>>> for FixedSizeBinaryArray {
700 type Error = ArrowError;
701
702 fn try_from(v: Vec<Option<&[u8; N]>>) -> Result<Self, Self::Error> {
703 N.try_into()
704 .map_err(|_| {
705 ArrowError::InvalidArgumentError(format!(
706 "FixedSizeBinaryArray value length exceeds i32, got {N}"
707 ))
708 })
709 .and_then(|x| Self::try_from_sparse_iter_with_size(v.into_iter(), x))
710 }
711}
712
713impl<const N: usize> TryFrom<Vec<&[u8; N]>> for FixedSizeBinaryArray {
714 type Error = ArrowError;
715
716 fn try_from(v: Vec<&[u8; N]>) -> Result<Self, Self::Error> {
717 Self::try_from_iter(v.into_iter())
718 }
719}
720
721impl std::fmt::Debug for FixedSizeBinaryArray {
722 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
723 write!(f, "FixedSizeBinaryArray<{}>\n[\n", self.value_length())?;
724 print_long_array(self, f, |array, index, f| {
725 std::fmt::Debug::fmt(&array.value(index), f)
726 })?;
727 write!(f, "]")
728 }
729}
730
731unsafe impl Array for FixedSizeBinaryArray {
733 fn as_any(&self) -> &dyn Any {
734 self
735 }
736
737 fn to_data(&self) -> ArrayData {
738 self.clone().into()
739 }
740
741 fn into_data(self) -> ArrayData {
742 self.into()
743 }
744
745 fn data_type(&self) -> &DataType {
746 &self.data_type
747 }
748
749 fn slice(&self, offset: usize, length: usize) -> ArrayRef {
750 Arc::new(self.slice(offset, length))
751 }
752
753 fn len(&self) -> usize {
754 self.len
755 }
756
757 fn is_empty(&self) -> bool {
758 self.len == 0
759 }
760
761 fn shrink_to_fit(&mut self) {
762 self.value_data.shrink_to_fit();
763 if let Some(nulls) = &mut self.nulls {
764 nulls.shrink_to_fit();
765 }
766 }
767
768 fn offset(&self) -> usize {
769 0
772 }
773
774 fn nulls(&self) -> Option<&NullBuffer> {
775 self.nulls.as_ref()
776 }
777
778 fn logical_null_count(&self) -> usize {
779 self.null_count()
781 }
782
783 fn get_buffer_memory_size(&self) -> usize {
784 let mut sum = self.value_data.capacity();
785 if let Some(n) = &self.nulls {
786 sum += n.buffer().capacity();
787 }
788 sum
789 }
790
791 fn get_array_memory_size(&self) -> usize {
792 std::mem::size_of::<Self>() + self.get_buffer_memory_size()
793 }
794
795 #[cfg(feature = "pool")]
796 fn claim(&self, pool: &dyn arrow_buffer::MemoryPool) {
797 self.value_data.claim(pool);
798 if let Some(nulls) = &self.nulls {
799 nulls.claim(pool);
800 }
801 }
802}
803
804impl<'a> ArrayAccessor for &'a FixedSizeBinaryArray {
805 type Item = &'a [u8];
806
807 fn value(&self, index: usize) -> Self::Item {
808 FixedSizeBinaryArray::value(self, index)
809 }
810
811 unsafe fn value_unchecked(&self, index: usize) -> Self::Item {
812 unsafe { FixedSizeBinaryArray::value_unchecked(self, index) }
813 }
814}
815
816impl<'a> IntoIterator for &'a FixedSizeBinaryArray {
817 type Item = Option<&'a [u8]>;
818 type IntoIter = FixedSizeBinaryIter<'a>;
819
820 fn into_iter(self) -> Self::IntoIter {
821 FixedSizeBinaryIter::<'a>::new(self)
822 }
823}
824
825#[cfg(test)]
826mod tests {
827 use super::*;
828 use crate::RecordBatch;
829 use arrow_schema::{Field, Schema};
830
831 #[test]
832 fn test_fixed_size_binary_array() {
833 let values: [u8; 15] = *b"hellotherearrow";
834
835 let array_data = ArrayData::builder(DataType::FixedSizeBinary(5))
836 .len(3)
837 .add_buffer(Buffer::from(&values))
838 .build()
839 .unwrap();
840 let fixed_size_binary_array = FixedSizeBinaryArray::from(array_data);
841 assert_eq!(3, fixed_size_binary_array.len());
842 assert_eq!(0, fixed_size_binary_array.null_count());
843 assert_eq!(
844 [b'h', b'e', b'l', b'l', b'o'],
845 fixed_size_binary_array.value(0)
846 );
847 assert_eq!(
848 [b't', b'h', b'e', b'r', b'e'],
849 fixed_size_binary_array.value(1)
850 );
851 assert_eq!(
852 [b'a', b'r', b'r', b'o', b'w'],
853 fixed_size_binary_array.value(2)
854 );
855 assert_eq!(5, fixed_size_binary_array.value_length());
856 for i in 0..3 {
857 assert!(fixed_size_binary_array.is_valid(i));
858 assert!(!fixed_size_binary_array.is_null(i));
859 }
860
861 let array_data = ArrayData::builder(DataType::FixedSizeBinary(5))
863 .len(2)
864 .offset(1)
865 .add_buffer(Buffer::from(&values))
866 .build()
867 .unwrap();
868 let fixed_size_binary_array = FixedSizeBinaryArray::from(array_data);
869 assert_eq!(
870 [b't', b'h', b'e', b'r', b'e'],
871 fixed_size_binary_array.value(0)
872 );
873 assert_eq!(
874 [b'a', b'r', b'r', b'o', b'w'],
875 fixed_size_binary_array.value(1)
876 );
877 assert_eq!(2, fixed_size_binary_array.len());
878 assert_eq!(5, fixed_size_binary_array.value_length());
879 }
880
881 #[test]
882 fn test_fixed_size_binary_array_from_fixed_size_list_array() {
883 let values = [0_u8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
884 let values_data = ArrayData::builder(DataType::UInt8)
885 .len(12)
886 .offset(2)
887 .add_buffer(Buffer::from_slice_ref(values))
888 .build()
889 .unwrap();
890 let array_data = unsafe {
892 ArrayData::builder(DataType::FixedSizeList(
893 Arc::new(Field::new_list_field(DataType::UInt8, false)),
894 4,
895 ))
896 .len(2)
897 .offset(1)
898 .add_child_data(values_data)
899 .null_bit_buffer(Some(Buffer::from_slice_ref([0b101])))
900 .build_unchecked()
901 };
902 let list_array = FixedSizeListArray::from(array_data);
903 let binary_array = FixedSizeBinaryArray::from(list_array);
904
905 assert_eq!(2, binary_array.len());
906 assert_eq!(1, binary_array.null_count());
907 assert!(binary_array.is_null(0));
908 assert!(binary_array.is_valid(1));
909 assert_eq!(&[10, 11, 12, 13], binary_array.value(1));
910 }
911
912 #[test]
913 #[should_panic(
914 expected = "FixedSizeBinaryArray can only be created from FixedSizeList<u8> arrays"
915 )]
916 #[cfg(not(feature = "force_validate"))]
919 fn test_fixed_size_binary_array_from_incorrect_fixed_size_list_array() {
920 let values: [u32; 12] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
921 let values_data = ArrayData::builder(DataType::UInt32)
922 .len(12)
923 .add_buffer(Buffer::from_slice_ref(values))
924 .build()
925 .unwrap();
926
927 let array_data = unsafe {
928 ArrayData::builder(DataType::FixedSizeList(
929 Arc::new(Field::new_list_field(DataType::Binary, false)),
930 4,
931 ))
932 .len(3)
933 .add_child_data(values_data)
934 .build_unchecked()
935 };
936 let list_array = FixedSizeListArray::from(array_data);
937 drop(FixedSizeBinaryArray::from(list_array));
938 }
939
940 #[test]
941 #[should_panic(expected = "The child array cannot contain null values.")]
942 fn test_fixed_size_binary_array_from_fixed_size_list_array_with_child_nulls_failed() {
943 let values = [0_u8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
944 let values_data = ArrayData::builder(DataType::UInt8)
945 .len(12)
946 .add_buffer(Buffer::from_slice_ref(values))
947 .null_bit_buffer(Some(Buffer::from_slice_ref([0b101010101010])))
948 .build()
949 .unwrap();
950
951 let array_data = unsafe {
952 ArrayData::builder(DataType::FixedSizeList(
953 Arc::new(Field::new_list_field(DataType::UInt8, false)),
954 4,
955 ))
956 .len(3)
957 .add_child_data(values_data)
958 .build_unchecked()
959 };
960 let list_array = FixedSizeListArray::from(array_data);
961 drop(FixedSizeBinaryArray::from(list_array));
962 }
963
964 #[test]
965 fn test_fixed_size_binary_array_fmt_debug() {
966 let values: [u8; 15] = *b"hellotherearrow";
967
968 let array_data = ArrayData::builder(DataType::FixedSizeBinary(5))
969 .len(3)
970 .add_buffer(Buffer::from(&values))
971 .build()
972 .unwrap();
973 let arr = FixedSizeBinaryArray::from(array_data);
974 assert_eq!(
975 "FixedSizeBinaryArray<5>\n[\n [104, 101, 108, 108, 111],\n [116, 104, 101, 114, 101],\n [97, 114, 114, 111, 119],\n]",
976 format!("{arr:?}")
977 );
978 }
979
980 #[test]
981 fn test_fixed_size_binary_array_from_iter() {
982 let input_arg = vec![vec![1, 2], vec![3, 4], vec![5, 6]];
983 let arr = FixedSizeBinaryArray::try_from_iter(input_arg.into_iter()).unwrap();
984
985 assert_eq!(2, arr.value_length());
986 assert_eq!(3, arr.len())
987 }
988
989 #[test]
990 fn test_all_none_fixed_size_binary_array_from_sparse_iter() {
991 let none_option: Option<[u8; 32]> = None;
992 let input_arg = vec![none_option, none_option, none_option];
993 #[allow(deprecated)]
994 let arr = FixedSizeBinaryArray::try_from_sparse_iter(input_arg.into_iter()).unwrap();
995 assert_eq!(0, arr.value_length());
996 assert_eq!(3, arr.len())
997 }
998
999 #[test]
1000 fn test_fixed_size_binary_array_from_sparse_iter() {
1001 let input_arg = vec![
1002 None,
1003 Some(vec![7, 8]),
1004 Some(vec![9, 10]),
1005 None,
1006 Some(vec![13, 14]),
1007 ];
1008 #[allow(deprecated)]
1009 let arr = FixedSizeBinaryArray::try_from_sparse_iter(input_arg.iter().cloned()).unwrap();
1010 assert_eq!(2, arr.value_length());
1011 assert_eq!(5, arr.len());
1012
1013 let arr =
1014 FixedSizeBinaryArray::try_from_sparse_iter_with_size(input_arg.into_iter(), 2).unwrap();
1015 assert_eq!(2, arr.value_length());
1016 assert_eq!(5, arr.len());
1017 }
1018
1019 #[test]
1020 fn test_fixed_size_binary_array_from_sparse_iter_with_size_all_none() {
1021 let input_arg = vec![None, None, None, None, None] as Vec<Option<Vec<u8>>>;
1022
1023 let arr = FixedSizeBinaryArray::try_from_sparse_iter_with_size(input_arg.into_iter(), 16)
1024 .unwrap();
1025 assert_eq!(16, arr.value_length());
1026 assert_eq!(5, arr.len())
1027 }
1028
1029 #[test]
1030 fn test_fixed_size_binary_array_from_vec() {
1031 let values = vec!["one".as_bytes(), b"two", b"six", b"ten"];
1032 let array = FixedSizeBinaryArray::try_from(values).unwrap();
1033 assert_eq!(array.len(), 4);
1034 assert_eq!(array.null_count(), 0);
1035 assert_eq!(array.logical_null_count(), 0);
1036 assert_eq!(array.value(0), b"one");
1037 assert_eq!(array.value(1), b"two");
1038 assert_eq!(array.value(2), b"six");
1039 assert_eq!(array.value(3), b"ten");
1040 assert!(!array.is_null(0));
1041 assert!(!array.is_null(1));
1042 assert!(!array.is_null(2));
1043 assert!(!array.is_null(3));
1044 }
1045
1046 #[test]
1047 fn test_fixed_size_binary_array_from_vec_incorrect_length() {
1048 let values = vec!["one".as_bytes(), b"two", b"three", b"four"];
1049 assert!(FixedSizeBinaryArray::try_from(values).is_err());
1050 }
1051
1052 #[test]
1053 fn test_fixed_size_binary_array_from_opt_vec() {
1054 let values = vec![
1055 Some("one".as_bytes()),
1056 Some(b"two"),
1057 None,
1058 Some(b"six"),
1059 Some(b"ten"),
1060 ];
1061 let array = FixedSizeBinaryArray::try_from(values).unwrap();
1062 assert_eq!(array.len(), 5);
1063 assert_eq!(array.value(0), b"one");
1064 assert_eq!(array.value(1), b"two");
1065 assert_eq!(array.value(3), b"six");
1066 assert_eq!(array.value(4), b"ten");
1067 assert!(!array.is_null(0));
1068 assert!(!array.is_null(1));
1069 assert!(array.is_null(2));
1070 assert!(!array.is_null(3));
1071 assert!(!array.is_null(4));
1072 }
1073
1074 #[test]
1075 fn test_fixed_size_binary_array_from_opt_vec_incorrect_length() {
1076 let values = vec![
1077 Some("one".as_bytes()),
1078 Some(b"two"),
1079 None,
1080 Some(b"three"),
1081 Some(b"four"),
1082 ];
1083 assert!(FixedSizeBinaryArray::try_from(values).is_err());
1084 }
1085
1086 #[test]
1087 fn fixed_size_binary_array_all_null() {
1088 let data = vec![None] as Vec<Option<String>>;
1089 let array =
1090 FixedSizeBinaryArray::try_from_sparse_iter_with_size(data.into_iter(), 0).unwrap();
1091 array
1092 .into_data()
1093 .validate_full()
1094 .expect("All null array has valid array data");
1095 }
1096
1097 #[test]
1098 fn fixed_size_binary_array_all_null_in_batch_with_schema() {
1100 let schema = Schema::new(vec![Field::new("a", DataType::FixedSizeBinary(2), true)]);
1101
1102 let none_option: Option<[u8; 2]> = None;
1103 let item = FixedSizeBinaryArray::try_from_sparse_iter_with_size(
1104 vec![none_option, none_option, none_option].into_iter(),
1105 2,
1106 )
1107 .unwrap();
1108
1109 RecordBatch::try_new(Arc::new(schema), vec![Arc::new(item)]).unwrap();
1111 }
1112
1113 #[test]
1114 #[should_panic(
1115 expected = "Trying to access an element at index 4 from a FixedSizeBinaryArray of length 3"
1116 )]
1117 fn test_fixed_size_binary_array_get_value_index_out_of_bound() {
1118 let values = vec![Some("one".as_bytes()), Some(b"two"), None];
1119 let array = FixedSizeBinaryArray::try_from(values).unwrap();
1120
1121 array.value(4);
1122 }
1123
1124 #[test]
1125 fn test_constructors() {
1126 let buffer = Buffer::from_vec(vec![0_u8; 10]);
1127 let a = FixedSizeBinaryArray::new(2, buffer.clone(), None);
1128 assert_eq!(a.len(), 5);
1129
1130 let nulls = NullBuffer::new_null(5);
1131 FixedSizeBinaryArray::new(2, buffer.clone(), Some(nulls));
1132
1133 let null_array = FixedSizeBinaryArray::new_null(4, 3);
1134 assert_eq!(null_array.len(), 3);
1135 assert_eq!(null_array.values().len(), 12);
1136
1137 let a = FixedSizeBinaryArray::new(3, buffer.clone(), None);
1138 assert_eq!(a.len(), 3);
1139
1140 let nulls = NullBuffer::new_null(3);
1141 FixedSizeBinaryArray::new(3, buffer.clone(), Some(nulls));
1142
1143 let err = FixedSizeBinaryArray::try_new(-1, buffer.clone(), None).unwrap_err();
1144
1145 assert_eq!(
1146 err.to_string(),
1147 "Invalid argument error: Value length cannot be negative, got -1"
1148 );
1149
1150 let nulls = NullBuffer::new_null(3);
1151 let err = FixedSizeBinaryArray::try_new(2, buffer.clone(), Some(nulls)).unwrap_err();
1152 assert_eq!(
1153 err.to_string(),
1154 "Invalid argument error: Incorrect length of null buffer for FixedSizeBinaryArray, expected 5 got 3"
1155 );
1156
1157 let zero_sized = FixedSizeBinaryArray::new(0, Buffer::default(), None);
1158 assert_eq!(zero_sized.len(), 0);
1159 assert_eq!(zero_sized.null_count(), 0);
1160 assert_eq!(zero_sized.values().len(), 0);
1161
1162 let nulls = NullBuffer::new_null(3);
1163 let zero_sized_with_nulls = FixedSizeBinaryArray::new(0, Buffer::default(), Some(nulls));
1164 assert_eq!(zero_sized_with_nulls.len(), 3);
1165 assert_eq!(zero_sized_with_nulls.null_count(), 3);
1166 assert_eq!(zero_sized_with_nulls.values().len(), 0);
1167
1168 let zero_sized_with_non_empty_buffer_err =
1169 FixedSizeBinaryArray::try_new(0, buffer, None).unwrap_err();
1170 assert_eq!(
1171 zero_sized_with_non_empty_buffer_err.to_string(),
1172 "Invalid argument error: Buffer cannot have non-zero length if the value length is zero"
1173 );
1174 }
1175}