diff --git a/ruby/red-arrow-format/lib/arrow-format/array.rb b/ruby/red-arrow-format/lib/arrow-format/array.rb index 72cce5cbbea..ac96038f194 100644 --- a/ruby/red-arrow-format/lib/arrow-format/array.rb +++ b/ruby/red-arrow-format/lib/arrow-format/array.rb @@ -189,6 +189,39 @@ def to_a end end + class IntervalArray < TemporalArray + end + + class YearMonthIntervalArray < IntervalArray + def to_a + apply_validity(@values_buffer.values(:s32, 0, @size)) + end + end + + class DayTimeIntervalArray < IntervalArray + def to_a + values = @values_buffer. + each(:s32, 0, @size * 2). + each_slice(2). + collect do |(_, day), (_, time)| + [day, time] + end + apply_validity(values) + end + end + + class MonthDayNanoIntervalArray < IntervalArray + def to_a + buffer_types = [:s32, :s32, :s64] + value_size = IO::Buffer.size_of(buffer_types) + values = @size.times.collect do |i| + offset = value_size * i + @values_buffer.get_values(buffer_types, offset) + end + apply_validity(values) + end + end + class DurationArray < TemporalArray def to_a apply_validity(@values_buffer.values(:s64, 0, @size)) 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 71f6e9cedae..29c7f5edd49 100644 --- a/ruby/red-arrow-format/lib/arrow-format/file-reader.rb +++ b/ruby/red-arrow-format/lib/arrow-format/file-reader.rb @@ -31,6 +31,8 @@ require_relative "org/apache/arrow/flatbuf/floating_point" require_relative "org/apache/arrow/flatbuf/footer" require_relative "org/apache/arrow/flatbuf/int" +require_relative "org/apache/arrow/flatbuf/interval" +require_relative "org/apache/arrow/flatbuf/interval_unit" require_relative "org/apache/arrow/flatbuf/large_binary" require_relative "org/apache/arrow/flatbuf/large_list" require_relative "org/apache/arrow/flatbuf/large_utf8" @@ -215,6 +217,15 @@ def read_field(fb_field) when Org::Apache::Arrow::Flatbuf::Timestamp unit = fb_type.unit.name.downcase.to_sym type = TimestampType.new(unit, fb_type.timezone) + when Org::Apache::Arrow::Flatbuf::Interval + case fb_type.unit + when Org::Apache::Arrow::Flatbuf::IntervalUnit::YEAR_MONTH + type = YearMonthIntervalType.new + when Org::Apache::Arrow::Flatbuf::IntervalUnit::DAY_TIME + type = DayTimeIntervalType.new + when Org::Apache::Arrow::Flatbuf::IntervalUnit::MONTH_DAY_NANO + type = MonthDayNanoIntervalType.new + end when Org::Apache::Arrow::Flatbuf::Duration unit = fb_type.unit.name.downcase.to_sym type = DurationType.new(unit) diff --git a/ruby/red-arrow-format/lib/arrow-format/type.rb b/ruby/red-arrow-format/lib/arrow-format/type.rb index abcefca3bf5..c6679660122 100644 --- a/ruby/red-arrow-format/lib/arrow-format/type.rb +++ b/ruby/red-arrow-format/lib/arrow-format/type.rb @@ -315,6 +315,42 @@ def build_array(size, validity_buffer, values_buffer) end end + class IntervalType < TemporalType + end + + class YearMonthIntervalType < IntervalType + def initialize + super("YearMonthInterval") + end + + def build_array(size, validity_buffer, values_buffer) + YearMonthIntervalArray.new(self, size, validity_buffer, values_buffer) + end + end + + class DayTimeIntervalType < IntervalType + def initialize + super("DayTimeInterval") + end + + def build_array(size, validity_buffer, values_buffer) + DayTimeIntervalArray.new(self, size, validity_buffer, values_buffer) + end + end + + class MonthDayNanoIntervalType < IntervalType + def initialize + super("MonthDayNanoInterval") + end + + def build_array(size, validity_buffer, values_buffer) + MonthDayNanoIntervalArray.new(self, + size, + validity_buffer, + values_buffer) + end + end + class DurationType < TemporalType attr_reader :unit def initialize(unit) diff --git a/ruby/red-arrow-format/test/test-file-reader.rb b/ruby/red-arrow-format/test/test-file-reader.rb index 12ed95846c3..6198f0cb96d 100644 --- a/ruby/red-arrow-format/test/test-file-reader.rb +++ b/ruby/red-arrow-format/test/test-file-reader.rb @@ -489,6 +489,71 @@ def test_type end end + sub_test_case("YearMonthInterval") do + def build_array + Arrow::MonthIntervalArray.new([0, nil, 100]) + end + + def test_read + assert_equal([{"value" => [0, nil, 100]}], + read) + end + end + + sub_test_case("DayTimeInterval") do + def build_array + Arrow::DayTimeIntervalArray.new([ + {day: 1, millisecond: 100}, + nil, + {day: 3, millisecond: 300}, + ]) + end + + def test_read + assert_equal([ + { + "value" => [ + [1, 100], + nil, + [3, 300], + ], + }, + ], + read) + end + end + + sub_test_case("MonthDayNanoInterval") do + def build_array + Arrow::MonthDayNanoIntervalArray.new([ + { + month: 1, + day: 1, + nanosecond: 100, + }, + nil, + { + month: 3, + day: 3, + nanosecond: 300, + }, + ]) + end + + def test_read + assert_equal([ + { + "value" => [ + [1, 1, 100], + nil, + [3, 3, 300], + ], + }, + ], + read) + end + end + sub_test_case("Duration(:second)") do def build_array Arrow::DurationArray.new(:second, [0, nil, 100])