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