red-arrow 6.0.1 → 9.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +10 -0
  3. data/ext/arrow/arrow.cpp +12 -0
  4. data/ext/arrow/converters.hpp +49 -10
  5. data/ext/arrow/extconf.rb +7 -5
  6. data/ext/arrow/raw-records.cpp +3 -2
  7. data/ext/arrow/red-arrow.hpp +7 -0
  8. data/ext/arrow/values.cpp +3 -2
  9. data/lib/arrow/array-builder.rb +40 -6
  10. data/lib/arrow/array-computable.rb +37 -0
  11. data/lib/arrow/array.rb +16 -0
  12. data/lib/arrow/chunked-array.rb +21 -0
  13. data/lib/arrow/column.rb +28 -0
  14. data/lib/arrow/data-type.rb +2 -1
  15. data/lib/arrow/datum.rb +2 -0
  16. data/lib/arrow/day-time-interval-array-builder.rb +29 -0
  17. data/lib/arrow/decimal128-array-builder.rb +16 -6
  18. data/lib/arrow/decimal128.rb +14 -0
  19. data/lib/arrow/decimal256-array-builder.rb +16 -6
  20. data/lib/arrow/decimal256.rb +14 -0
  21. data/lib/arrow/field.rb +44 -3
  22. data/lib/arrow/function.rb +52 -0
  23. data/lib/arrow/list-data-type.rb +1 -6
  24. data/lib/arrow/loader.rb +19 -0
  25. data/lib/arrow/month-day-nano-interval-array-builder.rb +29 -0
  26. data/lib/arrow/s3-global-options.rb +38 -0
  27. data/lib/arrow/sort-key.rb +61 -55
  28. data/lib/arrow/sort-options.rb +8 -8
  29. data/lib/arrow/string-array-builder.rb +30 -0
  30. data/lib/arrow/table-loader.rb +99 -62
  31. data/lib/arrow/table-saver.rb +7 -2
  32. data/lib/arrow/table.rb +78 -0
  33. data/lib/arrow/time-unit.rb +31 -0
  34. data/lib/arrow/time32-array-builder.rb +2 -14
  35. data/lib/arrow/time32-data-type.rb +9 -38
  36. data/lib/arrow/time64-array-builder.rb +2 -14
  37. data/lib/arrow/time64-data-type.rb +9 -38
  38. data/lib/arrow/timestamp-array-builder.rb +2 -14
  39. data/lib/arrow/timestamp-data-type.rb +9 -34
  40. data/lib/arrow/version.rb +1 -1
  41. data/red-arrow.gemspec +2 -11
  42. data/test/helper.rb +2 -0
  43. data/test/raw-records/test-basic-arrays.rb +30 -0
  44. data/test/raw-records/test-dense-union-array.rb +27 -0
  45. data/test/raw-records/test-dictionary-array.rb +341 -0
  46. data/test/raw-records/test-list-array.rb +39 -0
  47. data/test/raw-records/test-map-array.rb +37 -0
  48. data/test/raw-records/test-sparse-union-array.rb +27 -0
  49. data/test/raw-records/test-struct-array.rb +30 -0
  50. data/test/test-array-builder.rb +62 -0
  51. data/test/test-chunked-array.rb +6 -0
  52. data/test/test-column.rb +31 -0
  53. data/test/test-decimal128-array-builder.rb +14 -0
  54. data/test/test-decimal128-array.rb +5 -2
  55. data/test/test-decimal128.rb +26 -2
  56. data/test/test-decimal256-array-builder.rb +14 -0
  57. data/test/test-decimal256-array.rb +5 -2
  58. data/test/test-decimal256.rb +26 -2
  59. data/test/test-field.rb +26 -0
  60. data/test/test-function.rb +48 -14
  61. data/test/test-table.rb +204 -6
  62. data/test/values/test-basic-arrays.rb +30 -0
  63. data/test/values/test-dense-union-array.rb +27 -0
  64. data/test/values/test-dictionary-array.rb +325 -0
  65. data/test/values/test-list-array.rb +39 -0
  66. data/test/values/test-map-array.rb +33 -0
  67. data/test/values/test-sparse-union-array.rb +27 -0
  68. data/test/values/test-struct-array.rb +30 -0
  69. metadata +95 -196
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 853f00543077ecc6ecbc5dcca0f535eda624ece16e2f74bb5ec966f435d60137
4
- data.tar.gz: 8e6ea3a343fb7977729a004f61789c5f579b0d2a3c0823faedc4c10425eaec56
3
+ metadata.gz: 23d181c0c2d49f1479ddae27c02427d75b72f66a31c097e1f0ead363422170ed
4
+ data.tar.gz: e2c5e259b177bb136d7f492e46ec3411b5f05d190618cec6736494315fc64efb
5
5
  SHA512:
