Skip to content

Commit a64e583

Browse files
authored
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]>
1 parent 59e47ca commit a64e583

File tree

4 files changed

+59
-0
lines changed

4 files changed

+59
-0
lines changed

ruby/red-arrow-format/lib/arrow-format/array.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,4 +180,21 @@ def to_a
180180
apply_validity(values)
181181
end
182182
end
183+
184+
class StructArray < Array
185+
def initialize(type, size, validity_buffer, children)
186+
super(type, size, validity_buffer)
187+
@children = children
188+
end
189+
190+
def to_a
191+
if @children.empty?
192+
values = [[]] * @size
193+
else
194+
children_values = @children.collect(&:to_a)
195+
values = children_values[0].zip(*children_values[1..-1])
196+
end
197+
apply_validity(values)
198+
end
199+
end
183200
end

ruby/red-arrow-format/lib/arrow-format/file-reader.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
require_relative "org/apache/arrow/flatbuf/null"
3434
require_relative "org/apache/arrow/flatbuf/precision"
3535
require_relative "org/apache/arrow/flatbuf/schema"
36+
require_relative "org/apache/arrow/flatbuf/struct_"
3637
require_relative "org/apache/arrow/flatbuf/utf8"
3738

3839
module ArrowFormat
@@ -159,6 +160,9 @@ def read_field(fb_field)
159160
end
160161
when Org::Apache::Arrow::Flatbuf::List
161162
type = ListType.new(read_field(fb_field.children[0]))
163+
when Org::Apache::Arrow::Flatbuf::Struct
164+
children = fb_field.children.collect {|child| read_field(child)}
165+
type = StructType.new(children)
162166
when Org::Apache::Arrow::Flatbuf::Binary
163167
type = BinaryType.singleton
164168
when Org::Apache::Arrow::Flatbuf::LargeBinary
@@ -200,6 +204,11 @@ def read_column(field, nodes, buffers, body)
200204
offsets = body.slice(offsets_buffer.offset, offsets_buffer.length)
201205
child = read_column(field.type.child, nodes, buffers, body)
202206
field.type.build_array(length, validity, offsets, child)
207+
when StructType
208+
children = field.type.children.collect do |child|
209+
read_column(child, nodes, buffers, body)
210+
end
211+
field.type.build_array(length, validity, children)
203212
when VariableSizeBinaryType
204213
offsets_buffer = buffers.shift
205214
values_buffer = buffers.shift

ruby/red-arrow-format/lib/arrow-format/type.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,4 +206,16 @@ def build_array(size, validity_buffer, offsets_buffer, child)
206206
ListArray.new(self, size, validity_buffer, offsets_buffer, child)
207207
end
208208
end
209+
210+
class StructType < Type
211+
attr_reader :children
212+
def initialize(children)
213+
super("Struct")
214+
@children = children
215+
end
216+
217+
def build_array(size, validity_buffer, children)
218+
StructArray.new(self, size, validity_buffer, children)
219+
end
220+
end
209221
end

ruby/red-arrow-format/test/test-file-reader.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,4 +139,25 @@ def test_read
139139
read)
140140
end
141141
end
142+
143+
sub_test_case("Struct") do
144+
def build_array
145+
data_type = Arrow::StructDataType.new(count: :int8,
146+
visible: :boolean)
147+
Arrow::StructArray.new(data_type, [[-128, nil], nil, [nil, true]])
148+
end
149+
150+
def test_read
151+
assert_equal([
152+
{
153+
"value" => [
154+
[-128, nil],
155+
nil,
156+
[nil, true],
157+
],
158+
},
159+
],
160+
read)
161+
end
162+
end
142163
end

0 commit comments

Comments
 (0)