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 1cac811744 GH-49406: [Ruby] Add support for fixed size list array 
(#49407)
1cac811744 is described below

commit 1cac811744c74aa2a6e02f8c5b8c89797c324f52
Author: Sutou Kouhei <[email protected]>
AuthorDate: Sun Mar 1 15:08:45 2026 +0900

    GH-49406: [Ruby] Add support for fixed size list array (#49407)
    
    ### Rationale for this change
    
    It's a fixed size variant of list array.
    
    ### What changes are included in this PR?
    
    * Add `ArrowFormat::FixedSizeListType`
    * Add `ArrowFormat::FixedSizeListArray`
    
    ### Are these changes tested?
    
    Yes.
    
    ### Are there any user-facing changes?
    
    Yes.
    * GitHub Issue: #49406
    
    Authored-by: Sutou Kouhei <[email protected]>
    Signed-off-by: Sutou Kouhei <[email protected]>
---
 ruby/red-arrow-format/lib/arrow-format/array.rb    | 26 ++++++++++++++++++++
 .../lib/arrow-format/buffer-alignable.rb           |  2 +-
 .../{flat-buffers.rb => flatbuffers.rb}            |  1 +
 ruby/red-arrow-format/lib/arrow-format/readable.rb |  8 ++++++-
 ruby/red-arrow-format/lib/arrow-format/type.rb     | 28 ++++++++++++++++++++++
 ruby/red-arrow-format/test/test-reader.rb          | 20 ++++++++++++++++
 ruby/red-arrow-format/test/test-writer.rb          | 23 ++++++++++++++++++
 7 files changed, 106 insertions(+), 2 deletions(-)

diff --git a/ruby/red-arrow-format/lib/arrow-format/array.rb 
b/ruby/red-arrow-format/lib/arrow-format/array.rb
index 5bc7588f3a..951de74475 100644
--- a/ruby/red-arrow-format/lib/arrow-format/array.rb
+++ b/ruby/red-arrow-format/lib/arrow-format/array.rb
@@ -480,6 +480,32 @@ module ArrowFormat
   class LargeListArray < VariableSizeListArray
   end
 
+  class FixedSizeListArray < Array
+    attr_reader :child
+    def initialize(type, size, validity_buffer, child)
+      super(type, size, validity_buffer)
+      @child = child
+    end
+
+    def each_buffer(&block)
+      return to_enum(__method__) unless block_given?
+
+      yield(slice_bitmap_buffer(:validity, @validity_buffer))
+    end
+
+    def to_a
+      values = @child.to_a.each_slice(@type.size).to_a
+      apply_validity(values)
+    end
+
+    private
+    def slice!(offset, size)
+      super
+      @child = @child.slice(@type.size * @offset,
+                            @type.size * (@offset + @size + 1))
+    end
+  end
+
   class StructArray < Array
     attr_reader :children
     def initialize(type, size, validity_buffer, children)
diff --git a/ruby/red-arrow-format/lib/arrow-format/buffer-alignable.rb 
b/ruby/red-arrow-format/lib/arrow-format/buffer-alignable.rb
index 1ed806d715..b0cd37cd9a 100644
--- a/ruby/red-arrow-format/lib/arrow-format/buffer-alignable.rb
+++ b/ruby/red-arrow-format/lib/arrow-format/buffer-alignable.rb
@@ -15,7 +15,7 @@
 # specific language governing permissions and limitations
 # under the License.
 
-require_relative "flat-buffers"
+require_relative "flatbuffers"
 
 module ArrowFormat
   module BufferAlignable
diff --git a/ruby/red-arrow-format/lib/arrow-format/flat-buffers.rb 
b/ruby/red-arrow-format/lib/arrow-format/flatbuffers.rb
similarity index 97%
rename from ruby/red-arrow-format/lib/arrow-format/flat-buffers.rb
rename to ruby/red-arrow-format/lib/arrow-format/flatbuffers.rb
index 8b33d8a18e..913ae9b536 100644
--- a/ruby/red-arrow-format/lib/arrow-format/flat-buffers.rb
+++ b/ruby/red-arrow-format/lib/arrow-format/flatbuffers.rb
@@ -25,6 +25,7 @@ require_relative 
"org/apache/arrow/flatbuf/dictionary_encoding"
 require_relative "org/apache/arrow/flatbuf/dictionary_batch"
 require_relative "org/apache/arrow/flatbuf/duration"
 require_relative "org/apache/arrow/flatbuf/fixed_size_binary"
+require_relative "org/apache/arrow/flatbuf/fixed_size_list"
 require_relative "org/apache/arrow/flatbuf/floating_point"
 require_relative "org/apache/arrow/flatbuf/footer"
 require_relative "org/apache/arrow/flatbuf/int"
diff --git a/ruby/red-arrow-format/lib/arrow-format/readable.rb 
b/ruby/red-arrow-format/lib/arrow-format/readable.rb
index b0e65317ad..c5c1d5d2b3 100644
--- a/ruby/red-arrow-format/lib/arrow-format/readable.rb
+++ b/ruby/red-arrow-format/lib/arrow-format/readable.rb
@@ -17,7 +17,7 @@
 
 require_relative "array"
 require_relative "field"
-require_relative "flat-buffers"
+require_relative "flatbuffers"
 require_relative "record-batch"
 require_relative "schema"
 require_relative "type"
@@ -101,6 +101,9 @@ module ArrowFormat
         type = ListType.new(read_field(fb_field.children[0]))
       when FB::LargeList
         type = LargeListType.new(read_field(fb_field.children[0]))
+      when FB::FixedSizeList
+        type = FixedSizeListType.new(read_field(fb_field.children[0]),
+                                     fb_type.list_size)
       when FB::Struct
         children = fb_field.children.collect {|child| read_field(child)}
         type = StructType.new(children)
@@ -223,6 +226,9 @@ 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 FixedSizeListType
+        child = read_column(field.type.child, nodes, buffers, body)
+        field.type.build_array(length, validity, child)
       when StructType
         children = field.type.children.collect do |child|
           read_column(child, nodes, buffers, body)
diff --git a/ruby/red-arrow-format/lib/arrow-format/type.rb 
b/ruby/red-arrow-format/lib/arrow-format/type.rb
index 3c2d5f3ac9..fb153450b0 100644
--- a/ruby/red-arrow-format/lib/arrow-format/type.rb
+++ b/ruby/red-arrow-format/lib/arrow-format/type.rb
@@ -856,6 +856,34 @@ module ArrowFormat
     end
   end
 
+  class FixedSizeListType < Type
+    attr_reader :child
+    attr_reader :size
+    def initialize(child, size)
+      super()
+      @child = child
+      @size = size
+    end
+
+    def name
+      "FixedSizeList"
+    end
+
+    def to_s
+      "#{super}<#{child.name}: #{child.type}>(#{@size})"
+    end
+
+    def build_array(size, validity_buffer, child)
+      FixedSizeListArray.new(self, size, validity_buffer, child)
+    end
+
+    def to_flatbuffers
+      fb_type = FB::FixedSizeList::Data.new
+      fb_type.list_size = @size
+      fb_type
+    end
+  end
+
   class StructType < Type
     attr_reader :children
     def initialize(children)
diff --git a/ruby/red-arrow-format/test/test-reader.rb 
b/ruby/red-arrow-format/test/test-reader.rb
index 9d54ab987f..06360f62ac 100644
--- a/ruby/red-arrow-format/test/test-reader.rb
+++ b/ruby/red-arrow-format/test/test-reader.rb
@@ -561,6 +561,26 @@ module ReaderTests
                  [type.to_s, values])
   end
 
+  def test_fixed_size_list
+    data_type = Arrow::FixedSizeListDataType.new({
+                                                   name: "count",
+                                                   type: :int8,
+                                                 },
+                                                 2)
+    array = Arrow::FixedSizeListArray.new(data_type,
+                                          [[-128, 127], nil, [-1, 1]])
+    type, values = roundtrip(array)
+    assert_equal([
+                   "FixedSizeList<count: Int8>(2)",
+                   [
+                     [-128, 127],
+                     nil,
+                     [-1, 1],
+                   ],
+                 ],
+                 [type.to_s, values])
+  end
+
   def test_struct
     data_type = Arrow::StructDataType.new(count: :int8,
                                           visible: :boolean)
diff --git a/ruby/red-arrow-format/test/test-writer.rb 
b/ruby/red-arrow-format/test/test-writer.rb
index 629543a58b..f36a1a252e 100644
--- a/ruby/red-arrow-format/test/test-writer.rb
+++ b/ruby/red-arrow-format/test/test-writer.rb
@@ -91,6 +91,9 @@ module WriterHelper
       ArrowFormat::ListType.new(convert_field(red_arrow_type.field))
     when Arrow::LargeListDataType
       ArrowFormat::LargeListType.new(convert_field(red_arrow_type.field))
+    when Arrow::FixedSizeListDataType
+      ArrowFormat::FixedSizeListType.new(convert_field(red_arrow_type.field),
+                                         red_arrow_type.list_size)
     when Arrow::StructDataType
       fields = red_arrow_type.fields.collect do |field|
         convert_field(field)
@@ -161,6 +164,10 @@ module WriterHelper
                        convert_buffer(red_arrow_array.null_bitmap),
                        convert_buffer(red_arrow_array.value_offsets_buffer),
                        convert_array(red_arrow_array.values_raw))
+    when ArrowFormat::FixedSizeListType
+      type.build_array(red_arrow_array.size,
+                       convert_buffer(red_arrow_array.null_bitmap),
+                       convert_array(red_arrow_array.values_raw))
     when ArrowFormat::StructType
       children = red_arrow_array.fields.collect do |red_arrow_field|
         convert_array(red_arrow_field)
@@ -806,6 +813,22 @@ module WriterTests
                  [type.to_s, values])
   end
 
+  def test_fixed_size_list
+    data_type = Arrow::FixedSizeListDataType.new({
+                                                   name: "count",
+                                                   type: :int8,
+                                                 },
+                                                 2)
+    array = Arrow::FixedSizeListArray.new(data_type,
+                                          [[-128, 127], nil, [-1, 1]])
+    type, values = roundtrip(array)
+    assert_equal([
+                   "fixed_size_list<count: int8>[2]",
+                   [[-128, 127], nil, [-1, 1]],
+                 ],
+                 [type.to_s, values])
+  end
+
   def test_map
     data_type = Arrow::MapDataType.new(:string, :int8)
     array = Arrow::MapArray.new(data_type,

Reply via email to