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,