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

kou 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 a64e58313a GH-48382: [Ruby] Add support for reading struct array 
(#48383)
a64e58313a is described below

commit a64e58313ac2354b8a888036523cf90bdb11e634
Author: Sutou Kouhei <[email protected]>
AuthorDate: Mon Dec 8 06:16:40 2025 +0900

    GH-48382: [Ruby] Add support for reading struct array (#48383)
    
    ### Rationale for this change
    
    It's a nested array.
    
    ### What changes are included in this PR?
    
    * Add `ArrowFormat::StructType`
    * Add `ArrowFormat::StructArray`
    
    ### Are these changes tested?
    
    Yes.
    
    ### Are there any user-facing changes?
    
    Yes.
    
    * GitHub Issue: #48382
    
    Authored-by: Sutou Kouhei <[email protected]>
    Signed-off-by: Sutou Kouhei <[email protected]>
---
 ruby/red-arrow-format/lib/arrow-format/array.rb     | 17 +++++++++++++++++
 .../lib/arrow-format/file-reader.rb                 |  9 +++++++++
 ruby/red-arrow-format/lib/arrow-format/type.rb      | 12 ++++++++++++
 ruby/red-arrow-format/test/test-file-reader.rb      | 21 +++++++++++++++++++++
 4 files changed, 59 insertions(+)

diff --git a/ruby/red-arrow-format/lib/arrow-format/array.rb 
b/ruby/red-arrow-format/lib/arrow-format/array.rb
index 41a553bcd9..c5b636dc75 100644
--- a/ruby/red-arrow-format/lib/arrow-format/array.rb
+++ b/ruby/red-arrow-format/lib/arrow-format/array.rb
@@ -180,4 +180,21 @@ module ArrowFormat
       apply_validity(values)
     end
   end
+
+  class StructArray < Array
+    def initialize(type, size, validity_buffer, children)
+      super(type, size, validity_buffer)
+      @children = children
+    end
+
+    def to_a
+      if @children.empty?
+        values = [[]] * @size
+      else
+        children_values = @children.collect(&:to_a)
+        values = children_values[0].zip(*children_values[1..-1])
+      end
+      apply_validity(values)
+    end
+  end
 end
diff --git a/ruby/red-arrow-format/lib/arrow-format/file-reader.rb 
b/ruby/red-arrow-format/lib/arrow-format/file-reader.rb
index 72c5c9bca8..79ea86cd33 100644
--- a/ruby/red-arrow-format/lib/arrow-format/file-reader.rb
+++ b/ruby/red-arrow-format/lib/arrow-format/file-reader.rb
@@ -33,6 +33,7 @@ require_relative "org/apache/arrow/flatbuf/message"
 require_relative "org/apache/arrow/flatbuf/null"
 require_relative "org/apache/arrow/flatbuf/precision"
 require_relative "org/apache/arrow/flatbuf/schema"
+require_relative "org/apache/arrow/flatbuf/struct_"
 require_relative "org/apache/arrow/flatbuf/utf8"
 
 module ArrowFormat
@@ -159,6 +160,9 @@ module ArrowFormat
         end
       when Org::Apache::Arrow::Flatbuf::List
         type = ListType.new(read_field(fb_field.children[0]))
+      when Org::Apache::Arrow::Flatbuf::Struct
+        children = fb_field.children.collect {|child| read_field(child)}
+        type = StructType.new(children)
       when Org::Apache::Arrow::Flatbuf::Binary
         type = BinaryType.singleton
       when Org::Apache::Arrow::Flatbuf::LargeBinary
@@ -200,6 +204,11 @@ module ArrowFormat
         offsets = body.slice(offsets_buffer.offset, offsets_buffer.length)
         child = read_column(field.type.child, nodes, buffers, body)
         field.type.build_array(length, validity, offsets, child)
+      when StructType
+        children = field.type.children.collect do |child|
+          read_column(child, nodes, buffers, body)
+        end
+        field.type.build_array(length, validity, children)
       when VariableSizeBinaryType
         offsets_buffer = buffers.shift
         values_buffer = buffers.shift
diff --git a/ruby/red-arrow-format/lib/arrow-format/type.rb 
b/ruby/red-arrow-format/lib/arrow-format/type.rb
index c7cebcd745..179a89ff4c 100644
--- a/ruby/red-arrow-format/lib/arrow-format/type.rb
+++ b/ruby/red-arrow-format/lib/arrow-format/type.rb
@@ -206,4 +206,16 @@ module ArrowFormat
       ListArray.new(self, size, validity_buffer, offsets_buffer, child)
     end
   end
+
+  class StructType < Type
+    attr_reader :children
+    def initialize(children)
+      super("Struct")
+      @children = children
+    end
+
+    def build_array(size, validity_buffer, children)
+      StructArray.new(self, size, validity_buffer, children)
+    end
+  end
 end
diff --git a/ruby/red-arrow-format/test/test-file-reader.rb 
b/ruby/red-arrow-format/test/test-file-reader.rb
index b39d7b1fff..48c20d1f3f 100644
--- a/ruby/red-arrow-format/test/test-file-reader.rb
+++ b/ruby/red-arrow-format/test/test-file-reader.rb
@@ -139,4 +139,25 @@ class TestFileReader < Test::Unit::TestCase
                    read)
     end
   end
+
+  sub_test_case("Struct") do
+    def build_array
+      data_type = Arrow::StructDataType.new(count: :int8,
+                                            visible: :boolean)
+      Arrow::StructArray.new(data_type, [[-128, nil], nil, [nil, true]])
+    end
+
+    def test_read
+      assert_equal([
+                     {
+                       "value" => [
+                         [-128, nil],
+                         nil,
+                         [nil, true],
+                       ],
+                     },
+                   ],
+                   read)
+    end
+  end
 end

Reply via email to