diff --git a/ruby/red-arrow-format/lib/arrow-format/type.rb b/ruby/red-arrow-format/lib/arrow-format/type.rb index 50c392f27020..64edaec5707d 100644 --- a/ruby/red-arrow-format/lib/arrow-format/type.rb +++ b/ruby/red-arrow-format/lib/arrow-format/type.rb @@ -536,6 +536,12 @@ def name def build_array(size, validity_buffer, values_buffer) DurationArray.new(self, size, validity_buffer, values_buffer) end + + def to_flatbuffers + fb_type = FB::Duration::Data.new + fb_type.unit = FB::TimeUnit.try_convert(@unit.to_s.upcase) + fb_type + end end class VariableSizeBinaryType < Type diff --git a/ruby/red-arrow-format/test/test-writer.rb b/ruby/red-arrow-format/test/test-writer.rb index bf05f20e4ea8..e1a2678c5909 100644 --- a/ruby/red-arrow-format/test/test-writer.rb +++ b/ruby/red-arrow-format/test/test-writer.rb @@ -67,6 +67,8 @@ def convert_type(red_arrow_type) ArrowFormat::DayTimeIntervalType.singleton when Arrow::MonthDayNanoIntervalDataType ArrowFormat::MonthDayNanoIntervalType.singleton + when Arrow::DurationDataType + ArrowFormat::DurationType.new(convert_time_unit(red_arrow_type.unit)) when Arrow::BinaryDataType ArrowFormat::BinaryType.singleton when Arrow::LargeBinaryDataType @@ -610,6 +612,66 @@ def test_write end end + sub_test_case("Duration(:second)") do + def build_array + Arrow::DurationArray.new(:second, [0, nil, 100]) + end + + def test_write + assert_equal([0, nil, 100], + @values) + end + + def test_type + assert_equal(Arrow::TimeUnit::SECOND, @type.unit) + end + end + + sub_test_case("Duration(:millisecond)") do + def build_array + Arrow::DurationArray.new(:milli, [0, nil, 100]) + end + + def test_write + assert_equal([0, nil, 100], + @values) + end + + def test_type + assert_equal(Arrow::TimeUnit::MILLI, @type.unit) + end + end + + sub_test_case("Duration(:microsecond)") do + def build_array + Arrow::DurationArray.new(:micro, [0, nil, 100]) + end + + def test_write + assert_equal([0, nil, 100], + @values) + end + + def test_type + assert_equal(Arrow::TimeUnit::MICRO, @type.unit) + end + end + + sub_test_case("Duration(:nanosecond)") do + def build_array + Arrow::DurationArray.new(:nano, [0, nil, 100]) + end + + def test_write + assert_equal([0, nil, 100], + @values) + end + + def test_type + assert_equal(Arrow::TimeUnit::NANO, @type.unit) + end + end + sub_test_case("Binary") do def build_array Arrow::BinaryArray.new(["Hello".b, nil, "World".b]) diff --git a/ruby/red-arrow/ext/arrow/converters.hpp b/ruby/red-arrow/ext/arrow/converters.hpp index 6a1ceb20b844..b4838c8f79c2 100644 --- a/ruby/red-arrow/ext/arrow/converters.hpp +++ b/ruby/red-arrow/ext/arrow/converters.hpp @@ -241,11 +241,6 @@ namespace red_arrow { return rb_time_num_new(sec, Qnil); } - // TODO - // inline VALUE convert(const arrow::IntervalArray& array, - // const int64_t i) { - // }; - inline VALUE convert(const arrow::MonthIntervalArray& array, const int64_t i) { return INT2NUM(array.Value(i)); @@ -280,6 +275,11 @@ namespace red_arrow { return value; } + inline VALUE convert(const arrow::DurationArray& array, + const int64_t i) { + return LL2NUM(array.Value(i)); + } + VALUE convert(const arrow::ListArray& array, const int64_t i); @@ -382,6 +382,7 @@ namespace red_arrow { VISIT(MonthInterval) VISIT(DayTimeInterval) VISIT(MonthDayNanoInterval) + VISIT(Duration) VISIT(List) VISIT(LargeList) VISIT(Struct) @@ -481,6 +482,7 @@ namespace red_arrow { VISIT(MonthInterval) VISIT(DayTimeInterval) VISIT(MonthDayNanoInterval) + VISIT(Duration) VISIT(List) VISIT(LargeList) VISIT(Struct) @@ -588,6 +590,7 @@ namespace red_arrow { VISIT(MonthInterval) VISIT(DayTimeInterval) VISIT(MonthDayNanoInterval) + VISIT(Duration) VISIT(List) VISIT(LargeList) VISIT(Struct) @@ -691,6 +694,7 @@ namespace red_arrow { VISIT(MonthInterval) VISIT(DayTimeInterval) VISIT(MonthDayNanoInterval) + VISIT(Duration) VISIT(List) VISIT(LargeList) VISIT(Struct) @@ -795,6 +799,7 @@ namespace red_arrow { VISIT(MonthInterval) VISIT(DayTimeInterval) VISIT(MonthDayNanoInterval) + VISIT(Duration) VISIT(List) VISIT(LargeList) VISIT(Struct) @@ -907,6 +912,7 @@ namespace red_arrow { VISIT(MonthInterval) VISIT(DayTimeInterval) VISIT(MonthDayNanoInterval) + VISIT(Duration) VISIT(List) VISIT(LargeList) VISIT(Struct) diff --git a/ruby/red-arrow/ext/arrow/raw-records.cpp b/ruby/red-arrow/ext/arrow/raw-records.cpp index 67f1dab13ed4..7f643bad4130 100644 --- a/ruby/red-arrow/ext/arrow/raw-records.cpp +++ b/ruby/red-arrow/ext/arrow/raw-records.cpp @@ -100,6 +100,7 @@ namespace red_arrow { VISIT(MonthInterval) VISIT(DayTimeInterval) VISIT(MonthDayNanoInterval) + VISIT(Duration) VISIT(List) VISIT(Struct) VISIT(Map) @@ -238,6 +239,7 @@ namespace red_arrow { VISIT(MonthInterval) VISIT(DayTimeInterval) VISIT(MonthDayNanoInterval) + VISIT(Duration) VISIT(List) VISIT(Struct) VISIT(Map) diff --git a/ruby/red-arrow/ext/arrow/values.cpp b/ruby/red-arrow/ext/arrow/values.cpp index 9a26baf1d59a..0296f27398d8 100644 --- a/ruby/red-arrow/ext/arrow/values.cpp +++ b/ruby/red-arrow/ext/arrow/values.cpp @@ -81,6 +81,7 @@ namespace red_arrow { VISIT(MonthInterval) VISIT(DayTimeInterval) VISIT(MonthDayNanoInterval) + VISIT(Duration) VISIT(List) VISIT(LargeList) VISIT(Struct) diff --git a/ruby/red-arrow/test/raw-records/test-basic-arrays.rb b/ruby/red-arrow/test/raw-records/test-basic-arrays.rb index 1c21a493c556..7a6e6115d6ba 100644 --- a/ruby/red-arrow/test/raw-records/test-basic-arrays.rb +++ b/ruby/red-arrow/test/raw-records/test-basic-arrays.rb @@ -406,6 +406,46 @@ def test_month_day_nano_interval target = build({column: :month_day_nano_interval}, records) assert_equal(records, actual_records(target)) end + + def test_duration_second + records = [ + [0], + [nil], + [100], + ] + target = build({column: {type: :duration, unit: :second}}, records) + assert_equal(records, actual_records(target)) + end + + def test_duration_milli + records = [ + [0], + [nil], + [100], + ] + target = build({column: {type: :duration, unit: :milli}}, records) + assert_equal(records, actual_records(target)) + end + + def test_duration_micro + records = [ + [0], + [nil], + [100], + ] + target = build({column: {type: :duration, unit: :micro}}, records) + assert_equal(records, actual_records(target)) + end + + def test_duration_nano + records = [ + [0], + [nil], + [100], + ] + target = build({column: {type: :duration, unit: :nano}}, records) + assert_equal(records, actual_records(target)) + end end class EachRawRecordRecordBatchBasicArraysTest < Test::Unit::TestCase diff --git a/ruby/red-arrow/test/values/test-basic-arrays.rb b/ruby/red-arrow/test/values/test-basic-arrays.rb index ddaaa3db64fe..b3c8e18172d9 100644 --- a/ruby/red-arrow/test/values/test-basic-arrays.rb +++ b/ruby/red-arrow/test/values/test-basic-arrays.rb @@ -336,6 +336,46 @@ def test_month_day_nano_interval target = build(Arrow::MonthDayNanoIntervalArray.new(values)) assert_equal(values, target.values) end + + def test_duration_second + values = [ + 0, + nil, + 100, + ] + target = build(Arrow::DurationArray.new(:second, values)) + assert_equal(values, target.values) + end + + def test_duration_milli + values = [ + 0, + nil, + 100, + ] + target = build(Arrow::DurationArray.new(:milli, values)) + assert_equal(values, target.values) + end + + def test_duration_micro + values = [ + 0, + nil, + 100, + ] + target = build(Arrow::DurationArray.new(:micro, values)) + assert_equal(values, target.values) + end + + def test_duration_nano + values = [ + 0, + nil, + 100, + ] + target = build(Arrow::DurationArray.new(:nano, values)) + assert_equal(values, target.values) + end end class ValuesArrayBasicArraysTest < Test::Unit::TestCase