From a5035bd016ad89121bc528d547bfbc9e74880799 Mon Sep 17 00:00:00 2001 From: "Jorge C. Leitao" Date: Thu, 22 Jul 2021 18:33:24 +0000 Subject: [PATCH] Fixed nested FFI. --- .../tests/test_sql.py | 54 ++++++++++++++----- src/ffi/array.rs | 21 ++++++++ src/ffi/ffi.rs | 4 +- 3 files changed, 63 insertions(+), 16 deletions(-) diff --git a/arrow-pyarrow-integration-testing/tests/test_sql.py b/arrow-pyarrow-integration-testing/tests/test_sql.py index 2da732b746a..c3b6e7843a1 100644 --- a/arrow-pyarrow-integration-testing/tests/test_sql.py +++ b/arrow-pyarrow-integration-testing/tests/test_sql.py @@ -24,12 +24,17 @@ class TestCase(unittest.TestCase): def setUp(self): - self.old_allocated_rust = arrow_pyarrow_integration_testing.total_allocated_bytes() + self.old_allocated_rust = ( + arrow_pyarrow_integration_testing.total_allocated_bytes() + ) self.old_allocated_cpp = pyarrow.total_allocated_bytes() def tearDown(self): # No leak of Rust - self.assertEqual(self.old_allocated_rust, arrow_pyarrow_integration_testing.total_allocated_bytes()) + self.assertEqual( + self.old_allocated_rust, + arrow_pyarrow_integration_testing.total_allocated_bytes(), + ) # No leak of C++ memory self.assertEqual(self.old_allocated_cpp, pyarrow.total_allocated_bytes()) @@ -46,6 +51,7 @@ def test_primitive_rust(self): """ Rust -> Python -> Rust """ + def double(array): array = array.to_pylist() return pyarrow.array([x * 2 if x is not None else None for x in array]) @@ -102,9 +108,9 @@ def test_time32_python(self): """ Python -> Rust -> Python """ - a = pyarrow.array([None, 1, 2], pyarrow.time32('s')) + a = pyarrow.array([None, 1, 2], pyarrow.time32("s")) b = arrow_pyarrow_integration_testing.concatenate(a) - expected = pyarrow.array([None, 1, 2] + [None, 1, 2], pyarrow.time32('s')) + expected = pyarrow.array([None, 1, 2] + [None, 1, 2], pyarrow.time32("s")) self.assertEqual(b, expected) def test_list_array(self): @@ -112,7 +118,9 @@ def test_list_array(self): Python -> Rust -> Python """ for _ in range(2): - a = pyarrow.array([[], None, [1, 2], [4, 5, 6]], pyarrow.list_(pyarrow.int64())) + a = pyarrow.array( + [[], None, [1, 2], [4, 5, 6]], pyarrow.list_(pyarrow.int64()) + ) b = arrow_pyarrow_integration_testing.round_trip(a) b.validate(full=True) @@ -124,18 +132,36 @@ def test_struct_array(self): Python -> Rust -> Python """ fields = [ - ('f1', pyarrow.int32()), - ('f2', pyarrow.string()), + ("f1", pyarrow.int32()), + ("f2", pyarrow.string()), ] - a = pyarrow.array([ - {"f1": 1, "f2": "a"}, - None, - {"f1": 3, "f2": None}, - {"f1": None, "f2": "d"}, - {"f1": None, "f2": None}, - ], pyarrow.struct(fields)) + a = pyarrow.array( + [ + {"f1": 1, "f2": "a"}, + None, + {"f1": 3, "f2": None}, + {"f1": None, "f2": "d"}, + {"f1": None, "f2": None}, + ], + pyarrow.struct(fields), + ) b = arrow_pyarrow_integration_testing.round_trip(a) b.validate(full=True) assert a.to_pylist() == b.to_pylist() assert a.type == b.type + + def test_list_list_array(self): + """ + Python -> Rust -> Python + """ + for _ in range(2): + a = pyarrow.array( + [[None], None, [[1], [2]], [[4, 5], [6]]], + pyarrow.list_(pyarrow.list_(pyarrow.int64())), + ) + b = arrow_pyarrow_integration_testing.round_trip(a) + + b.validate(full=True) + assert a.to_pylist() == b.to_pylist() + assert a.type == b.type diff --git a/src/ffi/array.rs b/src/ffi/array.rs index 65f708cf2eb..3a74cc51872 100644 --- a/src/ffi/array.rs +++ b/src/ffi/array.rs @@ -168,4 +168,25 @@ mod tests { test_round_trip(array) } + + #[test] + fn test_list_list() -> Result<()> { + let data = vec![ + Some(vec![ + Some(vec![None]), + Some(vec![Some(2)]), + Some(vec![Some(3)]), + ]), + None, + Some(vec![Some(vec![Some(4), None, Some(6)])]), + ]; + + let mut array = + MutableListArray::>>::new(); + array.try_extend(data)?; + + let array: ListArray = array.into(); + + test_round_trip(array) + } } diff --git a/src/ffi/ffi.rs b/src/ffi/ffi.rs index 725dc42cbec..a6110af54d5 100644 --- a/src/ffi/ffi.rs +++ b/src/ffi/ffi.rs @@ -644,8 +644,8 @@ impl<'a> ArrowArrayRef for ArrowArrayChild<'a> { self.schema } - fn child(&self, _: usize) -> Result { - todo!() + fn child(&self, index: usize) -> Result { + create_child(self.array, self.schema, self.parent.clone(), index) } }