diff --git a/arrow-pyarrow-integration-testing/src/c_stream.rs b/arrow-pyarrow-integration-testing/src/c_stream.rs index a61f86ae3e7..efdf224c1c6 100644 --- a/arrow-pyarrow-integration-testing/src/c_stream.rs +++ b/arrow-pyarrow-integration-testing/src/c_stream.rs @@ -3,7 +3,8 @@ use pyo3::ffi::Py_uintptr_t; use pyo3::prelude::*; -use arrow2::array::Int32Array; +use arrow2::array::{Int32Array, StructArray}; +use arrow2::datatypes::DataType; use arrow2::ffi; use super::*; @@ -31,6 +32,11 @@ pub fn to_rust_iterator(ob: PyObject, py: Python) -> PyResult> { pub fn from_rust_iterator(py: Python) -> PyResult { // initialize an array let array = Int32Array::from(&[Some(2), None, Some(1), None]); + let array = StructArray::from_data( + DataType::Struct(vec![Field::new("a", array.data_type().clone(), true)]), + vec![Arc::new(array)], + None, + ); // and a field with its datatype let field = Field::new("a", array.data_type().clone(), true); @@ -38,8 +44,7 @@ pub fn from_rust_iterator(py: Python) -> PyResult { let array: Arc = Arc::new(array.clone()); // create an iterator of arrays - //let arrays = vec![array.clone(), array.clone(), array]; - let arrays: Vec> = vec![]; + let arrays = vec![array.clone(), array.clone(), array]; let iter = Box::new(arrays.clone().into_iter().map(Ok)) as _; // create an [`ArrowArrayStream`] based on this iterator and field diff --git a/arrow-pyarrow-integration-testing/tests/test_c_stream.py b/arrow-pyarrow-integration-testing/tests/test_c_stream.py index 9073ae2c213..74f3c6f7209 100644 --- a/arrow-pyarrow-integration-testing/tests/test_c_stream.py +++ b/arrow-pyarrow-integration-testing/tests/test_c_stream.py @@ -18,10 +18,12 @@ def test_rust_reads(self): array = arrays[0].field(0) assert array == a - # see https://issues.apache.org/jira/browse/ARROW-15747 - def _test_pyarrow_reads(self): + def test_pyarrow_reads(self): stream = arrow_pyarrow_integration_testing.from_rust_iterator() arrays = [a for a in stream] - assert False + expected = pyarrow.RecordBatch.from_arrays([pyarrow.array([2, None, 1, None], pyarrow.int32())], names=["a"]) + expected = [expected, expected, expected] + + self.assertEqual(arrays, expected) diff --git a/src/ffi/mod.rs b/src/ffi/mod.rs index 4678b567dd5..f3d689b7f8c 100644 --- a/src/ffi/mod.rs +++ b/src/ffi/mod.rs @@ -26,14 +26,14 @@ pub use stream::{export_iterator, ArrowArrayStreamReader}; pub unsafe fn export_array_to_c(array: Arc, ptr: *mut ArrowArray) { let array = bridge::align_to_c_data_interface(array); - *ptr = ArrowArray::new(array); + std::ptr::write_unaligned(ptr, ArrowArray::new(array)); } /// Exports a [`Field`] to the C data interface. /// # Safety /// The pointer `ptr` must be allocated and valid pub unsafe fn export_field_to_c(field: &Field, ptr: *mut ArrowSchema) { - *ptr = ArrowSchema::new(field) + std::ptr::write_unaligned(ptr, ArrowSchema::new(field)); } /// Imports a [`Field`] from the C data interface. diff --git a/src/ffi/stream.rs b/src/ffi/stream.rs index f1ccb7f3034..6a316a6847c 100644 --- a/src/ffi/stream.rs +++ b/src/ffi/stream.rs @@ -159,7 +159,8 @@ unsafe extern "C" fn get_next(iter: *mut ArrowArrayStream, array: *mut ArrowArra 2001 // custom application specific error (since this is never a result of this interface) } None => { - *array = ArrowArray::empty(); + let a = ArrowArray::empty(); + std::ptr::write_unaligned(array, a); private.error = None; 0 }