1use crate::builder::ArrayBuilder;
19use crate::types::{ByteArrayType, GenericBinaryType, GenericStringType};
20use crate::{Array, ArrayRef, GenericByteArray, OffsetSizeTrait};
21use arrow_buffer::{ArrowNativeType, Buffer, MutableBuffer, NullBufferBuilder, ScalarBuffer};
22use arrow_data::ArrayDataBuilder;
23use arrow_schema::ArrowError;
24use std::any::Any;
25use std::sync::Arc;
26
27pub struct GenericByteBuilder<T: ByteArrayType> {
32 value_builder: Vec<u8>,
33 offsets_builder: Vec<T::Offset>,
34 null_buffer_builder: NullBufferBuilder,
35}
36
37impl<T: ByteArrayType> GenericByteBuilder<T> {
38 pub fn new() -> Self {
40 Self::with_capacity(1024, 1024)
41 }
42
43 pub fn with_capacity(item_capacity: usize, data_capacity: usize) -> Self {
50 let mut offsets_builder = Vec::with_capacity(item_capacity + 1);
51 offsets_builder.push(T::Offset::from_usize(0).unwrap());
52 Self {
53 value_builder: Vec::with_capacity(data_capacity),
54 offsets_builder,
55 null_buffer_builder: NullBufferBuilder::new(item_capacity),
56 }
57 }
58
59 pub unsafe fn new_from_buffer(
69 offsets_buffer: MutableBuffer,
70 mut value_buffer: MutableBuffer,
71 null_buffer: Option<MutableBuffer>,
72 ) -> Self {
73 let offsets_builder: Vec<T::Offset> =
74 ScalarBuffer::<T::Offset>::from(offsets_buffer).into();
75
76 value_buffer.truncate(offsets_builder.last().unwrap().as_usize());
79 let value_builder: Vec<u8> = ScalarBuffer::<u8>::from(value_buffer).into();
80
81 let null_buffer_builder = null_buffer
82 .map(|buffer| NullBufferBuilder::new_from_buffer(buffer, offsets_builder.len() - 1))
83 .unwrap_or_else(|| NullBufferBuilder::new_with_len(offsets_builder.len() - 1));
84
85 Self {
86 offsets_builder,
87 value_builder,
88 null_buffer_builder,
89 }
90 }
91
92 #[inline]
93 fn next_offset(&self) -> T::Offset {
94 T::Offset::from_usize(self.value_builder.len()).expect("byte array offset overflow")
95 }
96
97 #[inline]
113 pub fn append_value(&mut self, value: impl AsRef<T::Native>) {
114 self.value_builder
115 .extend_from_slice(value.as_ref().as_ref());
116 self.null_buffer_builder.append(true);
117 self.offsets_builder.push(self.next_offset());
118 }
119
120 #[inline]
127 pub fn append_option(&mut self, value: Option<impl AsRef<T::Native>>) {
128 match value {
129 None => self.append_null(),
130 Some(v) => self.append_value(v),
131 };
132 }
133
134 #[inline]
136 pub fn append_null(&mut self) {
137 self.null_buffer_builder.append(false);
138 self.offsets_builder.push(self.next_offset());
139 }
140
141 #[inline]
143 pub fn append_nulls(&mut self, n: usize) {
144 self.null_buffer_builder.append_n_nulls(n);
145 let next_offset = self.next_offset();
146 self.offsets_builder
147 .extend(std::iter::repeat_n(next_offset, n));
148 }
149
150 #[inline]
153 pub fn append_array(&mut self, array: &GenericByteArray<T>) -> Result<(), ArrowError> {
154 use num_traits::CheckedAdd;
155 if array.len() == 0 {
156 return Ok(());
157 }
158
159 let offsets = array.offsets();
160
161 if self.next_offset() == offsets[0] {
164 self.offsets_builder.extend_from_slice(&offsets[1..]);
165 } else {
166 let shift: T::Offset = self.next_offset() - offsets[0];
168
169 if shift.checked_add(&offsets[offsets.len() - 1]).is_none() {
170 return Err(ArrowError::OffsetOverflowError(
171 shift.as_usize() + offsets[offsets.len() - 1].as_usize(),
172 ));
173 }
174
175 self.offsets_builder
176 .extend(offsets[1..].iter().map(|&offset| offset + shift));
177 }
178
179 self.value_builder.extend_from_slice(
181 &array.values().as_slice()[offsets[0].as_usize()..offsets[array.len()].as_usize()],
182 );
183
184 if let Some(null_buffer) = array.nulls() {
185 self.null_buffer_builder.append_buffer(null_buffer);
186 } else {
187 self.null_buffer_builder.append_n_non_nulls(array.len());
188 }
189 Ok(())
190 }
191
192 pub fn finish(&mut self) -> GenericByteArray<T> {
194 let array_type = T::DATA_TYPE;
195 let array_builder = ArrayDataBuilder::new(array_type)
196 .len(self.len())
197 .add_buffer(std::mem::take(&mut self.offsets_builder).into())
198 .add_buffer(std::mem::take(&mut self.value_builder).into())
199 .nulls(self.null_buffer_builder.finish());
200
201 self.offsets_builder.push(self.next_offset());
202 let array_data = unsafe { array_builder.build_unchecked() };
203 GenericByteArray::from(array_data)
204 }
205
206 pub fn finish_cloned(&self) -> GenericByteArray<T> {
208 let array_type = T::DATA_TYPE;
209 let offset_buffer = Buffer::from_slice_ref(self.offsets_builder.as_slice());
210 let value_buffer = Buffer::from_slice_ref(self.value_builder.as_slice());
211 let array_builder = ArrayDataBuilder::new(array_type)
212 .len(self.len())
213 .add_buffer(offset_buffer)
214 .add_buffer(value_buffer)
215 .nulls(self.null_buffer_builder.finish_cloned());
216
217 let array_data = unsafe { array_builder.build_unchecked() };
218 GenericByteArray::from(array_data)
219 }
220
221 pub fn values_slice(&self) -> &[u8] {
223 self.value_builder.as_slice()
224 }
225
226 pub fn offsets_slice(&self) -> &[T::Offset] {
228 self.offsets_builder.as_slice()
229 }
230
231 pub fn validity_slice(&self) -> Option<&[u8]> {
233 self.null_buffer_builder.as_slice()
234 }
235
236 pub fn validity_slice_mut(&mut self) -> Option<&mut [u8]> {
238 self.null_buffer_builder.as_slice_mut()
239 }
240}
241
242impl<T: ByteArrayType> std::fmt::Debug for GenericByteBuilder<T> {
243 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
244 write!(f, "{}{}Builder", T::Offset::PREFIX, T::PREFIX)?;
245 f.debug_struct("")
246 .field("value_builder", &self.value_builder)
247 .field("offsets_builder", &self.offsets_builder)
248 .field("null_buffer_builder", &self.null_buffer_builder)
249 .finish()
250 }
251}
252
253impl<T: ByteArrayType> Default for GenericByteBuilder<T> {
254 fn default() -> Self {
255 Self::new()
256 }
257}
258
259impl<T: ByteArrayType> ArrayBuilder for GenericByteBuilder<T> {
260 fn len(&self) -> usize {
262 self.null_buffer_builder.len()
263 }
264
265 fn finish(&mut self) -> ArrayRef {
267 Arc::new(self.finish())
268 }
269
270 fn finish_cloned(&self) -> ArrayRef {
272 Arc::new(self.finish_cloned())
273 }
274
275 fn as_any(&self) -> &dyn Any {
277 self
278 }
279
280 fn as_any_mut(&mut self) -> &mut dyn Any {
282 self
283 }
284
285 fn into_box_any(self: Box<Self>) -> Box<dyn Any> {
287 self
288 }
289}
290
291impl<T: ByteArrayType, V: AsRef<T::Native>> Extend<Option<V>> for GenericByteBuilder<T> {
292 #[inline]
293 fn extend<I: IntoIterator<Item = Option<V>>>(&mut self, iter: I) {
294 for v in iter {
295 self.append_option(v)
296 }
297 }
298}
299
300pub type GenericStringBuilder<O> = GenericByteBuilder<GenericStringType<O>>;
350
351impl<O: OffsetSizeTrait> std::fmt::Write for GenericStringBuilder<O> {
352 fn write_str(&mut self, s: &str) -> std::fmt::Result {
353 self.value_builder.extend_from_slice(s.as_bytes());
354 Ok(())
355 }
356}
357
358const AVERAGE_STRING_LENGTH: usize = 16;
369pub trait StringLikeArrayBuilder: ArrayBuilder {
374 fn type_name() -> &'static str;
376
377 fn with_capacity(capacity: usize) -> Self;
379
380 fn append_value(&mut self, value: &str);
382
383 fn append_null(&mut self);
385}
386
387impl<O: OffsetSizeTrait> StringLikeArrayBuilder for GenericStringBuilder<O> {
388 fn type_name() -> &'static str {
389 std::any::type_name::<Self>()
390 }
391 fn with_capacity(capacity: usize) -> Self {
392 Self::with_capacity(capacity, capacity * AVERAGE_STRING_LENGTH)
393 }
394 fn append_value(&mut self, value: &str) {
395 Self::append_value(self, value);
396 }
397 fn append_null(&mut self) {
398 Self::append_null(self);
399 }
400}
401
402const AVERAGE_BINARY_LENGTH: usize = 128;
413pub trait BinaryLikeArrayBuilder: ArrayBuilder {
418 fn type_name() -> &'static str;
420
421 fn with_capacity(capacity: usize) -> Self;
423
424 fn append_value(&mut self, value: &[u8]);
426
427 fn append_null(&mut self);
429}
430
431impl<O: OffsetSizeTrait> BinaryLikeArrayBuilder for GenericBinaryBuilder<O> {
432 fn type_name() -> &'static str {
433 std::any::type_name::<Self>()
434 }
435 fn with_capacity(capacity: usize) -> Self {
436 Self::with_capacity(capacity, capacity * AVERAGE_BINARY_LENGTH)
437 }
438 fn append_value(&mut self, value: &[u8]) {
439 Self::append_value(self, value);
440 }
441 fn append_null(&mut self) {
442 Self::append_null(self);
443 }
444}
445
446pub type GenericBinaryBuilder<O> = GenericByteBuilder<GenericBinaryType<O>>;
492
493impl<O: OffsetSizeTrait> std::io::Write for GenericBinaryBuilder<O> {
494 fn write(&mut self, bs: &[u8]) -> std::io::Result<usize> {
495 self.value_builder.extend_from_slice(bs);
496 Ok(bs.len())
497 }
498
499 fn flush(&mut self) -> std::io::Result<()> {
500 Ok(())
501 }
502}
503
504#[cfg(test)]
505mod tests {
506 use super::*;
507 use crate::GenericStringArray;
508 use crate::array::Array;
509 use arrow_buffer::NullBuffer;
510 use std::fmt::Write as _;
511 use std::io::Write as _;
512
513 fn _test_generic_binary_builder<O: OffsetSizeTrait>() {
514 let mut builder = GenericBinaryBuilder::<O>::new();
515
516 builder.append_value(b"hello");
517 builder.append_value(b"");
518 builder.append_null();
519 builder.append_value(b"rust");
520
521 let array = builder.finish();
522
523 assert_eq!(4, array.len());
524 assert_eq!(1, array.null_count());
525 assert_eq!(b"hello", array.value(0));
526 assert_eq!([] as [u8; 0], array.value(1));
527 assert!(array.is_null(2));
528 assert_eq!(b"rust", array.value(3));
529 assert_eq!(O::from_usize(5).unwrap(), array.value_offsets()[2]);
530 assert_eq!(O::from_usize(4).unwrap(), array.value_length(3));
531 }
532
533 #[test]
534 fn test_binary_builder() {
535 _test_generic_binary_builder::<i32>()
536 }
537
538 #[test]
539 fn test_large_binary_builder() {
540 _test_generic_binary_builder::<i64>()
541 }
542
543 fn _test_generic_binary_builder_all_nulls<O: OffsetSizeTrait>() {
544 let mut builder = GenericBinaryBuilder::<O>::new();
545 builder.append_null();
546 builder.append_null();
547 builder.append_null();
548 builder.append_nulls(2);
549 assert_eq!(5, builder.len());
550 assert!(!builder.is_empty());
551
552 let array = builder.finish();
553 assert_eq!(5, array.null_count());
554 assert_eq!(5, array.len());
555 assert!(array.is_null(0));
556 assert!(array.is_null(1));
557 assert!(array.is_null(2));
558 assert!(array.is_null(3));
559 assert!(array.is_null(4));
560 }
561
562 #[test]
563 fn test_binary_builder_all_nulls() {
564 _test_generic_binary_builder_all_nulls::<i32>()
565 }
566
567 #[test]
568 fn test_large_binary_builder_all_nulls() {
569 _test_generic_binary_builder_all_nulls::<i64>()
570 }
571
572 fn _test_generic_binary_builder_reset<O: OffsetSizeTrait>() {
573 let mut builder = GenericBinaryBuilder::<O>::new();
574
575 builder.append_value(b"hello");
576 builder.append_value(b"");
577 builder.append_null();
578 builder.append_value(b"rust");
579 builder.finish();
580
581 assert!(builder.is_empty());
582
583 builder.append_value(b"parquet");
584 builder.append_null();
585 builder.append_value(b"arrow");
586 builder.append_value(b"");
587 builder.append_nulls(2);
588 builder.append_value(b"hi");
589 let array = builder.finish();
590
591 assert_eq!(7, array.len());
592 assert_eq!(3, array.null_count());
593 assert_eq!(b"parquet", array.value(0));
594 assert!(array.is_null(1));
595 assert!(array.is_null(4));
596 assert!(array.is_null(5));
597 assert_eq!(b"arrow", array.value(2));
598 assert_eq!(b"", array.value(1));
599 assert_eq!(b"hi", array.value(6));
600
601 assert_eq!(O::zero(), array.value_offsets()[0]);
602 assert_eq!(O::from_usize(7).unwrap(), array.value_offsets()[2]);
603 assert_eq!(O::from_usize(14).unwrap(), array.value_offsets()[7]);
604 assert_eq!(O::from_usize(5).unwrap(), array.value_length(2));
605 }
606
607 #[test]
608 fn test_binary_builder_reset() {
609 _test_generic_binary_builder_reset::<i32>()
610 }
611
612 #[test]
613 fn test_large_binary_builder_reset() {
614 _test_generic_binary_builder_reset::<i64>()
615 }
616
617 fn _test_generic_string_array_builder<O: OffsetSizeTrait>() {
618 let mut builder = GenericStringBuilder::<O>::new();
619 let owned = "arrow".to_owned();
620
621 builder.append_value("hello");
622 builder.append_value("");
623 builder.append_value(&owned);
624 builder.append_null();
625 builder.append_option(Some("rust"));
626 builder.append_option(None::<&str>);
627 builder.append_option(None::<String>);
628 builder.append_nulls(2);
629 builder.append_value("parquet");
630 assert_eq!(10, builder.len());
631
632 assert_eq!(
633 GenericStringArray::<O>::from(vec![
634 Some("hello"),
635 Some(""),
636 Some("arrow"),
637 None,
638 Some("rust"),
639 None,
640 None,
641 None,
642 None,
643 Some("parquet")
644 ]),
645 builder.finish()
646 );
647 }
648
649 #[test]
650 fn test_string_array_builder() {
651 _test_generic_string_array_builder::<i32>()
652 }
653
654 #[test]
655 fn test_large_string_array_builder() {
656 _test_generic_string_array_builder::<i64>()
657 }
658
659 fn _test_generic_string_array_builder_finish<O: OffsetSizeTrait>() {
660 let mut builder = GenericStringBuilder::<O>::with_capacity(3, 11);
661
662 builder.append_value("hello");
663 builder.append_value("rust");
664 builder.append_null();
665
666 builder.finish();
667 assert!(builder.is_empty());
668 assert_eq!(&[O::zero()], builder.offsets_slice());
669
670 builder.append_value("arrow");
671 builder.append_value("parquet");
672 let arr = builder.finish();
673 assert!(arr.nulls().is_none());
675 assert_eq!(GenericStringArray::<O>::from(vec!["arrow", "parquet"]), arr,)
676 }
677
678 #[test]
679 fn test_string_array_builder_finish() {
680 _test_generic_string_array_builder_finish::<i32>()
681 }
682
683 #[test]
684 fn test_large_string_array_builder_finish() {
685 _test_generic_string_array_builder_finish::<i64>()
686 }
687
688 fn _test_generic_string_array_builder_finish_cloned<O: OffsetSizeTrait>() {
689 let mut builder = GenericStringBuilder::<O>::with_capacity(3, 11);
690
691 builder.append_value("hello");
692 builder.append_value("rust");
693 builder.append_null();
694
695 let mut arr = builder.finish_cloned();
696 assert!(!builder.is_empty());
697 assert_eq!(3, arr.len());
698
699 builder.append_value("arrow");
700 builder.append_value("parquet");
701 arr = builder.finish();
702
703 assert!(arr.nulls().is_some());
704 assert_eq!(&[O::zero()], builder.offsets_slice());
705 assert_eq!(5, arr.len());
706 }
707
708 #[test]
709 fn test_string_array_builder_finish_cloned() {
710 _test_generic_string_array_builder_finish_cloned::<i32>()
711 }
712
713 #[test]
714 fn test_large_string_array_builder_finish_cloned() {
715 _test_generic_string_array_builder_finish_cloned::<i64>()
716 }
717
718 #[test]
719 fn test_extend() {
720 let mut builder = GenericStringBuilder::<i32>::new();
721 builder.extend(["a", "b", "c", "", "a", "b", "c"].into_iter().map(Some));
722 builder.extend(["d", "cupcakes", "hello"].into_iter().map(Some));
723 let array = builder.finish();
724 assert_eq!(array.value_offsets(), &[0, 1, 2, 3, 3, 4, 5, 6, 7, 15, 20]);
725 assert_eq!(array.value_data(), b"abcabcdcupcakeshello");
726 }
727
728 #[test]
729 fn test_write_str() {
730 let mut builder = GenericStringBuilder::<i32>::new();
731 write!(builder, "foo").unwrap();
732 builder.append_value("");
733 writeln!(builder, "bar").unwrap();
734 builder.append_value("");
735 write!(builder, "fiz").unwrap();
736 write!(builder, "buz").unwrap();
737 builder.append_value("");
738 let a = builder.finish();
739 let r: Vec<_> = a.iter().flatten().collect();
740 assert_eq!(r, &["foo", "bar\n", "fizbuz"])
741 }
742
743 #[test]
744 fn test_write_bytes() {
745 let mut builder = GenericBinaryBuilder::<i32>::new();
746 write!(builder, "foo").unwrap();
747 builder.append_value("");
748 writeln!(builder, "bar").unwrap();
749 builder.append_value("");
750 write!(builder, "fiz").unwrap();
751 write!(builder, "buz").unwrap();
752 builder.append_value("");
753 let a = builder.finish();
754 let r: Vec<_> = a.iter().flatten().collect();
755 assert_eq!(
756 r,
757 &["foo".as_bytes(), "bar\n".as_bytes(), "fizbuz".as_bytes()]
758 )
759 }
760
761 #[test]
762 fn test_append_array_without_nulls() {
763 let input = vec![
764 "hello", "world", "how", "are", "you", "doing", "today", "I", "am", "doing", "well",
765 "thank", "you", "for", "asking",
766 ];
767 let arr1 = GenericStringArray::<i32>::from(input[..3].to_vec());
768 let arr2 = GenericStringArray::<i32>::from(input[3..7].to_vec());
769 let arr3 = GenericStringArray::<i32>::from(input[7..].to_vec());
770
771 let mut builder = GenericStringBuilder::<i32>::new();
772 builder.append_array(&arr1).unwrap();
773 builder.append_array(&arr2).unwrap();
774 builder.append_array(&arr3).unwrap();
775
776 let actual = builder.finish();
777 let expected = GenericStringArray::<i32>::from(input);
778
779 assert_eq!(actual, expected);
780 }
781
782 #[test]
783 fn test_append_array_with_nulls() {
784 let input = vec![
785 Some("hello"),
786 None,
787 Some("how"),
788 None,
789 None,
790 None,
791 None,
792 Some("I"),
793 Some("am"),
794 Some("doing"),
795 Some("well"),
796 ];
797 let arr1 = GenericStringArray::<i32>::from(input[..3].to_vec());
798 let arr2 = GenericStringArray::<i32>::from(input[3..7].to_vec());
799 let arr3 = GenericStringArray::<i32>::from(input[7..].to_vec());
800
801 let mut builder = GenericStringBuilder::<i32>::new();
802 builder.append_array(&arr1).unwrap();
803 builder.append_array(&arr2).unwrap();
804 builder.append_array(&arr3).unwrap();
805
806 let actual = builder.finish();
807 let expected = GenericStringArray::<i32>::from(input);
808
809 assert_eq!(actual, expected);
810 }
811
812 #[test]
813 fn test_append_empty_array() {
814 let arr = GenericStringArray::<i32>::from(Vec::<&str>::new());
815 let mut builder = GenericStringBuilder::<i32>::new();
816 builder.append_array(&arr).unwrap();
817 let result = builder.finish();
818 assert_eq!(result.len(), 0);
819 }
820
821 #[test]
822 fn test_append_array_with_offset_not_starting_at_0() {
823 let input = vec![
824 Some("hello"),
825 None,
826 Some("how"),
827 None,
828 None,
829 None,
830 None,
831 Some("I"),
832 Some("am"),
833 Some("doing"),
834 Some("well"),
835 ];
836 let full_array = GenericStringArray::<i32>::from(input);
837 let sliced = full_array.slice(1, 4);
838
839 assert_ne!(sliced.offsets()[0].as_usize(), 0);
840 assert_ne!(sliced.offsets().last(), full_array.offsets().last());
841
842 let mut builder = GenericStringBuilder::<i32>::new();
843 builder.append_array(&sliced).unwrap();
844 let actual = builder.finish();
845
846 let expected = GenericStringArray::<i32>::from(vec![None, Some("how"), None, None]);
847
848 assert_eq!(actual, expected);
849 }
850
851 #[test]
852 fn test_append_underlying_null_values_added_as_is() {
853 let input_1_array_with_nulls = {
854 let input = vec![
855 "hello", "world", "how", "are", "you", "doing", "today", "I", "am",
856 ];
857 let (offsets, buffer, _) = GenericStringArray::<i32>::from(input).into_parts();
858
859 GenericStringArray::<i32>::new(
860 offsets,
861 buffer,
862 Some(NullBuffer::from(&[
863 true, false, true, false, false, true, true, true, false,
864 ])),
865 )
866 };
867 let input_2_array_with_nulls = {
868 let input = vec!["doing", "well", "thank", "you", "for", "asking"];
869 let (offsets, buffer, _) = GenericStringArray::<i32>::from(input).into_parts();
870
871 GenericStringArray::<i32>::new(
872 offsets,
873 buffer,
874 Some(NullBuffer::from(&[false, false, true, false, true, true])),
875 )
876 };
877
878 let mut builder = GenericStringBuilder::<i32>::new();
879 builder.append_array(&input_1_array_with_nulls).unwrap();
880 builder.append_array(&input_2_array_with_nulls).unwrap();
881
882 let actual = builder.finish();
883 let expected = GenericStringArray::<i32>::from(vec![
884 Some("hello"),
885 None, Some("how"),
887 None, None, Some("doing"),
890 Some("today"),
891 Some("I"),
892 None, None, None, Some("thank"),
896 None, Some("for"),
898 Some("asking"),
899 ]);
900
901 assert_eq!(actual, expected);
902
903 let expected_underlying_buffer = Buffer::from(
904 [
905 "hello", "world", "how", "are", "you", "doing", "today", "I", "am", "doing",
906 "well", "thank", "you", "for", "asking",
907 ]
908 .join("")
909 .as_bytes(),
910 );
911 assert_eq!(actual.values(), &expected_underlying_buffer);
912 }
913
914 #[test]
915 fn append_array_with_continues_indices() {
916 let input = vec![
917 "hello", "world", "how", "are", "you", "doing", "today", "I", "am", "doing", "well",
918 "thank", "you", "for", "asking",
919 ];
920 let full_array = GenericStringArray::<i32>::from(input);
921 let slice1 = full_array.slice(0, 3);
922 let slice2 = full_array.slice(3, 4);
923 let slice3 = full_array.slice(7, full_array.len() - 7);
924
925 let mut builder = GenericStringBuilder::<i32>::new();
926 builder.append_array(&slice1).unwrap();
927 builder.append_array(&slice2).unwrap();
928 builder.append_array(&slice3).unwrap();
929
930 let actual = builder.finish();
931
932 assert_eq!(actual, full_array);
933 }
934
935 #[test]
936 fn test_append_array_offset_overflow_precise() {
937 let mut builder = GenericStringBuilder::<i32>::new();
938
939 let initial_string = "x".repeat(i32::MAX as usize - 100);
940 builder.append_value(&initial_string);
941
942 let overflow_string = "y".repeat(200);
943 let overflow_array = GenericStringArray::<i32>::from(vec![overflow_string.as_str()]);
944
945 let result = builder.append_array(&overflow_array);
946
947 assert!(matches!(result, Err(ArrowError::OffsetOverflowError(_))));
948 }
949}