avro 1.11.1 → 1.11.2
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.
- checksums.yaml +4 -4
- data/lib/avro/VERSION.txt +1 -1
- data/lib/avro/io.rb +11 -9
- data/lib/avro/schema.rb +12 -2
- data/test/test_logical_types.rb +112 -4
- data/test/test_schema.rb +31 -0
- metadata +6 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8804cb557ca9c4e16ffc22fe8de2c7e91b20c63bc8ba3ccc439e2891e463cb38
|
|
4
|
+
data.tar.gz: 511b69a9797a0dab27313837d347db8512434c851492b21e7618aa34e50cbe7f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8469a31eb4739efb59f849dadb7dd321820ab6df351a556f95a85b87279abc3a5ff1e70501178e58205e11b7774ea8f54d46faf807f05ab254085707b9a1897a
|
|
7
|
+
data.tar.gz: 39304274da622e79f450025c558187df06d7d8e3961965225c94df5c58bb57c9cf924faf16e1e15db8ffe710cbee3747a7703e0b0eb2b5ee1ddf9d0cef5efa0c
|
data/lib/avro/VERSION.txt
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.11.
|
|
1
|
+
1.11.2
|
data/lib/avro/io.rb
CHANGED
|
@@ -390,31 +390,31 @@ module Avro
|
|
|
390
390
|
|
|
391
391
|
def read_default_value(field_schema, default_value)
|
|
392
392
|
# Basically a JSON Decoder?
|
|
393
|
-
case field_schema.type_sym
|
|
393
|
+
datum = case field_schema.type_sym
|
|
394
394
|
when :null
|
|
395
|
-
|
|
395
|
+
nil
|
|
396
396
|
when :int, :long
|
|
397
|
-
|
|
397
|
+
Integer(default_value)
|
|
398
398
|
when :float, :double
|
|
399
|
-
|
|
399
|
+
Float(default_value)
|
|
400
400
|
when :boolean, :enum, :fixed, :string, :bytes
|
|
401
|
-
|
|
401
|
+
default_value
|
|
402
402
|
when :array
|
|
403
403
|
read_array = []
|
|
404
404
|
default_value.each do |json_val|
|
|
405
405
|
item_val = read_default_value(field_schema.items, json_val)
|
|
406
406
|
read_array << item_val
|
|
407
407
|
end
|
|
408
|
-
|
|
408
|
+
read_array
|
|
409
409
|
when :map
|
|
410
410
|
read_map = {}
|
|
411
411
|
default_value.each do |key, json_val|
|
|
412
412
|
map_val = read_default_value(field_schema.values, json_val)
|
|
413
413
|
read_map[key] = map_val
|
|
414
414
|
end
|
|
415
|
-
|
|
415
|
+
read_map
|
|
416
416
|
when :union
|
|
417
|
-
|
|
417
|
+
read_default_value(field_schema.schemas[0], default_value)
|
|
418
418
|
when :record, :error
|
|
419
419
|
read_record = {}
|
|
420
420
|
field_schema.fields.each do |field|
|
|
@@ -423,11 +423,13 @@ module Avro
|
|
|
423
423
|
field_val = read_default_value(field.type, json_val)
|
|
424
424
|
read_record[field.name] = field_val
|
|
425
425
|
end
|
|
426
|
-
|
|
426
|
+
read_record
|
|
427
427
|
else
|
|
428
428
|
fail_msg = "Unknown type: #{field_schema.type}"
|
|
429
429
|
raise AvroError, fail_msg
|
|
430
430
|
end
|
|
431
|
+
|
|
432
|
+
field_schema.type_adapter.decode(datum)
|
|
431
433
|
end
|
|
432
434
|
|
|
433
435
|
def skip_data(writers_schema, decoder)
|
data/lib/avro/schema.rb
CHANGED
|
@@ -126,6 +126,7 @@ module Avro
|
|
|
126
126
|
def initialize(type, logical_type=nil)
|
|
127
127
|
@type_sym = type.is_a?(Symbol) ? type : type.to_sym
|
|
128
128
|
@logical_type = logical_type
|
|
129
|
+
@type_adapter = nil
|
|
129
130
|
end
|
|
130
131
|
|
|
131
132
|
attr_reader :type_sym
|
|
@@ -571,6 +572,7 @@ module Avro
|
|
|
571
572
|
@order = order
|
|
572
573
|
@doc = doc
|
|
573
574
|
@aliases = aliases
|
|
575
|
+
@type_adapter = nil
|
|
574
576
|
validate_aliases! if aliases
|
|
575
577
|
validate_default! if default? && !Avro.disable_field_default_validation
|
|
576
578
|
end
|
|
@@ -599,8 +601,16 @@ module Avro
|
|
|
599
601
|
else
|
|
600
602
|
type
|
|
601
603
|
end
|
|
602
|
-
|
|
603
|
-
|
|
604
|
+
case type_for_default.logical_type
|
|
605
|
+
when DECIMAL_LOGICAL_TYPE
|
|
606
|
+
# https://avro.apache.org/docs/1.11.1/specification/#schema-record
|
|
607
|
+
# Default values for bytes and fixed fields are JSON strings, where Unicode code points 0-255 are mapped to unsigned 8-bit byte values 0-255
|
|
608
|
+
options = SchemaValidator::DEFAULT_VALIDATION_OPTIONS.dup
|
|
609
|
+
options[:encoded] = true
|
|
610
|
+
Avro::SchemaValidator.validate!(type_for_default, default, options)
|
|
611
|
+
else
|
|
612
|
+
Avro::SchemaValidator.validate!(type_for_default, default)
|
|
613
|
+
end
|
|
604
614
|
rescue Avro::SchemaValidator::ValidationError => e
|
|
605
615
|
raise Avro::SchemaParseError, "Error validating default for #{name}: #{e.message}"
|
|
606
616
|
end
|
data/test/test_logical_types.rb
CHANGED
|
@@ -124,6 +124,113 @@ class TestLogicalTypes < Test::Unit::TestCase
|
|
|
124
124
|
end
|
|
125
125
|
end
|
|
126
126
|
|
|
127
|
+
def test_logical_type_default_value
|
|
128
|
+
sales_schema = Avro::Schema.parse('{
|
|
129
|
+
"type": "record",
|
|
130
|
+
"name": "Order",
|
|
131
|
+
"fields" : [
|
|
132
|
+
{
|
|
133
|
+
"name": "sales",
|
|
134
|
+
"type": [
|
|
135
|
+
{
|
|
136
|
+
"type": "bytes",
|
|
137
|
+
"logicalType": "decimal",
|
|
138
|
+
"precision": 4,
|
|
139
|
+
"scale": 2
|
|
140
|
+
},
|
|
141
|
+
"null"
|
|
142
|
+
],
|
|
143
|
+
"default": "\u0000"
|
|
144
|
+
}
|
|
145
|
+
]
|
|
146
|
+
}')
|
|
147
|
+
|
|
148
|
+
sales_tax_schema = Avro::Schema.parse('{
|
|
149
|
+
"type": "record",
|
|
150
|
+
"name": "Order",
|
|
151
|
+
"fields" : [
|
|
152
|
+
{
|
|
153
|
+
"name": "sales",
|
|
154
|
+
"type": [
|
|
155
|
+
{
|
|
156
|
+
"type": "bytes",
|
|
157
|
+
"logicalType": "decimal",
|
|
158
|
+
"precision": 4,
|
|
159
|
+
"scale": 2
|
|
160
|
+
},
|
|
161
|
+
"null"
|
|
162
|
+
],
|
|
163
|
+
"default": "\u0000"
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
"name": "tax",
|
|
167
|
+
"type": [
|
|
168
|
+
{
|
|
169
|
+
"type": "bytes",
|
|
170
|
+
"logicalType": "decimal",
|
|
171
|
+
"precision": 4,
|
|
172
|
+
"scale": 2
|
|
173
|
+
},
|
|
174
|
+
"null"
|
|
175
|
+
],
|
|
176
|
+
"default": "\u0000"
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
"name": "invoice_date",
|
|
180
|
+
"type": [
|
|
181
|
+
{
|
|
182
|
+
"type": "int",
|
|
183
|
+
"logicalType": "date"
|
|
184
|
+
},
|
|
185
|
+
"null"
|
|
186
|
+
],
|
|
187
|
+
"default": 0
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
"name": "invoice_time",
|
|
191
|
+
"type": [
|
|
192
|
+
{
|
|
193
|
+
"type": "int",
|
|
194
|
+
"logicalType": "time-millis"
|
|
195
|
+
},
|
|
196
|
+
"null"
|
|
197
|
+
],
|
|
198
|
+
"default": 0
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
"name": "created_at",
|
|
202
|
+
"type": [
|
|
203
|
+
{
|
|
204
|
+
"type": "long",
|
|
205
|
+
"logicalType": "timestamp-millis"
|
|
206
|
+
},
|
|
207
|
+
"null"
|
|
208
|
+
],
|
|
209
|
+
"default": 0
|
|
210
|
+
}
|
|
211
|
+
]
|
|
212
|
+
}')
|
|
213
|
+
|
|
214
|
+
sales_record = {"sales" => BigDecimal("12.34")}
|
|
215
|
+
sales_tax_record = {
|
|
216
|
+
"sales" => BigDecimal("12.34"),
|
|
217
|
+
"tax" => BigDecimal("0.000"),
|
|
218
|
+
"invoice_date" => Time.at(0).to_date,
|
|
219
|
+
# time-millis is not supported
|
|
220
|
+
"invoice_time" => 0,
|
|
221
|
+
"created_at" => Time.at(0).utc,
|
|
222
|
+
}
|
|
223
|
+
encoded = encode(sales_record, sales_schema)
|
|
224
|
+
assert_equal sales_record, decode(encoded, sales_schema)
|
|
225
|
+
# decode with different schema applies default
|
|
226
|
+
assert_equal sales_tax_record, decode(encoded, sales_tax_schema, writer_schema: sales_schema)
|
|
227
|
+
|
|
228
|
+
# decode with same schema does not apply default, since it is nullable during encode
|
|
229
|
+
encoded = encode(sales_record, sales_tax_schema)
|
|
230
|
+
tax_nil_record = {"sales" => BigDecimal("12.34"), "tax" => nil, "invoice_date" => nil, "invoice_time" => nil, "created_at" => nil}
|
|
231
|
+
assert_equal tax_nil_record, decode(encoded, sales_tax_schema)
|
|
232
|
+
end
|
|
233
|
+
|
|
127
234
|
def test_bytes_decimal_range_errors
|
|
128
235
|
schema = Avro::Schema.parse <<-SCHEMA
|
|
129
236
|
{ "type": "bytes", "logicalType": "decimal", "precision": 4, "scale": 2 }
|
|
@@ -230,8 +337,8 @@ class TestLogicalTypes < Test::Unit::TestCase
|
|
|
230
337
|
end
|
|
231
338
|
|
|
232
339
|
assert_equal 5, report.total_allocated
|
|
233
|
-
# Ruby 2.7 does not retain anything. Ruby 2.6 retains 1
|
|
234
|
-
assert_operator
|
|
340
|
+
# Ruby 2.7 does not retain anything. Ruby 2.6 retains 1 or 2
|
|
341
|
+
assert_operator 2, :>=, report.total_retained
|
|
235
342
|
end
|
|
236
343
|
end
|
|
237
344
|
|
|
@@ -245,11 +352,12 @@ class TestLogicalTypes < Test::Unit::TestCase
|
|
|
245
352
|
buffer.string
|
|
246
353
|
end
|
|
247
354
|
|
|
248
|
-
def decode(encoded, schema)
|
|
355
|
+
def decode(encoded, schema, writer_schema: nil)
|
|
356
|
+
writer_schema ||= schema
|
|
249
357
|
buffer = StringIO.new(encoded)
|
|
250
358
|
decoder = Avro::IO::BinaryDecoder.new(buffer)
|
|
251
359
|
|
|
252
|
-
datum_reader = Avro::IO::DatumReader.new(
|
|
360
|
+
datum_reader = Avro::IO::DatumReader.new(writer_schema, schema)
|
|
253
361
|
datum_reader.read(decoder)
|
|
254
362
|
end
|
|
255
363
|
|
data/test/test_schema.rb
CHANGED
|
@@ -612,6 +612,37 @@ class TestSchema < Test::Unit::TestCase
|
|
|
612
612
|
assert_equal schema_hash, schema.to_avro
|
|
613
613
|
end
|
|
614
614
|
|
|
615
|
+
def test_bytes_decimal_in_record
|
|
616
|
+
assert_nothing_raised do
|
|
617
|
+
hash_to_schema(
|
|
618
|
+
type: 'record',
|
|
619
|
+
name: 'account',
|
|
620
|
+
fields: [
|
|
621
|
+
{ name: 'balance', type: 'bytes', logicalType: 'decimal', precision: 9, scale: 2 }
|
|
622
|
+
]
|
|
623
|
+
)
|
|
624
|
+
end
|
|
625
|
+
end
|
|
626
|
+
|
|
627
|
+
def test_bytes_decimal_with_default_in_record
|
|
628
|
+
assert_nothing_raised do
|
|
629
|
+
hash_to_schema(
|
|
630
|
+
type: 'record',
|
|
631
|
+
name: 'account',
|
|
632
|
+
fields: [
|
|
633
|
+
{
|
|
634
|
+
name: 'balance',
|
|
635
|
+
type: [
|
|
636
|
+
{ type: 'bytes', logicalType: 'decimal', precision: 9, scale: 2 },
|
|
637
|
+
'null'
|
|
638
|
+
],
|
|
639
|
+
default: '\u00ff'
|
|
640
|
+
}
|
|
641
|
+
]
|
|
642
|
+
)
|
|
643
|
+
end
|
|
644
|
+
end
|
|
645
|
+
|
|
615
646
|
def test_bytes_decimal_to_include_precision_scale
|
|
616
647
|
schema = Avro::Schema.parse <<-SCHEMA
|
|
617
648
|
{
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: avro
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.11.
|
|
4
|
+
version: 1.11.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Apache Software Foundation
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2023-06-26 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: multi_json
|
|
@@ -72,9 +72,9 @@ metadata:
|
|
|
72
72
|
homepage_uri: https://avro.apache.org/
|
|
73
73
|
bug_tracker_uri: https://issues.apache.org/jira/browse/AVRO
|
|
74
74
|
source_code_uri: https://github.com/apache/avro
|
|
75
|
-
documentation_uri: https://avro.apache.org/docs/1.11.
|
|
75
|
+
documentation_uri: https://avro.apache.org/docs/1.11.2/
|
|
76
76
|
rubygems_mfa_required: 'true'
|
|
77
|
-
post_install_message:
|
|
77
|
+
post_install_message:
|
|
78
78
|
rdoc_options:
|
|
79
79
|
- "--line-numbers"
|
|
80
80
|
- "--title"
|
|
@@ -93,7 +93,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
93
93
|
version: '0'
|
|
94
94
|
requirements: []
|
|
95
95
|
rubygems_version: 3.1.2
|
|
96
|
-
signing_key:
|
|
96
|
+
signing_key:
|
|
97
97
|
specification_version: 4
|
|
98
98
|
summary: Apache Avro for Ruby
|
|
99
99
|
test_files:
|