From 6aec84d757666cb4c8cb92de63ff6b611a596257 Mon Sep 17 00:00:00 2001 From: Ritchie Vink Date: Wed, 4 Jan 2023 14:04:55 +0100 Subject: [PATCH] fix(rust, python): deal with empty structs --- .../src/chunked_array/logical/struct_/mod.rs | 3 +++ .../src/chunked_array/ops/any_value.rs | 1 + polars/polars-lazy/src/tests/queries.rs | 21 ------------------- py-polars/tests/unit/test_struct.py | 12 +++++++++++ 4 files changed, 16 insertions(+), 21 deletions(-) diff --git a/polars/polars-core/src/chunked_array/logical/struct_/mod.rs b/polars/polars-core/src/chunked_array/logical/struct_/mod.rs index 8a56aa8b9798..eacba897fb96 100644 --- a/polars/polars-core/src/chunked_array/logical/struct_/mod.rs +++ b/polars/polars-core/src/chunked_array/logical/struct_/mod.rs @@ -79,6 +79,9 @@ impl StructChunked { } } Ok(Self::new_unchecked(name, &new_fields)) + } else if fields.is_empty() { + let fields = &[Series::full_null("", 1, &DataType::Null)]; + Ok(Self::new_unchecked(name, fields)) } else { Ok(Self::new_unchecked(name, fields)) } diff --git a/polars/polars-core/src/chunked_array/ops/any_value.rs b/polars/polars-core/src/chunked_array/ops/any_value.rs index 6a5d4375a8f2..27bd1b4e89ec 100644 --- a/polars/polars-core/src/chunked_array/ops/any_value.rs +++ b/polars/polars-core/src/chunked_array/ops/any_value.rs @@ -113,6 +113,7 @@ pub(crate) unsafe fn arr_to_any_value<'a>( let arr = &*(arr as *const dyn Array as *const FixedSizeBinaryArray); PolarsExtension::arr_to_av(arr, idx) } + DataType::Null => AnyValue::Null, dt => panic!("not implemented for {dt:?}"), } } diff --git a/polars/polars-lazy/src/tests/queries.rs b/polars/polars-lazy/src/tests/queries.rs index aa75f1e6ddfa..f3610547d4b2 100644 --- a/polars/polars-lazy/src/tests/queries.rs +++ b/polars/polars-lazy/src/tests/queries.rs @@ -2009,24 +2009,3 @@ fn test_partitioned_gb_ternary() -> PolarsResult<()> { Ok(()) } - -#[test] -fn test_foo() -> PolarsResult<()> { - let df = df![ - "a" => [2, 2], - "b" => [1, 2] - ]?; - - let out = df - .lazy() - .groupby([col("a")]) - .agg([ - (col("a").filter(col("b").eq(0)).diff(1, Default::default()) * lit(100)) - .diff(1, Default::default()) - .alias("foo"), - ]) - .collect(); - dbg!(out); - - Ok(()) -} diff --git a/py-polars/tests/unit/test_struct.py b/py-polars/tests/unit/test_struct.py index 3664a05db396..239edbaccdf7 100644 --- a/py-polars/tests/unit/test_struct.py +++ b/py-polars/tests/unit/test_struct.py @@ -718,3 +718,15 @@ def test_struct_categorical_5843() -> None: {"foo": "c", "counts": 1}, ] } + + +def test_struct_empty() -> None: + # List + df = pl.DataFrame({"a": [[{}]]}) + assert df.to_dict(False) == {"a": [[{"": None}]]} + # Struct one not empty + df = pl.DataFrame({"a": [[{}, {"a": 10}]]}) + assert df.to_dict(False) == {"a": [[{"a": None}, {"a": 10}]]} + # Empty struct + df = pl.DataFrame({"a": [{}]}) + assert df.to_dict(False) == {"a": [{"": None}]}