From 316c16dd3e30c064c3c285f8859d72febb4b3afc Mon Sep 17 00:00:00 2001 From: Yifan Chen <30335308+emecii@users.noreply.github.com> Date: Wed, 9 Sep 2026 22:13:51 -0700 Subject: [PATCH] GH-51273: [Ruby] Add FixedSizeListArray values constructor --- .../lib/arrow-format/array.rb | 40 ++++++++++- .../test/test-fixed-size-list-array.rb | 67 +++++++++++++++++++ 2 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 ruby/red-arrow-format/test/test-fixed-size-list-array.rb diff --git a/ruby/red-arrow-format/lib/arrow-format/array.rb b/ruby/red-arrow-format/lib/arrow-format/array.rb index 992abe815bd..7abe4e6791d 100644 --- a/ruby/red-arrow-format/lib/arrow-format/array.rb +++ b/ruby/red-arrow-format/lib/arrow-format/array.rb @@ -1093,7 +1093,15 @@ class LargeListArray < VariableSizeListArray class FixedSizeListArray < Array attr_reader :child - def initialize(type, size, validity_buffer, child) + def initialize(type, *args) + if args.size == 1 + args = build_data(type, args.first) + elsif args.size != 3 + raise ArgumentError, + "wrong number of arguments (given #{args.size + 1}, expected 2 or 4)" + end + + size, validity_buffer, child = args super(type, size, validity_buffer) @child = child end @@ -1112,6 +1120,36 @@ def to_a end private + def build_data(type, data) + n = 0 + validity_buffer_builder = nil + + child_values = [] + data.each_with_index do |value, i| + if value.nil? + validity_buffer_builder ||= SparseBitmapBuilder.new + validity_buffer_builder.unset(i) + child_values.concat([nil] * type.size) + else + unless value.size == type.size + message = "list size must be #{type.size}: #{value.inspect}" + raise ArgumentError, message + end + child_values.concat(value) + end + n += 1 + end + + validity_buffer = validity_buffer_builder&.finish(n) + child = type.child.type.build_array(child_values) + + [ + n, + validity_buffer, + child, + ] + end + def slice!(offset, size) super @child = @child.slice(@type.size * @offset, diff --git a/ruby/red-arrow-format/test/test-fixed-size-list-array.rb b/ruby/red-arrow-format/test/test-fixed-size-list-array.rb new file mode 100644 index 00000000000..bf4bb5afd84 --- /dev/null +++ b/ruby/red-arrow-format/test/test-fixed-size-list-array.rb @@ -0,0 +1,67 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +class TestFixedSizeListArray < Test::Unit::TestCase + def setup + child = ArrowFormat::Field.new("item", ArrowFormat::Int16Type.singleton) + @type = ArrowFormat::FixedSizeListType.new(child, 2) + end + + sub_test_case("#initialize") do + def test_no_null + values = [[-1, 0], [1, 2]] + array = ArrowFormat::FixedSizeListArray.new(@type, values) + assert_same(@type, array.type) + assert_same(@type.child.type, array.child.type) + assert_equal(values, array.to_a) + end + + def test_null_list + values = [[1, 2], nil, [3, 4]] + array = ArrowFormat::FixedSizeListArray.new(@type, values) + assert_equal(1, array.n_nulls) + assert_equal([1, 2, nil, nil, 3, 4], array.child.to_a) + assert_equal(values, array.to_a) + end + + def test_null_child + values = [[1, nil], [nil, 2]] + array = ArrowFormat::FixedSizeListArray.new(@type, values) + assert_equal(2, array.child.n_nulls) + assert_equal(values, array.to_a) + end + + def test_invalid_list_size + message = "list size must be 2: [1]" + assert_raise(ArgumentError.new(message)) do + ArrowFormat::FixedSizeListArray.new(@type, [[1]]) + end + end + + def test_empty + array = ArrowFormat::FixedSizeListArray.new(@type, []) + assert_equal([], array.child.to_a) + assert_equal([], array.to_a) + end + + def test_low_level + child = ArrowFormat::Int16Array.new([1, 2]) + array = ArrowFormat::FixedSizeListArray.new(@type, 1, nil, child) + assert_equal([[1, 2]], array.to_a) + end + end +end