From a8d9b35d7bcb6fe86c9c625d0d0f2f8777eb1700 Mon Sep 17 00:00:00 2001 From: Sutou Kouhei Date: Fri, 30 Jan 2026 17:10:15 +0900 Subject: [PATCH] GH-49074: [Ruby] Add support for writing interval arrays --- .../lib/arrow-format/readable.rb | 6 +- .../red-arrow-format/lib/arrow-format/type.rb | 29 ++++++++ ruby/red-arrow-format/test/test-writer.rb | 71 +++++++++++++++++++ 3 files changed, 103 insertions(+), 3 deletions(-) diff --git a/ruby/red-arrow-format/lib/arrow-format/readable.rb b/ruby/red-arrow-format/lib/arrow-format/readable.rb index 9cf1beecbebe..867a54c17bdc 100644 --- a/ruby/red-arrow-format/lib/arrow-format/readable.rb +++ b/ruby/red-arrow-format/lib/arrow-format/readable.rb @@ -78,11 +78,11 @@ def read_field(fb_field) when FB::Interval case fb_type.unit when FB::IntervalUnit::YEAR_MONTH - type = YearMonthIntervalType.new + type = YearMonthIntervalType.singleton when FB::IntervalUnit::DAY_TIME - type = DayTimeIntervalType.new + type = DayTimeIntervalType.singleton when FB::IntervalUnit::MONTH_DAY_NANO - type = MonthDayNanoIntervalType.new + type = MonthDayNanoIntervalType.singleton end when FB::Duration unit = fb_type.unit.name.downcase.to_sym diff --git a/ruby/red-arrow-format/lib/arrow-format/type.rb b/ruby/red-arrow-format/lib/arrow-format/type.rb index fd7582a7767e..9ba8cae71000 100644 --- a/ruby/red-arrow-format/lib/arrow-format/type.rb +++ b/ruby/red-arrow-format/lib/arrow-format/type.rb @@ -458,9 +458,30 @@ def to_flatbuffers end class IntervalType < TemporalType + class << self + def singleton + @singleton ||= new + end + end + + attr_reader :unit + def initialize(unit) + super() + @unit = unit + end + + def to_flatbuffers + fb_type = FB::Interval::Data.new + fb_type.unit = FB::IntervalUnit.try_convert(@unit.to_s.upcase) + fb_type + end end class YearMonthIntervalType < IntervalType + def initialize + super(:year_month) + end + def name "YearMonthInterval" end @@ -471,6 +492,10 @@ def build_array(size, validity_buffer, values_buffer) end class DayTimeIntervalType < IntervalType + def initialize + super(:day_time) + end + def name "DayTimeInterval" end @@ -481,6 +506,10 @@ def build_array(size, validity_buffer, values_buffer) end class MonthDayNanoIntervalType < IntervalType + def initialize + super(:month_day_nano) + end + def name "MonthDayNanoInterval" end diff --git a/ruby/red-arrow-format/test/test-writer.rb b/ruby/red-arrow-format/test/test-writer.rb index c440bc4a597a..841194ff51d9 100644 --- a/ruby/red-arrow-format/test/test-writer.rb +++ b/ruby/red-arrow-format/test/test-writer.rb @@ -61,6 +61,12 @@ def convert_type(red_arrow_type) when Arrow::TimestampDataType ArrowFormat::TimestampType.new(convert_time_unit(red_arrow_type.unit), red_arrow_type.time_zone&.identifier) + when Arrow::MonthIntervalDataType + ArrowFormat::YearMonthIntervalType.singleton + when Arrow::DayTimeIntervalDataType + ArrowFormat::DayTimeIntervalType.singleton + when Arrow::MonthDayNanoIntervalDataType + ArrowFormat::MonthDayNanoIntervalType.singleton when Arrow::BinaryDataType ArrowFormat::BinaryType.singleton when Arrow::LargeBinaryDataType @@ -523,6 +529,71 @@ def test_type end end + sub_test_case("YearMonthInterval") do + def build_array + Arrow::MonthIntervalArray.new([0, nil, 100]) + end + + def test_write + assert_equal([0, nil, 100], + @values) + 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_write + assert_equal([ + {day: 1, millisecond: 100}, + nil, + {day: 3, millisecond: 300}, + ], + @values) + 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_write + assert_equal([ + { + month: 1, + day: 1, + nanosecond: 100, + }, + nil, + { + month: 3, + day: 3, + nanosecond: 300, + }, + ], + @values) + end + end + sub_test_case("Binary") do def build_array Arrow::BinaryArray.new(["Hello".b, nil, "World".b])