[ 
https://issues.apache.org/jira/browse/AVRO-2042?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16050746#comment-16050746
 ] 

Ryan Blue commented on AVRO-2042:
---------------------------------

The problem is that you're converting floats, which causes the BigDecimal code 
to guess what the intended scale is. Instead, you should use the String 
constructor. You can see the tests for an example: 
https://github.com/apache/avro/blob/master/lang/java/avro/src/test/java/org/apache/avro/generic/TestGenericLogicalTypes.java#L140

Another option is to set the scale using 
[setScale|https://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html#setScale(int,%20java.math.RoundingMode)]
 to normalize incoming doubles or floats.

> Can't reliably write decimal/BigDecimal  values to file
> -------------------------------------------------------
>
>                 Key: AVRO-2042
>                 URL: https://issues.apache.org/jira/browse/AVRO-2042
>             Project: Avro
>          Issue Type: Bug
>    Affects Versions: 1.8.2
>            Reporter: Fred Cohen
>         Attachments: AvroDecimal.avsc, AvroDecimalTest.java
>
>
> Attempting to write some decimal values fails.
> Here's the schema I created for this test:
> {
>   "namespace":"org.test",
>   "type": "record",
>   "name": "DecimalTest",
>   "fields": [
>     {
>       "name": "decimalVal",
>       "type": {"type": "bytes", "logicalType":"decimal","precision": 6, 
> "scale": 4}
>        }
>   ]
> }
> The problem is that to my knowledge I can't control the scale used by 
> BigDecimal.
> While the first value uses a scale of 4, the second one is scale 0.
>         decimals.add(new BigDecimal(12.01F, mathContext));
>         decimals.add(new BigDecimal(12.00F, mathContext));
> It leads to these errors during the write operation:
> org.apache.avro.file.DataFileWriter$AppendWriteException: 
> org.apache.avro.AvroTypeException: Cannot encode decimal with scale 0 as 
> scale 4
>       at org.apache.avro.file.DataFileWriter.append(DataFileWriter.java:308)
>       at AvroDecimalTest.writeDecimalTest(AvroDecimalTest.java:67)
>       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>       at 
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
>       at 
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>       at java.lang.reflect.Method.invoke(Method.java:497)
>       at 
> org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
>       at 
> org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
>       at 
> org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
>       at 
> org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
>       at 
> org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
>       at 
> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
>       at 
> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
>       at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
>       at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
>       at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
>       at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
>       at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
>       at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
>       at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
>       at 
> com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
>       at 
> com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
>       at 
> com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
>       at 
> com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
> Caused by: org.apache.avro.AvroTypeException: Cannot encode decimal with 
> scale 0 as scale 4
>       at 
> org.apache.avro.Conversions$DecimalConversion.toBytes(Conversions.java:92)
>       at 
> org.apache.avro.Conversions$DecimalConversion.toBytes(Conversions.java:62)
>       at org.apache.avro.Conversions.convertToRawType(Conversions.java:218)
>       at 
> org.apache.avro.generic.GenericDatumWriter.convert(GenericDatumWriter.java:95)
>       at 
> org.apache.avro.specific.SpecificDatumWriter.writeField(SpecificDatumWriter.java:84)
>       at 
> org.apache.avro.generic.GenericDatumWriter.writeRecord(GenericDatumWriter.java:156)
>       at 
> org.apache.avro.generic.GenericDatumWriter.writeWithoutConversion(GenericDatumWriter.java:118)
>       at 
> org.apache.avro.generic.GenericDatumWriter.write(GenericDatumWriter.java:75)
>       at 
> org.apache.avro.generic.GenericDatumWriter.write(GenericDatumWriter.java:62)
>       at org.apache.avro.file.DataFileWriter.append(DataFileWriter.java:302)
>       ... 23 more



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Reply via email to