This is an automated email from the ASF dual-hosted git repository.

wjones127 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git


The following commit(s) were added to refs/heads/main by this push:
     new c7ba0cd2cb GH-34983: [C++] Preserve map values nullability on C Data 
Interface import (#35013)
c7ba0cd2cb is described below

commit c7ba0cd2cbdd89bce7d58edf573a9d3c16cf647d
Author: Will Jones <[email protected]>
AuthorDate: Mon Apr 10 18:40:00 2023 -0700

    GH-34983: [C++] Preserve map values nullability on C Data Interface import 
(#35013)
    
    ### Rationale for this change
    
    Map types with non-nullable values don't roundtrip right now through C Data 
interface, when they arguably should.
    
    I also found that field names don't roundtrip, but I think that might be a 
feature, not a bug. Therefore I added unit tests enforcing it for now.
    
    ### What changes are included in this PR?
    
    ### Are these changes tested?
    
    Yes, added various unit tests for export and roundtrip.
    
    ### Are there any user-facing changes?
    
    * Closes: #34983
    
    Authored-by: Will Jones <[email protected]>
    Signed-off-by: Will Jones <[email protected]>
---
 cpp/src/arrow/c/bridge.cc      |  8 +++++++-
 cpp/src/arrow/c/bridge_test.cc | 15 +++++++++++++++
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/cpp/src/arrow/c/bridge.cc b/cpp/src/arrow/c/bridge.cc
index d6ea60f520..e1dddbaf6a 100644
--- a/cpp/src/arrow/c/bridge.cc
+++ b/cpp/src/arrow/c/bridge.cc
@@ -1102,7 +1102,13 @@ struct SchemaImporter {
     }
 
     bool keys_sorted = (c_struct_->flags & ARROW_FLAG_MAP_KEYS_SORTED);
-    type_ = map(value_type->field(0)->type(), value_type->field(1)->type(), 
keys_sorted);
+    bool values_nullable = value_type->field(1)->nullable();
+    // Some implementations of Arrow (such as Rust) use a non-standard field 
name
+    // for key ("keys") and value ("values") fields. For simplicity, we 
override
+    // them on import.
+    auto values_field =
+        ::arrow::field("value", value_type->field(1)->type(), values_nullable);
+    type_ = map(value_type->field(0)->type(), values_field, keys_sorted);
     return Status::OK();
   }
 
diff --git a/cpp/src/arrow/c/bridge_test.cc b/cpp/src/arrow/c/bridge_test.cc
index 90fe9d5965..88fc2ed35a 100644
--- a/cpp/src/arrow/c/bridge_test.cc
+++ b/cpp/src/arrow/c/bridge_test.cc
@@ -417,6 +417,10 @@ TEST_F(TestSchemaExport, Map) {
       map(int8(), utf8(), /*keys_sorted=*/true), {"+m", "+s", "c", "u"},
       {"", "entries", "key", "value"},
       {ARROW_FLAG_NULLABLE | ARROW_FLAG_MAP_KEYS_SORTED, 0, 0, 
ARROW_FLAG_NULLABLE});
+
+  // Exports field names and nullability
+  TestNested(map(int8(), field("something", utf8(), false)), {"+m", "+s", "c", 
"u"},
+             {"", "entries", "key", "something"}, {ARROW_FLAG_NULLABLE, 0, 0, 
0});
 }
 
 TEST_F(TestSchemaExport, Union) {
@@ -2802,6 +2806,17 @@ TEST_F(TestSchemaRoundtrip, RegisteredExtension) {
 
 TEST_F(TestSchemaRoundtrip, Map) {
   TestWithTypeFactory([&]() { return map(utf8(), int32()); });
+  TestWithTypeFactory([&]() { return map(utf8(), field("value", int32(), 
false)); });
+  // Field names are brought in line with the spec on import.
+  TestWithTypeFactory(
+      [&]() {
+        return MapType::Make(field("some_entries",
+                                   struct_({field("some_key", utf8(), false),
+                                            field("some_value", int32())}),
+                                   false))
+            .ValueOrDie();
+      },
+      [&]() { return map(utf8(), int32()); });
   TestWithTypeFactory([&]() { return map(list(utf8()), int32()); });
   TestWithTypeFactory([&]() { return list(map(list(utf8()), int32())); });
 }

Reply via email to