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

Commit

Permalink
Fixed writing to unaligned pointers
Browse files Browse the repository at this point in the history
  • Loading branch information
jorgecarleitao committed Feb 21, 2022
1 parent 7f75aa8 commit c8182a4
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 9 deletions.
11 changes: 8 additions & 3 deletions arrow-pyarrow-integration-testing/src/c_stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand Down Expand Up @@ -31,15 +32,19 @@ pub fn to_rust_iterator(ob: PyObject, py: Python) -> PyResult<Vec<PyObject>> {
pub fn from_rust_iterator(py: Python) -> PyResult<PyObject> {
// 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);

// Arc it, since it will be shared with an external program
let array: Arc<dyn Array> = Arc::new(array.clone());

// create an iterator of arrays
//let arrays = vec![array.clone(), array.clone(), array];
let arrays: Vec<Arc<dyn Array>> = 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
Expand Down
8 changes: 5 additions & 3 deletions arrow-pyarrow-integration-testing/tests/test_c_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
4 changes: 2 additions & 2 deletions src/ffi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ pub use stream::{export_iterator, ArrowArrayStreamReader};
pub unsafe fn export_array_to_c(array: Arc<dyn Array>, 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.
Expand Down
3 changes: 2 additions & 1 deletion src/ffi/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down

0 comments on commit c8182a4

Please sign in to comment.