This is an automated email from the ASF dual-hosted git repository.
tustvold pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git
The following commit(s) were added to refs/heads/master by this push:
new 58dc6118d Fix bugs in the `from_list` function. (#2277)
58dc6118d is described below
commit 58dc6118d0beccaf3607a2bdfc7c93130af4dd43
Author: Remzi Yang <[email protected]>
AuthorDate: Tue Aug 2 18:20:25 2022 +0800
Fix bugs in the `from_list` function. (#2277)
* update binary_from_list
Signed-off-by: remzi <[email protected]>
* fix binary from list
Signed-off-by: remzi <[email protected]>
* fix decimal from fixed list
Signed-off-by: remzi <[email protected]>
* fix fixed binary from fixed list
Signed-off-by: remzi <[email protected]>
* fix string from list
Signed-off-by: remzi <[email protected]>
* add child length check
Signed-off-by: remzi <[email protected]>
* clean the code
Signed-off-by: remzi <[email protected]>
---
arrow/src/array/array_binary.rs | 165 ++++++++++++++++++++---------
arrow/src/array/array_decimal.rs | 80 +++++++++++++-
arrow/src/array/array_fixed_size_binary.rs | 77 +++++++++++++-
arrow/src/array/array_string.rs | 157 ++++++++++++++++++++++++++-
4 files changed, 417 insertions(+), 62 deletions(-)
diff --git a/arrow/src/array/array_binary.rs b/arrow/src/array/array_binary.rs
index 5e0651078..3e49f6031 100644
--- a/arrow/src/array/array_binary.rs
+++ b/arrow/src/array/array_binary.rs
@@ -134,21 +134,35 @@ impl<OffsetSize: OffsetSizeTrait>
GenericBinaryArray<OffsetSize> {
fn from_list(v: GenericListArray<OffsetSize>) -> Self {
assert_eq!(
- v.data_ref().child_data()[0].child_data().len(),
+ v.data_ref().child_data().len(),
+ 1,
+ "BinaryArray can only be created from list array of u8 values \
+ (i.e. List<PrimitiveArray<u8>>)."
+ );
+ let child_data = &v.data_ref().child_data()[0];
+
+ assert_eq!(
+ child_data.child_data().len(),
0,
"BinaryArray can only be created from list array of u8 values \
(i.e. List<PrimitiveArray<u8>>)."
);
assert_eq!(
- v.data_ref().child_data()[0].data_type(),
+ child_data.data_type(),
&DataType::UInt8,
"BinaryArray can only be created from List<u8> arrays, mismatched
data types."
);
+ assert_eq!(
+ child_data.null_count(),
+ 0,
+ "The child array cannot contain null values."
+ );
let builder = ArrayData::builder(Self::get_data_type())
.len(v.len())
+ .offset(v.offset())
.add_buffer(v.data_ref().buffers()[0].clone())
- .add_buffer(v.data_ref().child_data()[0].buffers()[0].clone())
+ .add_buffer(child_data.buffers()[0].slice(child_data.offset()))
.null_bit_buffer(v.data_ref().null_buffer().cloned());
let data = unsafe { builder.build_unchecked() };
@@ -441,10 +455,7 @@ pub type LargeBinaryArray = GenericBinaryArray<i64>;
#[cfg(test)]
mod tests {
use super::*;
- use crate::{
- array::{LargeListArray, ListArray},
- datatypes::Field,
- };
+ use crate::{array::ListArray, datatypes::Field};
#[test]
fn test_binary_array() {
@@ -577,37 +588,38 @@ mod tests {
assert_eq!(7, binary_array.value_length(1));
}
- #[test]
- fn test_binary_array_from_list_array() {
- let values: [u8; 12] = [
- b'h', b'e', b'l', b'l', b'o', b'p', b'a', b'r', b'q', b'u', b'e',
b't',
- ];
- let values_data = ArrayData::builder(DataType::UInt8)
+ fn _test_generic_binary_array_from_list_array<O: OffsetSizeTrait>() {
+ let values = b"helloparquet";
+ let child_data = ArrayData::builder(DataType::UInt8)
.len(12)
.add_buffer(Buffer::from(&values[..]))
.build()
.unwrap();
- let offsets: [i32; 4] = [0, 5, 5, 12];
+ let offsets = [0, 5, 5, 12].map(|n| O::from_usize(n).unwrap());
// Array data: ["hello", "", "parquet"]
- let array_data1 = ArrayData::builder(DataType::Binary)
+ let array_data1 =
ArrayData::builder(GenericBinaryArray::<O>::get_data_type())
.len(3)
.add_buffer(Buffer::from_slice_ref(&offsets))
.add_buffer(Buffer::from_slice_ref(&values))
.build()
.unwrap();
- let binary_array1 = BinaryArray::from(array_data1);
+ let binary_array1 = GenericBinaryArray::<O>::from(array_data1);
+
+ let data_type = if O::IS_LARGE {
+ DataType::LargeList
+ } else {
+ DataType::List
+ }(Box::new(Field::new("item", DataType::UInt8, false)));
- let data_type =
- DataType::List(Box::new(Field::new("item", DataType::UInt8,
false)));
let array_data2 = ArrayData::builder(data_type)
.len(3)
.add_buffer(Buffer::from_slice_ref(&offsets))
- .add_child_data(values_data)
+ .add_child_data(child_data)
.build()
.unwrap();
- let list_array = ListArray::from(array_data2);
- let binary_array2 = BinaryArray::from(list_array);
+ let list_array = GenericListArray::<O>::from(array_data2);
+ let binary_array2 = GenericBinaryArray::<O>::from(list_array);
assert_eq!(2, binary_array2.data().buffers().len());
assert_eq!(0, binary_array2.data().child_data().len());
@@ -624,51 +636,102 @@ mod tests {
}
}
+ #[test]
+ fn test_binary_array_from_list_array() {
+ _test_generic_binary_array_from_list_array::<i32>();
+ }
+
#[test]
fn test_large_binary_array_from_list_array() {
- let values: [u8; 12] = [
- b'h', b'e', b'l', b'l', b'o', b'p', b'a', b'r', b'q', b'u', b'e',
b't',
- ];
- let values_data = ArrayData::builder(DataType::UInt8)
- .len(12)
+ _test_generic_binary_array_from_list_array::<i64>();
+ }
+
+ fn _test_generic_binary_array_from_list_array_with_offset<O:
OffsetSizeTrait>() {
+ let values = b"HelloArrowAndParquet";
+ // b"ArrowAndParquet"
+ let child_data = ArrayData::builder(DataType::UInt8)
+ .len(15)
+ .offset(5)
.add_buffer(Buffer::from(&values[..]))
.build()
.unwrap();
- let offsets: [i64; 4] = [0, 5, 5, 12];
- // Array data: ["hello", "", "parquet"]
- let array_data1 = ArrayData::builder(DataType::LargeBinary)
- .len(3)
+ let offsets = [0, 5, 8, 15].map(|n| O::from_usize(n).unwrap());
+ let null_buffer = Buffer::from_slice_ref(&[0b101]);
+ let data_type = if O::IS_LARGE {
+ DataType::LargeList
+ } else {
+ DataType::List
+ }(Box::new(Field::new("item", DataType::UInt8, false)));
+
+ // [None, Some(b"Parquet")]
+ let array_data = ArrayData::builder(data_type)
+ .len(2)
+ .offset(1)
.add_buffer(Buffer::from_slice_ref(&offsets))
- .add_buffer(Buffer::from_slice_ref(&values))
+ .null_bit_buffer(Some(null_buffer))
+ .add_child_data(child_data)
.build()
.unwrap();
- let binary_array1 = LargeBinaryArray::from(array_data1);
+ let list_array = GenericListArray::<O>::from(array_data);
+ let binary_array = GenericBinaryArray::<O>::from(list_array);
- let data_type =
- DataType::LargeList(Box::new(Field::new("item", DataType::UInt8,
false)));
- let array_data2 = ArrayData::builder(data_type)
- .len(3)
+ assert_eq!(2, binary_array.len());
+ assert_eq!(1, binary_array.null_count());
+ assert!(binary_array.is_null(0));
+ assert!(binary_array.is_valid(1));
+ assert_eq!(b"Parquet", binary_array.value(1));
+ }
+
+ #[test]
+ fn test_binary_array_from_list_array_with_offset() {
+ _test_generic_binary_array_from_list_array_with_offset::<i32>();
+ }
+
+ #[test]
+ fn test_large_binary_array_from_list_array_with_offset() {
+ _test_generic_binary_array_from_list_array_with_offset::<i64>();
+ }
+
+ fn _test_generic_binary_array_from_list_array_with_child_nulls_failed<
+ O: OffsetSizeTrait,
+ >() {
+ let values = b"HelloArrow";
+ let child_data = ArrayData::builder(DataType::UInt8)
+ .len(10)
+ .add_buffer(Buffer::from(&values[..]))
+ .null_bit_buffer(Some(Buffer::from_slice_ref(&[0b1010101010])))
+ .build()
+ .unwrap();
+
+ let offsets = [0, 5, 10].map(|n| O::from_usize(n).unwrap());
+ let data_type = if O::IS_LARGE {
+ DataType::LargeList
+ } else {
+ DataType::List
+ }(Box::new(Field::new("item", DataType::UInt8, false)));
+
+ // [None, Some(b"Parquet")]
+ let array_data = ArrayData::builder(data_type)
+ .len(2)
.add_buffer(Buffer::from_slice_ref(&offsets))
- .add_child_data(values_data)
+ .add_child_data(child_data)
.build()
.unwrap();
- let list_array = LargeListArray::from(array_data2);
- let binary_array2 = LargeBinaryArray::from(list_array);
+ let list_array = GenericListArray::<O>::from(array_data);
+ drop(GenericBinaryArray::<O>::from(list_array));
+ }
- assert_eq!(2, binary_array2.data().buffers().len());
- assert_eq!(0, binary_array2.data().child_data().len());
+ #[test]
+ #[should_panic(expected = "The child array cannot contain null values.")]
+ fn test_binary_array_from_list_array_with_child_nulls_failed() {
+
_test_generic_binary_array_from_list_array_with_child_nulls_failed::<i32>();
+ }
- assert_eq!(binary_array1.len(), binary_array2.len());
- assert_eq!(binary_array1.null_count(), binary_array2.null_count());
- assert_eq!(binary_array1.value_offsets(),
binary_array2.value_offsets());
- for i in 0..binary_array1.len() {
- assert_eq!(binary_array1.value(i), binary_array2.value(i));
- assert_eq!(binary_array1.value(i), unsafe {
- binary_array2.value_unchecked(i)
- });
- assert_eq!(binary_array1.value_length(i),
binary_array2.value_length(i));
- }
+ #[test]
+ #[should_panic(expected = "The child array cannot contain null values.")]
+ fn test_large_binary_array_from_list_array_with_child_nulls_failed() {
+
_test_generic_binary_array_from_list_array_with_child_nulls_failed::<i64>();
}
fn test_generic_binary_array_from_opt_vec<T: OffsetSizeTrait>() {
diff --git a/arrow/src/array/array_decimal.rs b/arrow/src/array/array_decimal.rs
index 5ce407b0b..186d0a2f6 100644
--- a/arrow/src/array/array_decimal.rs
+++ b/arrow/src/array/array_decimal.rs
@@ -187,24 +187,42 @@ pub trait BasicDecimalArray<T: BasicDecimal, U:
From<ArrayData>>:
/// Build a decimal array from [`FixedSizeListArray`].
///
/// NB: This function does not validate that each value is in the
permissible
- /// range for a decimal. And, the null buffer of the child array will be
ignored.
+ /// range for a decimal.
#[deprecated(note = "please use `from_fixed_size_binary_array` instead")]
fn from_fixed_size_list_array(
v: FixedSizeListArray,
precision: usize,
scale: usize,
) -> U {
+ assert_eq!(
+ v.data_ref().child_data().len(),
+ 1,
+ "DecimalArray can only be created from list array of u8 values \
+ (i.e. FixedSizeList<PrimitiveArray<u8>>)."
+ );
let child_data = &v.data_ref().child_data()[0];
+
assert_eq!(
child_data.child_data().len(),
0,
- "Decimal128Array can only be created from list array of u8 values \
+ "DecimalArray can only be created from list array of u8 values \
(i.e. FixedSizeList<PrimitiveArray<u8>>)."
);
assert_eq!(
child_data.data_type(),
&DataType::UInt8,
- "Decimal128Array can only be created from FixedSizeList<u8>
arrays, mismatched data types."
+ "DecimalArray can only be created from FixedSizeList<u8> arrays,
mismatched data types."
+ );
+ assert!(
+ v.value_length() == Self::VALUE_LENGTH,
+ "Value length of the array ({}) must equal to the byte width of
the decimal ({})",
+ v.value_length(),
+ Self::VALUE_LENGTH,
+ );
+ assert_eq!(
+ v.data_ref().child_data()[0].null_count(),
+ 0,
+ "The child array cannot contain null values."
);
let list_offset = v.offset();
@@ -841,6 +859,62 @@ mod tests {
assert_eq!(decimal.value_as_string(1), "56".to_string());
}
+ #[test]
+ #[allow(deprecated)]
+ #[should_panic(expected = "The child array cannot contain null values.")]
+ fn test_decimal_array_from_fixed_size_list_with_child_nulls_failed() {
+ let value_data = ArrayData::builder(DataType::UInt8)
+ .len(16)
+ .add_buffer(Buffer::from_slice_ref(&[12_i128]))
+
.null_bit_buffer(Some(Buffer::from_slice_ref(&[0b1010101010101010])))
+ .build()
+ .unwrap();
+
+ // Construct a list array from the above two
+ let list_data_type = DataType::FixedSizeList(
+ Box::new(Field::new("item", DataType::UInt8, false)),
+ 16,
+ );
+ let list_data = ArrayData::builder(list_data_type)
+ .len(1)
+ .add_child_data(value_data)
+ .build()
+ .unwrap();
+ let list_array = FixedSizeListArray::from(list_data);
+ drop(Decimal128Array::from_fixed_size_list_array(
+ list_array, 38, 0,
+ ));
+ }
+
+ #[test]
+ #[allow(deprecated)]
+ #[should_panic(
+ expected = "Value length of the array (8) must equal to the byte width
of the decimal (16)"
+ )]
+ fn test_decimal_array_from_fixed_size_list_with_wrong_length() {
+ let value_data = ArrayData::builder(DataType::UInt8)
+ .len(16)
+ .add_buffer(Buffer::from_slice_ref(&[12_i128]))
+
.null_bit_buffer(Some(Buffer::from_slice_ref(&[0b1010101010101010])))
+ .build()
+ .unwrap();
+
+ // Construct a list array from the above two
+ let list_data_type = DataType::FixedSizeList(
+ Box::new(Field::new("item", DataType::UInt8, false)),
+ 8,
+ );
+ let list_data = ArrayData::builder(list_data_type)
+ .len(2)
+ .add_child_data(value_data)
+ .build()
+ .unwrap();
+ let list_array = FixedSizeListArray::from(list_data);
+ drop(Decimal128Array::from_fixed_size_list_array(
+ list_array, 38, 0,
+ ));
+ }
+
#[test]
fn test_decimal256_iter() {
let mut builder = Decimal256Builder::new(30, 76, 6);
diff --git a/arrow/src/array/array_fixed_size_binary.rs
b/arrow/src/array/array_fixed_size_binary.rs
index e851fd392..a811917c7 100644
--- a/arrow/src/array/array_fixed_size_binary.rs
+++ b/arrow/src/array/array_fixed_size_binary.rs
@@ -291,20 +291,34 @@ impl From<FixedSizeBinaryArray> for ArrayData {
impl From<FixedSizeListArray> for FixedSizeBinaryArray {
fn from(v: FixedSizeListArray) -> Self {
assert_eq!(
- v.data_ref().child_data()[0].child_data().len(),
+ v.data_ref().child_data().len(),
+ 1,
+ "FixedSizeBinaryArray can only be created from list array of u8
values \
+ (i.e. FixedSizeList<PrimitiveArray<u8>>)."
+ );
+ let child_data = &v.data_ref().child_data()[0];
+
+ assert_eq!(
+ child_data.child_data().len(),
0,
"FixedSizeBinaryArray can only be created from list array of u8
values \
(i.e. FixedSizeList<PrimitiveArray<u8>>)."
);
assert_eq!(
- v.data_ref().child_data()[0].data_type(),
+ child_data.data_type(),
&DataType::UInt8,
"FixedSizeBinaryArray can only be created from FixedSizeList<u8>
arrays, mismatched data types."
);
+ assert_eq!(
+ child_data.null_count(),
+ 0,
+ "The child array cannot contain null values."
+ );
let builder =
ArrayData::builder(DataType::FixedSizeBinary(v.value_length()))
.len(v.len())
- .add_buffer(v.data_ref().child_data()[0].buffers()[0].clone())
+ .offset(v.offset())
+ .add_buffer(child_data.buffers()[0].slice(child_data.offset()))
.null_bit_buffer(v.data_ref().null_buffer().cloned());
let data = unsafe { builder.build_unchecked() };
@@ -412,6 +426,37 @@ mod tests {
assert_eq!(10, fixed_size_binary_array.value_offset(1));
}
+ #[test]
+ fn test_fixed_size_binary_array_from_fixed_size_list_array() {
+ let values = [0_u8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
+ let values_data = ArrayData::builder(DataType::UInt8)
+ .len(12)
+ .offset(2)
+ .add_buffer(Buffer::from_slice_ref(&values))
+ .build()
+ .unwrap();
+ // [null, [10, 11, 12, 13]]
+ let array_data = unsafe {
+ ArrayData::builder(DataType::FixedSizeList(
+ Box::new(Field::new("item", DataType::UInt8, false)),
+ 4,
+ ))
+ .len(2)
+ .offset(1)
+ .add_child_data(values_data)
+ .null_bit_buffer(Some(Buffer::from_slice_ref(&[0b101])))
+ .build_unchecked()
+ };
+ let list_array = FixedSizeListArray::from(array_data);
+ let binary_array = FixedSizeBinaryArray::from(list_array);
+
+ assert_eq!(2, binary_array.len());
+ assert_eq!(1, binary_array.null_count());
+ assert!(binary_array.is_null(0));
+ assert!(binary_array.is_valid(1));
+ assert_eq!(&[10, 11, 12, 13], binary_array.value(1));
+ }
+
#[test]
#[should_panic(
expected = "FixedSizeBinaryArray can only be created from
FixedSizeList<u8> arrays"
@@ -419,7 +464,7 @@ mod tests {
// Different error messages, so skip for now
// https://github.com/apache/arrow-rs/issues/1545
#[cfg(not(feature = "force_validate"))]
- fn test_fixed_size_binary_array_from_incorrect_list_array() {
+ fn test_fixed_size_binary_array_from_incorrect_fixed_size_list_array() {
let values: [u32; 12] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
let values_data = ArrayData::builder(DataType::UInt32)
.len(12)
@@ -440,6 +485,30 @@ mod tests {
drop(FixedSizeBinaryArray::from(list_array));
}
+ #[test]
+ #[should_panic(expected = "The child array cannot contain null values.")]
+ fn
test_fixed_size_binary_array_from_fixed_size_list_array_with_child_nulls_failed()
{
+ let values = [0_u8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
+ let values_data = ArrayData::builder(DataType::UInt8)
+ .len(12)
+ .add_buffer(Buffer::from_slice_ref(&values))
+ .null_bit_buffer(Some(Buffer::from_slice_ref(&[0b101010101010])))
+ .build()
+ .unwrap();
+
+ let array_data = unsafe {
+ ArrayData::builder(DataType::FixedSizeList(
+ Box::new(Field::new("item", DataType::UInt8, false)),
+ 4,
+ ))
+ .len(3)
+ .add_child_data(values_data)
+ .build_unchecked()
+ };
+ let list_array = FixedSizeListArray::from(array_data);
+ drop(FixedSizeBinaryArray::from(list_array));
+ }
+
#[test]
fn test_fixed_size_binary_array_fmt_debug() {
let values: [u8; 15] = *b"hellotherearrow";
diff --git a/arrow/src/array/array_string.rs b/arrow/src/array/array_string.rs
index 12a6b2f98..c332aa197 100644
--- a/arrow/src/array/array_string.rs
+++ b/arrow/src/array/array_string.rs
@@ -119,23 +119,40 @@ impl<OffsetSize: OffsetSizeTrait>
GenericStringArray<OffsetSize> {
unsafe { self.value_unchecked(i) }
}
+ /// Convert a list array to a string array.
+ /// This method is unsound because it does
+ /// not check the utf-8 validation for each element.
fn from_list(v: GenericListArray<OffsetSize>) -> Self {
assert_eq!(
- v.data().child_data()[0].child_data().len(),
+ v.data_ref().child_data().len(),
+ 1,
+ "StringArray can only be created from list array of u8 values \
+ (i.e. List<PrimitiveArray<u8>>)."
+ );
+ let child_data = &v.data_ref().child_data()[0];
+
+ assert_eq!(
+ child_data.child_data().len(),
0,
"StringArray can only be created from list array of u8 values \
(i.e. List<PrimitiveArray<u8>>)."
);
assert_eq!(
- v.data().child_data()[0].data_type(),
+ child_data.data_type(),
&DataType::UInt8,
"StringArray can only be created from List<u8> arrays, mismatched
data types."
);
+ assert_eq!(
+ child_data.null_count(),
+ 0,
+ "The child array cannot contain null values."
+ );
let builder = ArrayData::builder(Self::get_data_type())
.len(v.len())
+ .offset(v.offset())
.add_buffer(v.data().buffers()[0].clone())
- .add_buffer(v.data().child_data()[0].buffers()[0].clone())
+ .add_buffer(child_data.buffers()[0].slice(child_data.offset()))
.null_bit_buffer(v.data().null_buffer().cloned());
let array_data = unsafe { builder.build_unchecked() };
@@ -409,7 +426,10 @@ pub type LargeStringArray = GenericStringArray<i64>;
#[cfg(test)]
mod tests {
- use crate::array::{ListBuilder, StringBuilder};
+ use crate::{
+ array::{ListBuilder, StringBuilder},
+ datatypes::Field,
+ };
use super::*;
@@ -675,4 +695,133 @@ mod tests {
LargeStringArray::from_iter_values(BadIterator::new(3, 1,
data.clone()));
assert_eq!(expected, arr);
}
+
+ fn _test_generic_string_array_from_list_array<O: OffsetSizeTrait>() {
+ let values = b"HelloArrowAndParquet";
+ // "ArrowAndParquet"
+ let child_data = ArrayData::builder(DataType::UInt8)
+ .len(15)
+ .offset(5)
+ .add_buffer(Buffer::from(&values[..]))
+ .build()
+ .unwrap();
+
+ let offsets = [0, 5, 8, 15].map(|n| O::from_usize(n).unwrap());
+ let null_buffer = Buffer::from_slice_ref(&[0b101]);
+ let data_type = if O::IS_LARGE {
+ DataType::LargeList
+ } else {
+ DataType::List
+ }(Box::new(Field::new("item", DataType::UInt8, false)));
+
+ // [None, Some("Parquet")]
+ let array_data = ArrayData::builder(data_type)
+ .len(2)
+ .offset(1)
+ .add_buffer(Buffer::from_slice_ref(&offsets))
+ .null_bit_buffer(Some(null_buffer))
+ .add_child_data(child_data)
+ .build()
+ .unwrap();
+ let list_array = GenericListArray::<O>::from(array_data);
+ let string_array = GenericStringArray::<O>::from(list_array);
+
+ assert_eq!(2, string_array.len());
+ assert_eq!(1, string_array.null_count());
+ assert!(string_array.is_null(0));
+ assert!(string_array.is_valid(1));
+ assert_eq!("Parquet", string_array.value(1));
+ }
+
+ #[test]
+ fn test_string_array_from_list_array() {
+ _test_generic_string_array_from_list_array::<i32>();
+ }
+
+ #[test]
+ fn test_large_string_array_from_list_array() {
+ _test_generic_string_array_from_list_array::<i64>();
+ }
+
+ fn _test_generic_string_array_from_list_array_with_child_nulls_failed<
+ O: OffsetSizeTrait,
+ >() {
+ let values = b"HelloArrow";
+ let child_data = ArrayData::builder(DataType::UInt8)
+ .len(10)
+ .add_buffer(Buffer::from(&values[..]))
+ .null_bit_buffer(Some(Buffer::from_slice_ref(&[0b1010101010])))
+ .build()
+ .unwrap();
+
+ let offsets = [0, 5, 10].map(|n| O::from_usize(n).unwrap());
+ let data_type = if O::IS_LARGE {
+ DataType::LargeList
+ } else {
+ DataType::List
+ }(Box::new(Field::new("item", DataType::UInt8, false)));
+
+ // [None, Some(b"Parquet")]
+ let array_data = ArrayData::builder(data_type)
+ .len(2)
+ .add_buffer(Buffer::from_slice_ref(&offsets))
+ .add_child_data(child_data)
+ .build()
+ .unwrap();
+ let list_array = GenericListArray::<O>::from(array_data);
+ drop(GenericStringArray::<O>::from(list_array));
+ }
+
+ #[test]
+ #[should_panic(expected = "The child array cannot contain null values.")]
+ fn test_stirng_array_from_list_array_with_child_nulls_failed() {
+
_test_generic_string_array_from_list_array_with_child_nulls_failed::<i32>();
+ }
+
+ #[test]
+ #[should_panic(expected = "The child array cannot contain null values.")]
+ fn test_large_string_array_from_list_array_with_child_nulls_failed() {
+
_test_generic_string_array_from_list_array_with_child_nulls_failed::<i64>();
+ }
+
+ fn _test_generic_string_array_from_list_array_wrong_type<O:
OffsetSizeTrait>() {
+ let values = b"HelloArrow";
+ let child_data = ArrayData::builder(DataType::UInt16)
+ .len(5)
+ .add_buffer(Buffer::from(&values[..]))
+ .build()
+ .unwrap();
+
+ let offsets = [0, 2, 3].map(|n| O::from_usize(n).unwrap());
+ let data_type = if O::IS_LARGE {
+ DataType::LargeList
+ } else {
+ DataType::List
+ }(Box::new(Field::new("item", DataType::UInt16, false)));
+
+ let array_data = ArrayData::builder(data_type)
+ .len(2)
+ .add_buffer(Buffer::from_slice_ref(&offsets))
+ .add_child_data(child_data)
+ .build()
+ .unwrap();
+ let list_array = GenericListArray::<O>::from(array_data);
+ drop(GenericStringArray::<O>::from(list_array));
+ }
+
+ #[test]
+ #[should_panic(
+ expected = "StringArray can only be created from List<u8> arrays,
mismatched data types."
+ )]
+ fn test_string_array_from_list_array_wrong_type() {
+ _test_generic_string_array_from_list_array_wrong_type::<i32>();
+ }
+
+ #[test]
+ #[should_panic(
+ expected = "StringArray can only be created from List<u8> arrays,
mismatched data types."
+ )]
+ fn test_large_string_array_from_list_array_wrong_type() {
+ _test_generic_string_array_from_list_array_wrong_type::<i32>();
+ }
}