Skip to content
This repository has been archived by the owner on Feb 18, 2024. It is now read-only.

Commit

Permalink
Added support for NullArray at FFI. (#598)
Browse files Browse the repository at this point in the history
  • Loading branch information
jorgecarleitao authored Nov 12, 2021
1 parent 9c8c7b2 commit a667ad7
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 10 deletions.
11 changes: 11 additions & 0 deletions arrow-pyarrow-integration-testing/tests/test_sql.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,17 @@ def tearDown(self):
# No leak of C++ memory
self.assertEqual(self.old_allocated_cpp, pyarrow.total_allocated_bytes())

# see https://issues.apache.org/jira/browse/ARROW-14680
def _test_null(self):
"""
Python -> Rust -> Python
"""
a = pyarrow.array([None], type=pyarrow.null())
b = arrow_pyarrow_integration_testing.round_trip_array(a)
b.validate(full=True)
assert a.to_pylist() == b.to_pylist()
assert a.type == b.type

def test_primitive(self):
a = pyarrow.array([0, None, 2, 3, 4])
b = arrow_pyarrow_integration_testing.round_trip_array(a)
Expand Down
13 changes: 12 additions & 1 deletion src/array/null.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
use crate::{bitmap::Bitmap, datatypes::DataType};

use super::{ffi::ToFfi, Array};
use crate::{
array::{Array, FromFfi, ToFfi},
error::Result,
ffi,
};

/// The concrete [`Array`] of [`DataType::Null`].
#[derive(Debug, Clone)]
Expand Down Expand Up @@ -89,3 +93,10 @@ unsafe impl ToFfi for NullArray {
self.clone()
}
}

impl<A: ffi::ArrowArrayRef> FromFfi<A> for NullArray {
unsafe fn try_from_ffi(array: A) -> Result<Self> {
let data_type = array.field().data_type().clone();
Ok(Self::from_data(data_type, array.array().len()))
}
}
10 changes: 2 additions & 8 deletions src/ffi/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@
use super::ffi::ArrowArrayRef;
use crate::array::{BooleanArray, FromFfi};
use crate::error::{ArrowError, Result};
use crate::error::Result;
use crate::{array::*, datatypes::PhysicalType};

/// Reads a valid `ffi` interface into a `Box<dyn Array>`
/// # Errors
/// If and only if:
/// * the data type is not supported
/// * the interface is not valid (e.g. a null pointer)
pub unsafe fn try_from<A: ArrowArrayRef>(array: A) -> Result<Box<dyn Array>> {
use PhysicalType::*;
Ok(match array.field().data_type().to_physical_type() {
Null => Box::new(NullArray::try_from_ffi(array)?),
Boolean => Box::new(BooleanArray::try_from_ffi(array)?),
Primitive(primitive) => with_match_primitive_type!(primitive, |$T| {
Box::new(PrimitiveArray::<$T>::try_from_ffi(array)?)
Expand All @@ -33,11 +33,5 @@ pub unsafe fn try_from<A: ArrowArrayRef>(array: A) -> Result<Box<dyn Array>> {
}
Union => Box::new(UnionArray::try_from_ffi(array)?),
Map => Box::new(MapArray::try_from_ffi(array)?),
data_type => {
return Err(ArrowError::NotYetImplemented(format!(
"Importing PhysicalType \"{:?}\" is not yet supported.",
data_type
)))
}
})
}
10 changes: 9 additions & 1 deletion src/io/parquet/read/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub use parquet2::{
};

use crate::{
array::{Array, DictionaryKey, PrimitiveArray},
array::{Array, DictionaryKey, NullArray, PrimitiveArray},
datatypes::{DataType, IntervalUnit, TimeUnit},
error::{ArrowError, Result},
io::parquet::read::nested_utils::create_list,
Expand Down Expand Up @@ -234,6 +234,10 @@ pub fn page_iter_to_array<I: FallibleStreamingIterator<Item = DataPage, Error =
) -> Result<Box<dyn Array>> {
use DataType::*;
match data_type.to_logical_type() {
Null => Ok(Box::new(NullArray::from_data(
data_type,
metadata.num_values() as usize,
))),
// INT32
UInt8 => primitive::iter_to_array(iter, metadata, data_type, |x: i32| x as u8),
UInt16 => primitive::iter_to_array(iter, metadata, data_type, |x: i32| x as u16),
Expand Down Expand Up @@ -346,6 +350,10 @@ pub async fn page_stream_to_array<I: Stream<Item = std::result::Result<DataPage,
) -> Result<Box<dyn Array>> {
use DataType::*;
match data_type.to_logical_type() {
Null => Ok(Box::new(NullArray::from_data(
data_type,
metadata.num_values() as usize,
))),
// INT32
UInt8 => primitive::stream_to_array(pages, metadata, data_type, |x: i32| x as u8).await,
UInt16 => primitive::stream_to_array(pages, metadata, data_type, |x: i32| x as u16).await,
Expand Down

0 comments on commit a667ad7

Please sign in to comment.