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, BooleanBuffer, 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)]
53pub struct FixedSizeBinaryArray {
54 data_type: DataType, value_data: Buffer,
56 nulls: Option<NullBuffer>,
57 len: usize,
58 value_length: i32,
59}
60
61impl FixedSizeBinaryArray {
62 pub fn new(size: i32, values: Buffer, nulls: Option<NullBuffer>) -> Self {
68 Self::try_new(size, values, nulls).unwrap()
69 }
70
71 pub fn new_scalar(value: impl AsRef<[u8]>) -> Scalar<Self> {
73 let v = value.as_ref();
74 Scalar::new(Self::new(v.len() as _, Buffer::from(v), None))
75 }
76
77 pub fn try_new(
84 size: i32,
85 values: Buffer,
86 nulls: Option<NullBuffer>,
87 ) -> Result<Self, ArrowError> {
88 let data_type = DataType::FixedSizeBinary(size);
89 let s = size.to_usize().ok_or_else(|| {
90 ArrowError::InvalidArgumentError(format!("Size cannot be negative, got {size}"))
91 })?;
92
93 let len = values.len() / s;
94 if let Some(n) = nulls.as_ref() {
95 if n.len() != len {
96 return Err(ArrowError::InvalidArgumentError(format!(
97 "Incorrect length of null buffer for FixedSizeBinaryArray, expected {} got {}",
98 len,
99 n.len(),
100 )));
101 }
102 }
103
104 Ok(Self {
105 data_type,
106 value_data: values,
107 value_length: size,
108 nulls,
109 len,
110 })
111 }
112
113 pub fn new_null(size: i32, len: usize) -> Self {
122 let capacity = size.to_usize().unwrap().checked_mul(len).unwrap();
123 Self {
124 data_type: DataType::FixedSizeBinary(size),
125 value_data: MutableBuffer::new(capacity).into(),
126 nulls: Some(NullBuffer::new_null(len)),
127 value_length: size,
128 len,
129 }
130 }
131
132 pub fn into_parts(self) -> (i32, Buffer, Option<NullBuffer>) {
134 (self.value_length, self.value_data, self.nulls)
135 }
136
137 pub fn value(&self, i: usize) -> &[u8] {
145 assert!(
146 i < self.len(),
147 "Trying to access an element at index {} from a FixedSizeBinaryArray of length {}",
148 i,
149 self.len()
150 );
151 let offset = i + self.offset();
152 unsafe {
153 let pos = self.value_offset_at(offset);
154 std::slice::from_raw_parts(
155 self.value_data.as_ptr().offset(pos as isize),
156 (self.value_offset_at(offset + 1) - pos) as usize,
157 )
158 }
159 }
160
161 pub unsafe fn value_unchecked(&self, i: usize) -> &[u8] {
171 let offset = i + self.offset();
172 let pos = self.value_offset_at(offset);
173 unsafe {
174 std::slice::from_raw_parts(
175 self.value_data.as_ptr().offset(pos as isize),
176 (self.value_offset_at(offset + 1) - pos) as usize,
177 )
178 }
179 }
180
181 #[inline]
185 pub fn value_offset(&self, i: usize) -> i32 {
186 self.value_offset_at(self.offset() + i)
187 }
188
189 #[inline]
193 pub fn value_length(&self) -> i32 {
194 self.value_length
195 }
196
197 #[inline]
202 pub fn values(&self) -> &Buffer {
203 &self.value_data
204 }
205
206 pub fn value_data(&self) -> &[u8] {
208 self.value_data.as_slice()
209 }
210
211 pub fn slice(&self, offset: usize, len: usize) -> Self {
213 assert!(
214 offset.saturating_add(len) <= self.len,
215 "the length + offset of the sliced FixedSizeBinaryArray cannot exceed the existing length"
216 );
217
218 let size = self.value_length as usize;
219
220 Self {
221 data_type: self.data_type.clone(),
222 nulls: self.nulls.as_ref().map(|n| n.slice(offset, len)),
223 value_length: self.value_length,
224 value_data: self.value_data.slice_with_length(offset * size, len * size),
225 len,
226 }
227 }
228
229 #[deprecated(
252 since = "28.0.0",
253 note = "This function will fail if the iterator produces only None values; prefer `try_from_sparse_iter_with_size`"
254 )]
255 pub fn try_from_sparse_iter<T, U>(mut iter: T) -> Result<Self, ArrowError>
256 where
257 T: Iterator<Item = Option<U>>,
258 U: AsRef<[u8]>,
259 {
260 let mut len = 0;
261 let mut size = None;
262 let mut byte = 0;
263
264 let iter_size_hint = iter.size_hint().0;
265 let mut null_buf = MutableBuffer::new(bit_util::ceil(iter_size_hint, 8));
266 let mut buffer = MutableBuffer::new(0);
267
268 let mut prepend = 0;
269 iter.try_for_each(|item| -> Result<(), ArrowError> {
270 if byte == 0 {
272 null_buf.push(0u8);
273 byte = 8;
274 }
275 byte -= 1;
276
277 if let Some(slice) = item {
278 let slice = slice.as_ref();
279 if let Some(size) = size {
280 if size != slice.len() {
281 return Err(ArrowError::InvalidArgumentError(format!(
282 "Nested array size mismatch: one is {}, and the other is {}",
283 size,
284 slice.len()
285 )));
286 }
287 } else {
288 let len = slice.len();
289 size = Some(len);
290 buffer.reserve(iter_size_hint * len);
294 buffer.extend_zeros(slice.len() * prepend);
295 }
296 bit_util::set_bit(null_buf.as_slice_mut(), len);
297 buffer.extend_from_slice(slice);
298 } else if let Some(size) = size {
299 buffer.extend_zeros(size);
300 } else {
301 prepend += 1;
302 }
303
304 len += 1;
305
306 Ok(())
307 })?;
308
309 if len == 0 {
310 return Err(ArrowError::InvalidArgumentError(
311 "Input iterable argument has no data".to_owned(),
312 ));
313 }
314
315 let null_buf = BooleanBuffer::new(null_buf.into(), 0, len);
316 let nulls = Some(NullBuffer::new(null_buf)).filter(|n| n.null_count() > 0);
317
318 let size = size.unwrap_or(0) as i32;
319 Ok(Self {
320 data_type: DataType::FixedSizeBinary(size),
321 value_data: buffer.into(),
322 nulls,
323 value_length: size,
324 len,
325 })
326 }
327
328 pub fn try_from_sparse_iter_with_size<T, U>(mut iter: T, size: i32) -> Result<Self, ArrowError>
353 where
354 T: Iterator<Item = Option<U>>,
355 U: AsRef<[u8]>,
356 {
357 let mut len = 0;
358 let mut byte = 0;
359
360 let iter_size_hint = iter.size_hint().0;
361 let mut null_buf = MutableBuffer::new(bit_util::ceil(iter_size_hint, 8));
362 let mut buffer = MutableBuffer::new(iter_size_hint * (size as usize));
363
364 iter.try_for_each(|item| -> Result<(), ArrowError> {
365 if byte == 0 {
367 null_buf.push(0u8);
368 byte = 8;
369 }
370 byte -= 1;
371
372 if let Some(slice) = item {
373 let slice = slice.as_ref();
374 if size as usize != slice.len() {
375 return Err(ArrowError::InvalidArgumentError(format!(
376 "Nested array size mismatch: one is {}, and the other is {}",
377 size,
378 slice.len()
379 )));
380 }
381
382 bit_util::set_bit(null_buf.as_slice_mut(), len);
383 buffer.extend_from_slice(slice);
384 } else {
385 buffer.extend_zeros(size as usize);
386 }
387
388 len += 1;
389
390 Ok(())
391 })?;
392
393 let null_buf = BooleanBuffer::new(null_buf.into(), 0, len);
394 let nulls = Some(NullBuffer::new(null_buf)).filter(|n| n.null_count() > 0);
395
396 Ok(Self {
397 data_type: DataType::FixedSizeBinary(size),
398 value_data: buffer.into(),
399 nulls,
400 len,
401 value_length: size,
402 })
403 }
404
405 pub fn try_from_iter<T, U>(mut iter: T) -> Result<Self, ArrowError>
423 where
424 T: Iterator<Item = U>,
425 U: AsRef<[u8]>,
426 {
427 let mut len = 0;
428 let mut size = None;
429 let iter_size_hint = iter.size_hint().0;
430 let mut buffer = MutableBuffer::new(0);
431
432 iter.try_for_each(|item| -> Result<(), ArrowError> {
433 let slice = item.as_ref();
434 if let Some(size) = size {
435 if size != slice.len() {
436 return Err(ArrowError::InvalidArgumentError(format!(
437 "Nested array size mismatch: one is {}, and the other is {}",
438 size,
439 slice.len()
440 )));
441 }
442 } else {
443 let len = slice.len();
444 size = Some(len);
445 buffer.reserve(iter_size_hint * len);
446 }
447
448 buffer.extend_from_slice(slice);
449
450 len += 1;
451
452 Ok(())
453 })?;
454
455 if len == 0 {
456 return Err(ArrowError::InvalidArgumentError(
457 "Input iterable argument has no data".to_owned(),
458 ));
459 }
460
461 let size = size.unwrap_or(0).try_into().unwrap();
462 Ok(Self {
463 data_type: DataType::FixedSizeBinary(size),
464 value_data: buffer.into(),
465 nulls: None,
466 value_length: size,
467 len,
468 })
469 }
470
471 #[inline]
472 fn value_offset_at(&self, i: usize) -> i32 {
473 self.value_length * i as i32
474 }
475
476 pub fn iter(&self) -> FixedSizeBinaryIter<'_> {
478 FixedSizeBinaryIter::new(self)
479 }
480}
481
482impl From<ArrayData> for FixedSizeBinaryArray {
483 fn from(data: ArrayData) -> Self {
484 assert_eq!(
485 data.buffers().len(),
486 1,
487 "FixedSizeBinaryArray data should contain 1 buffer only (values)"
488 );
489 let value_length = match data.data_type() {
490 DataType::FixedSizeBinary(len) => *len,
491 _ => panic!("Expected data type to be FixedSizeBinary"),
492 };
493
494 let size = value_length as usize;
495 let value_data =
496 data.buffers()[0].slice_with_length(data.offset() * size, data.len() * size);
497
498 Self {
499 data_type: data.data_type().clone(),
500 nulls: data.nulls().cloned(),
501 len: data.len(),
502 value_data,
503 value_length,
504 }
505 }
506}
507
508impl From<FixedSizeBinaryArray> for ArrayData {
509 fn from(array: FixedSizeBinaryArray) -> Self {
510 let builder = ArrayDataBuilder::new(array.data_type)
511 .len(array.len)
512 .buffers(vec![array.value_data])
513 .nulls(array.nulls);
514
515 unsafe { builder.build_unchecked() }
516 }
517}
518
519impl From<FixedSizeListArray> for FixedSizeBinaryArray {
521 fn from(v: FixedSizeListArray) -> Self {
522 let value_len = v.value_length();
523 let v = v.into_data();
524 assert_eq!(
525 v.child_data().len(),
526 1,
527 "FixedSizeBinaryArray can only be created from list array of u8 values \
528 (i.e. FixedSizeList<PrimitiveArray<u8>>)."
529 );
530 let child_data = &v.child_data()[0];
531
532 assert_eq!(
533 child_data.child_data().len(),
534 0,
535 "FixedSizeBinaryArray can only be created from list array of u8 values \
536 (i.e. FixedSizeList<PrimitiveArray<u8>>)."
537 );
538 assert_eq!(
539 child_data.data_type(),
540 &DataType::UInt8,
541 "FixedSizeBinaryArray can only be created from FixedSizeList<u8> arrays, mismatched data types."
542 );
543 assert_eq!(
544 child_data.null_count(),
545 0,
546 "The child array cannot contain null values."
547 );
548
549 let builder = ArrayData::builder(DataType::FixedSizeBinary(value_len))
550 .len(v.len())
551 .offset(v.offset())
552 .add_buffer(child_data.buffers()[0].slice(child_data.offset()))
553 .nulls(v.nulls().cloned());
554
555 let data = unsafe { builder.build_unchecked() };
556 Self::from(data)
557 }
558}
559
560impl From<Vec<Option<&[u8]>>> for FixedSizeBinaryArray {
561 fn from(v: Vec<Option<&[u8]>>) -> Self {
562 #[allow(deprecated)]
563 Self::try_from_sparse_iter(v.into_iter()).unwrap()
564 }
565}
566
567impl From<Vec<&[u8]>> for FixedSizeBinaryArray {
568 fn from(v: Vec<&[u8]>) -> Self {
569 Self::try_from_iter(v.into_iter()).unwrap()
570 }
571}
572
573impl<const N: usize> From<Vec<&[u8; N]>> for FixedSizeBinaryArray {
574 fn from(v: Vec<&[u8; N]>) -> Self {
575 Self::try_from_iter(v.into_iter()).unwrap()
576 }
577}
578
579impl std::fmt::Debug for FixedSizeBinaryArray {
580 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
581 write!(f, "FixedSizeBinaryArray<{}>\n[\n", self.value_length())?;
582 print_long_array(self, f, |array, index, f| {
583 std::fmt::Debug::fmt(&array.value(index), f)
584 })?;
585 write!(f, "]")
586 }
587}
588
589impl Array for FixedSizeBinaryArray {
590 fn as_any(&self) -> &dyn Any {
591 self
592 }
593
594 fn to_data(&self) -> ArrayData {
595 self.clone().into()
596 }
597
598 fn into_data(self) -> ArrayData {
599 self.into()
600 }
601
602 fn data_type(&self) -> &DataType {
603 &self.data_type
604 }
605
606 fn slice(&self, offset: usize, length: usize) -> ArrayRef {
607 Arc::new(self.slice(offset, length))
608 }
609
610 fn len(&self) -> usize {
611 self.len
612 }
613
614 fn is_empty(&self) -> bool {
615 self.len == 0
616 }
617
618 fn shrink_to_fit(&mut self) {
619 self.value_data.shrink_to_fit();
620 if let Some(nulls) = &mut self.nulls {
621 nulls.shrink_to_fit();
622 }
623 }
624
625 fn offset(&self) -> usize {
626 0
627 }
628
629 fn nulls(&self) -> Option<&NullBuffer> {
630 self.nulls.as_ref()
631 }
632
633 fn logical_null_count(&self) -> usize {
634 self.null_count()
636 }
637
638 fn get_buffer_memory_size(&self) -> usize {
639 let mut sum = self.value_data.capacity();
640 if let Some(n) = &self.nulls {
641 sum += n.buffer().capacity();
642 }
643 sum
644 }
645
646 fn get_array_memory_size(&self) -> usize {
647 std::mem::size_of::<Self>() + self.get_buffer_memory_size()
648 }
649}
650
651impl<'a> ArrayAccessor for &'a FixedSizeBinaryArray {
652 type Item = &'a [u8];
653
654 fn value(&self, index: usize) -> Self::Item {
655 FixedSizeBinaryArray::value(self, index)
656 }
657
658 unsafe fn value_unchecked(&self, index: usize) -> Self::Item {
659 unsafe { FixedSizeBinaryArray::value_unchecked(self, index) }
660 }
661}
662
663impl<'a> IntoIterator for &'a FixedSizeBinaryArray {
664 type Item = Option<&'a [u8]>;
665 type IntoIter = FixedSizeBinaryIter<'a>;
666
667 fn into_iter(self) -> Self::IntoIter {
668 FixedSizeBinaryIter::<'a>::new(self)
669 }
670}
671
672#[cfg(test)]
673mod tests {
674 use crate::RecordBatch;
675 use arrow_schema::{Field, Schema};
676
677 use super::*;
678
679 #[test]
680 fn test_fixed_size_binary_array() {
681 let values: [u8; 15] = *b"hellotherearrow";
682
683 let array_data = ArrayData::builder(DataType::FixedSizeBinary(5))
684 .len(3)
685 .add_buffer(Buffer::from(&values))
686 .build()
687 .unwrap();
688 let fixed_size_binary_array = FixedSizeBinaryArray::from(array_data);
689 assert_eq!(3, fixed_size_binary_array.len());
690 assert_eq!(0, fixed_size_binary_array.null_count());
691 assert_eq!(
692 [b'h', b'e', b'l', b'l', b'o'],
693 fixed_size_binary_array.value(0)
694 );
695 assert_eq!(
696 [b't', b'h', b'e', b'r', b'e'],
697 fixed_size_binary_array.value(1)
698 );
699 assert_eq!(
700 [b'a', b'r', b'r', b'o', b'w'],
701 fixed_size_binary_array.value(2)
702 );
703 assert_eq!(5, fixed_size_binary_array.value_length());
704 assert_eq!(10, fixed_size_binary_array.value_offset(2));
705 for i in 0..3 {
706 assert!(fixed_size_binary_array.is_valid(i));
707 assert!(!fixed_size_binary_array.is_null(i));
708 }
709
710 let array_data = ArrayData::builder(DataType::FixedSizeBinary(5))
712 .len(2)
713 .offset(1)
714 .add_buffer(Buffer::from(&values))
715 .build()
716 .unwrap();
717 let fixed_size_binary_array = FixedSizeBinaryArray::from(array_data);
718 assert_eq!(
719 [b't', b'h', b'e', b'r', b'e'],
720 fixed_size_binary_array.value(0)
721 );
722 assert_eq!(
723 [b'a', b'r', b'r', b'o', b'w'],
724 fixed_size_binary_array.value(1)
725 );
726 assert_eq!(2, fixed_size_binary_array.len());
727 assert_eq!(0, fixed_size_binary_array.value_offset(0));
728 assert_eq!(5, fixed_size_binary_array.value_length());
729 assert_eq!(5, fixed_size_binary_array.value_offset(1));
730 }
731
732 #[test]
733 fn test_fixed_size_binary_array_from_fixed_size_list_array() {
734 let values = [0_u8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
735 let values_data = ArrayData::builder(DataType::UInt8)
736 .len(12)
737 .offset(2)
738 .add_buffer(Buffer::from_slice_ref(values))
739 .build()
740 .unwrap();
741 let array_data = unsafe {
743 ArrayData::builder(DataType::FixedSizeList(
744 Arc::new(Field::new_list_field(DataType::UInt8, false)),
745 4,
746 ))
747 .len(2)
748 .offset(1)
749 .add_child_data(values_data)
750 .null_bit_buffer(Some(Buffer::from_slice_ref([0b101])))
751 .build_unchecked()
752 };
753 let list_array = FixedSizeListArray::from(array_data);
754 let binary_array = FixedSizeBinaryArray::from(list_array);
755
756 assert_eq!(2, binary_array.len());
757 assert_eq!(1, binary_array.null_count());
758 assert!(binary_array.is_null(0));
759 assert!(binary_array.is_valid(1));
760 assert_eq!(&[10, 11, 12, 13], binary_array.value(1));
761 }
762
763 #[test]
764 #[should_panic(
765 expected = "FixedSizeBinaryArray can only be created from FixedSizeList<u8> arrays"
766 )]
767 #[cfg(not(feature = "force_validate"))]
770 fn test_fixed_size_binary_array_from_incorrect_fixed_size_list_array() {
771 let values: [u32; 12] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
772 let values_data = ArrayData::builder(DataType::UInt32)
773 .len(12)
774 .add_buffer(Buffer::from_slice_ref(values))
775 .build()
776 .unwrap();
777
778 let array_data = unsafe {
779 ArrayData::builder(DataType::FixedSizeList(
780 Arc::new(Field::new_list_field(DataType::Binary, false)),
781 4,
782 ))
783 .len(3)
784 .add_child_data(values_data)
785 .build_unchecked()
786 };
787 let list_array = FixedSizeListArray::from(array_data);
788 drop(FixedSizeBinaryArray::from(list_array));
789 }
790
791 #[test]
792 #[should_panic(expected = "The child array cannot contain null values.")]
793 fn test_fixed_size_binary_array_from_fixed_size_list_array_with_child_nulls_failed() {
794 let values = [0_u8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
795 let values_data = ArrayData::builder(DataType::UInt8)
796 .len(12)
797 .add_buffer(Buffer::from_slice_ref(values))
798 .null_bit_buffer(Some(Buffer::from_slice_ref([0b101010101010])))
799 .build()
800 .unwrap();
801
802 let array_data = unsafe {
803 ArrayData::builder(DataType::FixedSizeList(
804 Arc::new(Field::new_list_field(DataType::UInt8, false)),
805 4,
806 ))
807 .len(3)
808 .add_child_data(values_data)
809 .build_unchecked()
810 };
811 let list_array = FixedSizeListArray::from(array_data);
812 drop(FixedSizeBinaryArray::from(list_array));
813 }
814
815 #[test]
816 fn test_fixed_size_binary_array_fmt_debug() {
817 let values: [u8; 15] = *b"hellotherearrow";
818
819 let array_data = ArrayData::builder(DataType::FixedSizeBinary(5))
820 .len(3)
821 .add_buffer(Buffer::from(&values))
822 .build()
823 .unwrap();
824 let arr = FixedSizeBinaryArray::from(array_data);
825 assert_eq!(
826 "FixedSizeBinaryArray<5>\n[\n [104, 101, 108, 108, 111],\n [116, 104, 101, 114, 101],\n [97, 114, 114, 111, 119],\n]",
827 format!("{arr:?}")
828 );
829 }
830
831 #[test]
832 fn test_fixed_size_binary_array_from_iter() {
833 let input_arg = vec![vec![1, 2], vec![3, 4], vec![5, 6]];
834 let arr = FixedSizeBinaryArray::try_from_iter(input_arg.into_iter()).unwrap();
835
836 assert_eq!(2, arr.value_length());
837 assert_eq!(3, arr.len())
838 }
839
840 #[test]
841 fn test_all_none_fixed_size_binary_array_from_sparse_iter() {
842 let none_option: Option<[u8; 32]> = None;
843 let input_arg = vec![none_option, none_option, none_option];
844 #[allow(deprecated)]
845 let arr = FixedSizeBinaryArray::try_from_sparse_iter(input_arg.into_iter()).unwrap();
846 assert_eq!(0, arr.value_length());
847 assert_eq!(3, arr.len())
848 }
849
850 #[test]
851 fn test_fixed_size_binary_array_from_sparse_iter() {
852 let input_arg = vec![
853 None,
854 Some(vec![7, 8]),
855 Some(vec![9, 10]),
856 None,
857 Some(vec![13, 14]),
858 ];
859 #[allow(deprecated)]
860 let arr = FixedSizeBinaryArray::try_from_sparse_iter(input_arg.iter().cloned()).unwrap();
861 assert_eq!(2, arr.value_length());
862 assert_eq!(5, arr.len());
863
864 let arr =
865 FixedSizeBinaryArray::try_from_sparse_iter_with_size(input_arg.into_iter(), 2).unwrap();
866 assert_eq!(2, arr.value_length());
867 assert_eq!(5, arr.len());
868 }
869
870 #[test]
871 fn test_fixed_size_binary_array_from_sparse_iter_with_size_all_none() {
872 let input_arg = vec![None, None, None, None, None] as Vec<Option<Vec<u8>>>;
873
874 let arr = FixedSizeBinaryArray::try_from_sparse_iter_with_size(input_arg.into_iter(), 16)
875 .unwrap();
876 assert_eq!(16, arr.value_length());
877 assert_eq!(5, arr.len())
878 }
879
880 #[test]
881 fn test_fixed_size_binary_array_from_vec() {
882 let values = vec!["one".as_bytes(), b"two", b"six", b"ten"];
883 let array = FixedSizeBinaryArray::from(values);
884 assert_eq!(array.len(), 4);
885 assert_eq!(array.null_count(), 0);
886 assert_eq!(array.logical_null_count(), 0);
887 assert_eq!(array.value(0), b"one");
888 assert_eq!(array.value(1), b"two");
889 assert_eq!(array.value(2), b"six");
890 assert_eq!(array.value(3), b"ten");
891 assert!(!array.is_null(0));
892 assert!(!array.is_null(1));
893 assert!(!array.is_null(2));
894 assert!(!array.is_null(3));
895 }
896
897 #[test]
898 #[should_panic(expected = "Nested array size mismatch: one is 3, and the other is 5")]
899 fn test_fixed_size_binary_array_from_vec_incorrect_length() {
900 let values = vec!["one".as_bytes(), b"two", b"three", b"four"];
901 let _ = FixedSizeBinaryArray::from(values);
902 }
903
904 #[test]
905 fn test_fixed_size_binary_array_from_opt_vec() {
906 let values = vec![
907 Some("one".as_bytes()),
908 Some(b"two"),
909 None,
910 Some(b"six"),
911 Some(b"ten"),
912 ];
913 let array = FixedSizeBinaryArray::from(values);
914 assert_eq!(array.len(), 5);
915 assert_eq!(array.value(0), b"one");
916 assert_eq!(array.value(1), b"two");
917 assert_eq!(array.value(3), b"six");
918 assert_eq!(array.value(4), b"ten");
919 assert!(!array.is_null(0));
920 assert!(!array.is_null(1));
921 assert!(array.is_null(2));
922 assert!(!array.is_null(3));
923 assert!(!array.is_null(4));
924 }
925
926 #[test]
927 #[should_panic(expected = "Nested array size mismatch: one is 3, and the other is 5")]
928 fn test_fixed_size_binary_array_from_opt_vec_incorrect_length() {
929 let values = vec![
930 Some("one".as_bytes()),
931 Some(b"two"),
932 None,
933 Some(b"three"),
934 Some(b"four"),
935 ];
936 let _ = FixedSizeBinaryArray::from(values);
937 }
938
939 #[test]
940 fn fixed_size_binary_array_all_null() {
941 let data = vec![None] as Vec<Option<String>>;
942 let array =
943 FixedSizeBinaryArray::try_from_sparse_iter_with_size(data.into_iter(), 0).unwrap();
944 array
945 .into_data()
946 .validate_full()
947 .expect("All null array has valid array data");
948 }
949
950 #[test]
951 fn fixed_size_binary_array_all_null_in_batch_with_schema() {
953 let schema = Schema::new(vec![Field::new("a", DataType::FixedSizeBinary(2), true)]);
954
955 let none_option: Option<[u8; 2]> = None;
956 let item = FixedSizeBinaryArray::try_from_sparse_iter_with_size(
957 vec![none_option, none_option, none_option].into_iter(),
958 2,
959 )
960 .unwrap();
961
962 RecordBatch::try_new(Arc::new(schema), vec![Arc::new(item)]).unwrap();
964 }
965
966 #[test]
967 #[should_panic(
968 expected = "Trying to access an element at index 4 from a FixedSizeBinaryArray of length 3"
969 )]
970 fn test_fixed_size_binary_array_get_value_index_out_of_bound() {
971 let values = vec![Some("one".as_bytes()), Some(b"two"), None];
972 let array = FixedSizeBinaryArray::from(values);
973
974 array.value(4);
975 }
976
977 #[test]
978 fn test_constructors() {
979 let buffer = Buffer::from_vec(vec![0_u8; 10]);
980 let a = FixedSizeBinaryArray::new(2, buffer.clone(), None);
981 assert_eq!(a.len(), 5);
982
983 let nulls = NullBuffer::new_null(5);
984 FixedSizeBinaryArray::new(2, buffer.clone(), Some(nulls));
985
986 let a = FixedSizeBinaryArray::new(3, buffer.clone(), None);
987 assert_eq!(a.len(), 3);
988
989 let nulls = NullBuffer::new_null(3);
990 FixedSizeBinaryArray::new(3, buffer.clone(), Some(nulls));
991
992 let err = FixedSizeBinaryArray::try_new(-1, buffer.clone(), None).unwrap_err();
993
994 assert_eq!(
995 err.to_string(),
996 "Invalid argument error: Size cannot be negative, got -1"
997 );
998
999 let nulls = NullBuffer::new_null(3);
1000 let err = FixedSizeBinaryArray::try_new(2, buffer, Some(nulls)).unwrap_err();
1001 assert_eq!(
1002 err.to_string(),
1003 "Invalid argument error: Incorrect length of null buffer for FixedSizeBinaryArray, expected 5 got 3"
1004 );
1005 }
1006}