avro 1.11.1 → 1.11.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 660434b4d31525eed0d771a26e10c3753856fa45797e55845a82b4a8d4b2361c
4
- data.tar.gz: a44c0c7af2a5a030c648d5cc3705ae2ea092fccb3d58ccf9186f4f4619d79092
3
+ metadata.gz: 124c809b0bcf3463852b754fb01cf2b75e4d90547a934d8932a27f52a3264b69
4
+ data.tar.gz: e293185ed5b05dd1aaf6837dc9a64748cd0d26fbba8ab5fc0a4b608cca7ab244
5
5
  SHA512:
6
- metadata.gz: a7eb879efaea928bf6a8d39079f0b6d92381c3905fcae130c37e1e426f33f940b13b028df43ebcf5ce0bb40dc996efd4c88d7bea5b7b6088715c2677a48146d5
7
- data.tar.gz: 9657974edde8c940074930808706554c9db9390f061f573830194cdd9167fed1c46c1811b188cf598cc2a48673874e2af41d43c73ce74ff7c620594e641f4831
6
+ metadata.gz: 677e4fc7525cea9ac5309b891bb88b60c2421ee58add86d90efa3fa0731199b6cbb2f0bb2b7db42c9237f54a36fb5dda49de649fb5d40810d73f1c7084d9e290
7
+ data.tar.gz: e0bcfcd4f139ad961ae0af5ecac5eba24d6cfaab866487bd8c06918158d7e0f8307b33fc550cd35c2a75cc93fa75851c038a85a2f27f8eed123bf16219d07105
data/lib/avro/VERSION.txt CHANGED
@@ -1 +1 @@
1
- 1.11.1
1
+ 1.11.3
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
- return nil
395
+ nil
396
396
  when :int, :long
397
- return Integer(default_value)
397
+ Integer(default_value)
398
398
  when :float, :double
399
- return Float(default_value)
399
+ Float(default_value)
400
400
  when :boolean, :enum, :fixed, :string, :bytes
401
- return default_value
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
- return read_array
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
- return read_map
415
+ read_map
416
416
  when :union
417
- return read_default_value(field_schema.schemas[0], default_value)
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
- return read_record
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
@@ -111,7 +111,7 @@ module Avro
111
111
  elsif PRIMITIVE_TYPES.include? json_obj
112
112
  return PrimitiveSchema.new(json_obj)
113
113
  else
114
- raise UnknownSchemaError.new(json_obj)
114
+ raise UnknownSchemaError.new(json_obj, default_namespace)
115
115
  end
116
116
  end
117
117
 
@@ -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
- Avro::SchemaValidator.validate!(type_for_default, default)
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
@@ -611,9 +621,11 @@ module Avro
611
621
 
612
622
  class UnknownSchemaError < SchemaParseError
613
623
  attr_reader :type_name
624
+ attr_reader :default_namespace
614
625
 
615
- def initialize(type)
626
+ def initialize(type, default_namespace)
616
627
  @type_name = type
628
+ @default_namespace = default_namespace
617
629
  super("#{type.inspect} is not a schema we know about.")
618
630
  end
619
631
  end
@@ -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 1, :>=, report.total_retained
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(schema, schema)
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
@@ -176,6 +176,8 @@ class TestSchema < Test::Unit::TestCase
176
176
  end
177
177
 
178
178
  assert_equal '"MissingType" is not a schema we know about.', error.message
179
+ assert_equal "MissingType", error.type_name
180
+ assert_equal "my.name.space", error.default_namespace
179
181
  end
180
182
 
181
183
  def test_invalid_name
@@ -612,6 +614,37 @@ class TestSchema < Test::Unit::TestCase
612
614
  assert_equal schema_hash, schema.to_avro
613
615
  end
614
616
 
617
+ def test_bytes_decimal_in_record
618
+ assert_nothing_raised do
619
+ hash_to_schema(
620
+ type: 'record',
621
+ name: 'account',
622
+ fields: [
623
+ { name: 'balance', type: 'bytes', logicalType: 'decimal', precision: 9, scale: 2 }
624
+ ]
625
+ )
626
+ end
627
+ end
628
+
629
+ def test_bytes_decimal_with_default_in_record
630
+ assert_nothing_raised do
631
+ hash_to_schema(
632
+ type: 'record',
633
+ name: 'account',
634
+ fields: [
635
+ {
636
+ name: 'balance',
637
+ type: [
638
+ { type: 'bytes', logicalType: 'decimal', precision: 9, scale: 2 },
639
+ 'null'
640
+ ],
641
+ default: '\u00ff'
642
+ }
643
+ ]
644
+ )
645
+ end
646
+ end
647
+
615
648
  def test_bytes_decimal_to_include_precision_scale
616
649
  schema = Avro::Schema.parse <<-SCHEMA
617
650
  {
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.1
4
+ version: 1.11.3
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: 2022-07-26 00:00:00.000000000 Z
11
+ date: 2023-09-15 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.1/
75
+ documentation_uri: https://avro.apache.org/docs/1.11.3/
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: