[
https://issues.apache.org/jira/browse/AVRO-2636?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16985323#comment-16985323
]
Valentin Nikotin commented on AVRO-2636:
----------------------------------------
Hi!
Return of {{bb.duplicate }}solves my problem. The way I use
{{getDefaultValue(field)}} is to get default values during converting
GenericRecords into another format. I have unit tests with random Avro schemas
with random default for every possible type, and realized it failed on defaults
for Byte type. Decimal was just more real-world example of the problem.
I agree about Fixed too, strong warning should be enough to preserve people
from the optimization to reuse the same {{byte[]}}, while I can't think any
reasonable way to reuse, there might be some possible security issues though.
On the other hand copying arrays just for safety reason may affect performance,
having safe/unsafe {{getDefaultValue}} methods would be confusing.
> GenericData defaultValueCache caches mutable ByteBuffers
> --------------------------------------------------------
>
> Key: AVRO-2636
> URL: https://issues.apache.org/jira/browse/AVRO-2636
> Project: Apache Avro
> Issue Type: Bug
> Components: java
> Reporter: Valentin Nikotin
> Priority: Minor
>
> It appears that for default value for Byte type (and Decimal logical type if
> it uses underlying Bytes type) value rendered with getDefaultValue is cached.
> This leads to bugs when you read the same value (for example if converted
> with DecimalConversion). For single thread environment workaround would be to
> reset ByteBuffer after read, but in concurrent environment we should not
> cache mutable objects.
>
> {code:java}
> @Test(expected=NumberFormatException.class)
> public void testReuse() {
> Conversions.DecimalConversion decimalConversion =
> new Conversions.DecimalConversion();
> LogicalType logicalDecimal =
> LogicalTypes.decimal(38, 9);
> ByteBuffer defaultValue =
> decimalConversion.toBytes(
> BigDecimal.valueOf(42L).setScale(9),
> null,
> logicalDecimal);
> Schema schema = SchemaBuilder
> .record("test")
> .fields()
> .name("decimal")
>
> .type(logicalDecimal.addToSchema(SchemaBuilder.builder().bytesType()))
> .withDefault(defaultValue)
> .endRecord();
> BigDecimal firstRead = decimalConversion
> .fromBytes(
> (ByteBuffer)
> GenericData.get().getDefaultValue(schema.getField("decimal")),
> null,
> logicalDecimal);
> BigDecimal secondRead = decimalConversion
> .fromBytes(
> (ByteBuffer)
> GenericData.get().getDefaultValue(schema.getField("decimal")),
> null,
> logicalDecimal);
> }
> {code}
--
This message was sent by Atlassian Jira
(v8.3.4#803005)