6
- metadata.gz: cb6de71e011620648821b4b13081386f5ad5a7e77ca7be26554c956a2f1d97ac488ad7f14bf289656fa15504600243fd4e3ba16068d355d6e1559a02a8e1c56f
7
- data.tar.gz: 5e1ec7c8e1d306d5c72c282447a23c0b58674ee64f74c6d230834ba495265560a22953e489009bcecff9baa8c49816e5c8e431a1c1c5557cd2bac39a3696df02
6
+ metadata.gz: a4d7673b6457b4f288d9fc1e0bcc8b9adad239f21dbe722cbb412e81e51d117e8661027731bd4918be19c9ed6c6978f21613ebdd31fbe21271d2175f3d416655
7
+ data.tar.gz: f300245a89afeb3c8d5e56db26fe866ae666a429429c26155591b430bc47f9d7abe987e35fd0507133b9e5011f78381b6e46797b1072556786fb8fb54e19e9fe
data/Gemfile CHANGED
@@ -20,3 +20,13 @@
20
20
  source "https://rubygems.org/"
21
21
 
22
22
  gemspec
23
+
24
+ gem "benchmark-driver"
25
+ gem "bundler"
26
+ gem "faker"
27
+ gem "fiddle", ">= 1.0.9"
28
+ gem "rake"
29
+ gem "redcarpet"
30
+ gem "test-unit"
31
+ gem "webrick"
32
+ gem "yard"
data/ext/arrow/arrow.cpp CHANGED
@@ -36,6 +36,13 @@ namespace red_arrow {
36
36
  ID id_jd;
37
37
  ID id_new;
38
38
  ID id_to_datetime;
39
+
40
+ namespace symbols {
41
+ VALUE day;
42
+ VALUE millisecond;
43
+ VALUE month;
44
+ VALUE nanosecond;
45
+ }
39
46
  }
40
47
 
41
48
  extern "C" void Init_arrow() {
@@ -81,4 +88,9 @@ extern "C" void Init_arrow() {
81
88
  red_arrow::id_to_datetime = rb_intern("to_datetime");
82
89
 
83
90
  red_arrow::memory_view::init(mArrow);
91
+
92
+ red_arrow::symbols::day = ID2SYM(rb_intern("day"));
93
+ red_arrow::symbols::millisecond = ID2SYM(rb_intern("millisecond"));
94
+ red_arrow::symbols::month = ID2SYM(rb_intern("month"));
95
+ red_arrow::symbols::nanosecond = ID2SYM(rb_intern("nanosecond"));
84
96
  }
@@ -202,6 +202,40 @@ namespace red_arrow {
202
202
  // const int64_t i) {
203
203
  // };
204
204
 
205
+ inline VALUE convert(const arrow::MonthIntervalArray& array,
206
+ const int64_t i) {
207
+ return INT2NUM(array.Value(i));
208
+ }
209
+
210
+ inline VALUE convert(const arrow::DayTimeIntervalArray& array,
211
+ const int64_t i) {
212
+ auto value = rb_hash_new();
213
+ auto arrow_value = array.Value(i);
214
+ rb_hash_aset(value,
215
+ red_arrow::symbols::day,
216
+ INT2NUM(arrow_value.days));
217
+ rb_hash_aset(value,
218
+ red_arrow::symbols::millisecond,
219
+ INT2NUM(arrow_value.milliseconds));
220
+ return value;
221
+ }
222
+
223
+ inline VALUE convert(const arrow::MonthDayNanoIntervalArray& array,
224
+ const int64_t i) {
225
+ auto value = rb_hash_new();
226
+ auto arrow_value = array.Value(i);
227
+ rb_hash_aset(value,
228
+ red_arrow::symbols::month,
229
+ INT2NUM(arrow_value.months));
230
+ rb_hash_aset(value,
231
+ red_arrow::symbols::day,
232
+ INT2NUM(arrow_value.days));
233
+ rb_hash_aset(value,
234
+ red_arrow::symbols::nanosecond,
235
+ INT2NUM(arrow_value.nanoseconds));
236
+ return value;
237
+ }
238
+
205
239
  VALUE convert(const arrow::ListArray& array,
206
240
  const int64_t i);
207
241
 
@@ -298,8 +332,9 @@ namespace red_arrow {
298
332
  VISIT(Time32)
299
333
  VISIT(Time64)
300
334
  VISIT(Timestamp)
301
- // TODO
302
- // VISIT(Interval)
335
+ VISIT(MonthInterval)
336
+ VISIT(DayTimeInterval)
337
+ VISIT(MonthDayNanoInterval)
303
338
  VISIT(List)
304
339
  VISIT(Struct)
305
340
  VISIT(Map)
@@ -404,8 +439,9 @@ namespace red_arrow {
404
439
  VISIT(Time32)
405
440
  VISIT(Time64)
406
441
  VISIT(Timestamp)
407
- // TODO
408
- // VISIT(Interval)
442
+ VISIT(MonthInterval)
443
+ VISIT(DayTimeInterval)
444
+ VISIT(MonthDayNanoInterval)
409
445
  VISIT(List)
410
446
  VISIT(Struct)
411
447
  VISIT(Map)
@@ -506,8 +542,9 @@ namespace red_arrow {
506
542
  VISIT(Time32)
507
543
  VISIT(Time64)
508
544
  VISIT(Timestamp)
509
- // TODO
510
- // VISIT(Interval)
545
+ VISIT(MonthInterval)
546
+ VISIT(DayTimeInterval)
547
+ VISIT(MonthDayNanoInterval)
511
548
  VISIT(List)
512
549
  VISIT(Struct)
513
550
  VISIT(Map)
@@ -609,8 +646,9 @@ namespace red_arrow {
609
646
  VISIT(Time32)
610
647
  VISIT(Time64)
611
648
  VISIT(Timestamp)
612
- // TODO
613
- // VISIT(Interval)
649
+ VISIT(MonthInterval)
650
+ VISIT(DayTimeInterval)
651
+ VISIT(MonthDayNanoInterval)
614
652
  VISIT(List)
615
653
  VISIT(Struct)
616
654
  VISIT(Map)
@@ -735,8 +773,9 @@ namespace red_arrow {
735
773
  VISIT(Time32)
736
774
  VISIT(Time64)
737
775
  VISIT(Timestamp)
738
- // TODO
739
- // VISIT(Interval)
776
+ VISIT(MonthInterval)
777
+ VISIT(DayTimeInterval)
778
+ VISIT(MonthDayNanoInterval)
740
779
  VISIT(List)
741
780
  VISIT(Struct)
742
781
  VISIT(Map)
data/ext/arrow/extconf.rb CHANGED
@@ -28,7 +28,7 @@ end
28
28
  checking_for(checking_message("Homebrew")) do
29
29
  platform = NativePackageInstaller::Platform.detect
30
30
  if platform.is_a?(NativePackageInstaller::Platform::Homebrew)
31
- openssl_prefix = `brew --prefix openssl@1.1`.chomp
31
+ openssl_prefix = `brew --prefix openssl`.chomp
32
32
  unless openssl_prefix.empty?
33
33
  PKGConfig.add_path("#{openssl_prefix}/lib/pkgconfig")
34
34
  end
@@ -45,9 +45,10 @@ unless required_pkg_config_package([
45
45
  Arrow::Version::MICRO,
46
46
  ],
47
47
  debian: "libarrow-dev",
48
- redhat: "arrow-devel",
48
+ fedora: "libarrow-devel",
49
49
  homebrew: "apache-arrow",
50
- msys2: "arrow")
50
+ msys2: "arrow",
51
+ redhat: "arrow-devel")
51
52
  exit(false)
52
53
  end
53
54
 
@@ -58,9 +59,10 @@ unless required_pkg_config_package([
58
59
  Arrow::Version::MICRO,
59
60
  ],
60
61
  debian: "libarrow-glib-dev",
61
- redhat: "arrow-glib-devel",
62
+ fedora: "libarrow-glib-devel",
62
63
  homebrew: "apache-arrow-glib",
63
- msys2: "arrow")
64
+ msys2: "arrow",
65
+ redhat: "arrow-glib-devel")
64
66
  exit(false)
65
67
  end
66
68
 
@@ -96,8 +96,9 @@ namespace red_arrow {
96
96
  VISIT(Time32)
97
97
  VISIT(Time64)
98
98
  VISIT(Timestamp)
99
- // TODO
100
- // VISIT(Interval)
99
+ VISIT(MonthInterval)
100
+ VISIT(DayTimeInterval)
101
+ VISIT(MonthDayNanoInterval)
101
102
  VISIT(List)
102
103
  VISIT(Struct)
103
104
  VISIT(Map)
@@ -47,6 +47,13 @@ namespace red_arrow {
47
47
  extern ID id_new;
48
48
  extern ID id_to_datetime;
49
49
 
50
+ namespace symbols {
51
+ extern VALUE day;
52
+ extern VALUE millisecond;
53
+ extern VALUE month;
54
+ extern VALUE nanosecond;
55
+ }
56
+
50
57
  VALUE array_values(VALUE obj);
51
58
  VALUE chunked_array_values(VALUE obj);
52
59
 
data/ext/arrow/values.cpp CHANGED
@@ -77,8 +77,9 @@ namespace red_arrow {
77
77
  VISIT(Time32)
78
78
  VISIT(Time64)
79
79
  VISIT(Timestamp)
80
- // TODO
81
- // VISIT(Interval)
80
+ VISIT(MonthInterval)
81
+ VISIT(DayTimeInterval)
82
+ VISIT(MonthDayNanoInterval)
82
83
  VISIT(List)
83
84
  VISIT(Struct)
84
85
  VISIT(Map)
@@ -33,6 +33,11 @@ module Arrow
33
33
  end
34
34
  if builder_info
35
35
  builder = builder_info[:builder]
36
+ if builder.nil? and builder_info[:builder_type]
37
+ builder = create_builder(builder_info)
38
+ end
39
+ end
40
+ if builder
36
41
  builder.build(values)
37
42
  else
38
43
  Arrow::StringArray.new(values)
@@ -121,15 +126,28 @@ module Arrow
121
126
  detected: true,
122
127
  }
123
128
  when BigDecimal
124
- if value.to_arrow.is_a?(Decimal128)
125
- {
126
- builder: Decimal128ArrayBuilder.new,
127
- }
128
- else
129
+ builder_info ||= {}
130
+ if builder_info[:builder] or value.nan? or value.infinite?
129
131
  {
130
- builder: Decimal256ArrayBuilder.new,
132
+ builder: StringArrayBuilder.new,
131
133
  detected: true,
132
134
  }
135
+ else
136
+ precision = [builder_info[:precision] || 0, value.precision].max
137
+ scale = [builder_info[:scale] || 0, value.scale].max
138
+ if precision <= Decimal128DataType::MAX_PRECISION
139
+ {
140
+ builder_type: :decimal128,
141
+ precision: precision,
142
+ scale: scale,
143
+ }
144
+ else
145
+ {
146
+ builder_type: :decimal256,
147
+ precision: precision,
148
+ scale: scale,
149
+ }
150
+ end
133
151
  end
134
152
  when ::Array
135
153
  sub_builder_info = nil
@@ -154,6 +172,22 @@ module Arrow
154
172
  }
155
173
  end
156
174
  end
175
+
176
+ def create_builder(builder_info)
177
+ builder_type = builder_info[:builder_type]
178
+ case builder_type
179
+ when :decimal128
180
+ data_type = Decimal128DataType.new(builder_info[:precision],
181
+ builder_info[:scale])
182
+ Decimal128ArrayBuilder.new(data_type)
183
+ when :decimal256
184
+ data_type = Decimal256DataType.new(builder_info[:precision],
185
+ builder_info[:scale])
186
+ Decimal256ArrayBuilder.new(data_type)
187
+ else
188
+ nil
189
+ end
190
+ end
157
191
  end
158
192
 
159
193
  def build(values)
@@ -0,0 +1,37 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one
2
+ # or more contributor license agreements. See the NOTICE file
3
+ # distributed with this work for additional information
4
+ # regarding copyright ownership. The ASF licenses this file
5
+ # to you under the Apache License, Version 2.0 (the
6
+ # "License"); you may not use this file except in compliance
7
+ # with the License. You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+
18
+ module Arrow
19
+ module ArrayComputable
20
+ def min(options: nil)
21
+ compute("min", options: options).value
22
+ end
23
+
24
+ def max(options: nil)
25
+ compute("max", options: options).value
26
+ end
27
+
28
+ def uniq
29
+ unique.values
30
+ end
31
+
32
+ private
33
+ def compute(name, options: nil)
34
+ Function.find(name).execute([self], options).value
35
+ end
36
+ end
37
+ end
data/lib/arrow/array.rb CHANGED
@@ -18,6 +18,8 @@
18
18
  module Arrow
19
19
  class Array
20
20
  include Enumerable
21
+
22
+ include ArrayComputable
21
23
  include GenericFilterable
22
24
  include GenericTakeable
23
25
 
@@ -34,6 +36,20 @@ module Arrow
34
36
  return nil unless const_defined?(builder_class_name)
35
37
  const_get(builder_class_name)
36
38
  end
39
+
40
+ # @api private
41
+ def try_convert(value)
42
+ case value
43
+ when ::Array
44
+ begin
45
+ new(value)
46
+ rescue ArgumentError
47
+ nil
48
+ end
49
+ else
50
+ nil
51
+ end
52
+ end
37
53
  end
38
54
 
39
55
  # @param i [Integer]
@@ -18,6 +18,8 @@
18
18
  module Arrow
19
19
  class ChunkedArray
20
20
  include Enumerable
21
+
22
+ include ArrayComputable
21
23
  include GenericFilterable
22
24
  include GenericTakeable
23
25
 
@@ -87,5 +89,24 @@ module Arrow
87
89
  first_chunk.class.new(to_a)
88
90
  end
89
91
  end
92
+
93
+ def count(options: nil)
94
+ compute("count", options: options).value
95
+ end
96
+
97
+ def sum(options: nil)
98
+ compute("sum", options: options).value
99
+ end
100
+
101
+ def unique
102
+ compute("unique")
103
+ end
104
+
105
+ def cast(target_data_type, options: nil)
106
+ casted_chunks = chunks.collect do |chunk|
107
+ chunk.cast(target_data_type, options)
108
+ end
109
+ self.class.new(casted_chunks)
110
+ end
90
111
  end
91
112
  end
data/lib/arrow/column.rb CHANGED
@@ -72,5 +72,33 @@ module Arrow
72
72
  @field == other.field and
73
73
  @data == other.data
74
74
  end
75
+
76
+ def count(options: nil)
77
+ @data.count(options: options)
78
+ end
79
+
80
+ def sum(options: nil)
81
+ @data.sum(options: options)
82
+ end
83
+
84
+ def min(options: nil)
85
+ @data.min(options: options)
86
+ end
87
+
88
+ def max(options: nil)
89
+ @data.max(options: options)
90
+ end
91
+
92
+ def unique
93
+ @data.unique
94
+ end
95
+
96
+ def uniq
97
+ @data.uniq
98
+ end
99
+
100
+ def cast(target_data_type, options: nil)
101
+ @data.cast(target_data_type, options: options)
102
+ end
75
103
  end
76
104
  end
@@ -110,7 +110,7 @@ module Arrow
110
110
  description[key] = value
111
111
  end
112
112
  end
113
- if type.nil?
113
+ if type.nil? and self == DataType
114
114
  message =
115
115
  "data type description must have :type value: #{data_type.inspect}"
116
116
  raise ArgumentError, message
@@ -152,6 +152,7 @@ module Arrow
152
152
 
153
153
  private
154
154
  def resolve_class(data_type)
155
+ return self if data_type.nil?
155
156
  components = data_type.to_s.split("_").collect(&:capitalize)
156
157
  data_type_name = components.join.gsub(/\AUint/, "UInt")
157
158
  data_type_class_name = "#{data_type_name}DataType"
data/lib/arrow/datum.rb CHANGED
@@ -27,6 +27,8 @@ module Arrow
27
27
  ArrayDatum.new(value)
28
28
  when ChunkedArray
29
29
  ChunkedArrayDatum.new(value)
30
+ when Column
31
+ ChunkedArrayDatum.new(value.data)
30
32
  when Scalar
31
33
  ScalarDatum.new(value)
32
34
  when ::Array
@@ -0,0 +1,29 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one
2
+ # or more contributor license agreements. See the NOTICE file
3
+ # distributed with this work for additional information
4
+ # regarding copyright ownership. The ASF licenses this file
5
+ # to you under the Apache License, Version 2.0 (the
6
+ # "License"); you may not use this file except in compliance
7
+ # with the License. You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+
18
+ module Arrow
19
+ class DayTimeIntervalArrayBuilder
20
+ private
21
+ def convert_to_arrow_value(value)
22
+ if value.is_a?(Hash)
23
+ Arrow::DayMillisecond.new(value[:day], value[:millisecond])
24
+ else
25
+ value
26
+ end
27
+ end
28
+ end
29
+ end
@@ -42,16 +42,26 @@ module Arrow
42
42
  end
43
43
 
44
44
  private
45
+ def precision
46
+ @precision ||= value_data_type.precision
47
+ end
48
+
49
+ def scale
50
+ @scale ||= value_data_type.scale
51
+ end
52
+
45
53
  def normalize_value(value)
46
54
  case value
47
- when String
48
- Decimal128.new(value)
49
- when Float
50
- Decimal128.new(value.to_s)
51
55
  when BigDecimal
52
- Decimal128.new(value.to_s)
56
+ if value.nan? or value.infinite?
57
+ message = "can't use #{value} as an Arrow::Decimal128Array value"
58
+ raise FloatDomainError, message
59
+ end
60
+ integer, decimal = value.to_s("f").split(".", 2)
61
+ decimal = decimal[0, scale].ljust(scale, "0")
62
+ Decimal128.new("#{integer}.#{decimal}")
53
63
  else
54
- value
64
+ Decimal128.try_convert(value) || value
55
65
  end
56
66
  end
57
67
  end
@@ -17,6 +17,20 @@
17
17
 
18
18
  module Arrow
19
19
  class Decimal128
20
+ class << self
21
+ # @api private
22
+ def try_convert(value)
23
+ case value
24
+ when String
25
+ new(value)
26
+ when Float
27
+ new(value.to_s)
28
+ else
29
+ nil
30
+ end
31
+ end
32
+ end
33
+
20
34
  alias_method :to_s_raw, :to_s
21
35
 
22
36
  # @overload to_s
@@ -45,16 +45,26 @@ module Arrow
45
45
  end
46
46
 
47
47
  private
48
+ def precision
49
+ @precision ||= value_data_type.precision
50
+ end
51
+
52
+ def scale
53
+ @scale ||= value_data_type.scale
54
+ end
55
+
48
56
  def normalize_value(value)
49
57
  case value
50
- when String
51
- Decimal256.new(value)
52
- when Float
53
- Decimal256.new(value.to_s)
54
58
  when BigDecimal
55
- Decimal256.new(value.to_s)
59
+ if value.nan? or value.infinite?
60
+ message = "can't use #{value} as an Arrow::Decimal256Array value"
61
+ raise FloatDomainError, message
62
+ end
63
+ integer, decimal = value.to_s("f").split(".", 2)
64
+ decimal = decimal[0, scale].ljust(scale, "0")
65
+ Decimal256.new("#{integer}.#{decimal}")
56
66
  else
57
- value
67
+ Decimal256.try_convert(value) || value
58
68
  end
59
69
  end
60
70
  end
@@ -17,6 +17,20 @@
17
17
 
18
18
  module Arrow
19
19
  class Decimal256
20
+ class << self
21
+ # @api private
22
+ def try_convert(value)
23
+ case value
24
+ when String
25
+ new(value)
26
+ when Float
27
+ new(value.to_s)
28
+ else
29
+ nil
30
+ end
31
+ end
32
+ end
33
+
20
34
  alias_method :to_s_raw, :to_s
21
35
 
22
36
  # @overload to_s