Hi all,

I do not have a lot of experience using Avro, so hopefully this is not an
obvious question (and I hope this is the right place to ask):

I have a schema with a decimal logical type, e.g.,

{
  "type" : "record",
  "name" : "testRecord",
  "namespace" : "org.example",
  "doc" : "",
  "fields" : [
    {
      "name" : "value",
      "type":[
        "null",
        {
          "type":"bytes",
          "logicalType":"decimal",
          "precision":12,
          "scale":4
        }
      ],
      "doc":"",
      "default":null
    }
  ]
}

And I have a code that parses this schema and creates a GenericRecord based
on that then puts a BigDecimal for "value" (I have copied the full code at
the end). The problem is that when I write this record to file, I get the
following exception which IIUC is coming from the fact that there are no
conversions registered for BigDecimal here
<https://github.com/apache/avro/blob/9a6aa43c8699ccde7bef485206928acb35378bdb/lang/java/avro/src/main/java/org/apache/avro/generic/GenericData.java#L859>
:

org.apache.avro.file.DataFileWriter$AppendWriteException:
org.apache.avro.AvroRuntimeException:
Unknown datum type java.math.BigDecimal: 10.0
   at org.apache.avro.file.DataFileWriter.append (DataFileWriter.java:317)
   at org.openmrs.analytics.TestAvro.main (TestAvro.java:25)
   at org.codehaus.mojo.exec.ExecJavaMojo$1.run (ExecJavaMojo.java:254)
   at java.lang.Thread.run (Thread.java:834)
Caused by: org.apache.avro.AvroRuntimeException: Unknown datum type
java.math.BigDecimal: 10.0
   at org.apache.avro.generic.GenericData.getSchemaName (
GenericData.java:912)
   at org.apache.avro.generic.GenericData.resolveUnion (GenericData.java:874
)
   at org.apache.avro.generic.GenericDatumWriter.resolveUnion (
GenericDatumWriter.java:272)
   at org.apache.avro.generic.GenericDatumWriter.writeWithoutConversion (
GenericDatumWriter.java:143)
   at org.apache.avro.generic.GenericDatumWriter.write (
GenericDatumWriter.java:83)
   at org.apache.avro.generic.GenericDatumWriter.writeField (
GenericDatumWriter.java:221)
   at org.apache.avro.generic.GenericDatumWriter.writeRecord (
GenericDatumWriter.java:210)
   at org.apache.avro.generic.GenericDatumWriter.writeWithoutConversion (
GenericDatumWriter.java:131)
   at org.apache.avro.generic.GenericDatumWriter.write (
GenericDatumWriter.java:83)
   at org.apache.avro.generic.GenericDatumWriter.write (
GenericDatumWriter.java:73)
   at org.apache.avro.file.DataFileWriter.append (DataFileWriter.java:314)
   at org.openmrs.analytics.TestAvro.main (TestAvro.java:25)
   at org.codehaus.mojo.exec.ExecJavaMojo$1.run (ExecJavaMojo.java:254)
   at java.lang.Thread.run (Thread.java:834)

But my understanding is that BigDecimal is the right type for the Avro
decimal logical type, is that correct? If yes, shouldn't this approach
work? I can do a conversion from BigDecimal to ByteBuffer but that is
something that I want to avoid because in my real use case, I am receiving
GenericRecord from another library that creates the schema too, possibly
with many such logical types. Here is the full code:

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;

import org.apache.avro.Schema;
import org.apache.avro.file.DataFileWriter;
import org.apache.avro.generic.GenericData.Record;
import org.apache.avro.generic.GenericDatumWriter;
import org.apache.avro.generic.GenericRecord;
import org.apache.avro.io.DatumWriter;

public class TestAvro {
  public static void main(String[] args) throws IOException {
    Schema testSchema = new Schema.Parser().parse(new
File("tmp/test_decimal_union.avsc"));
    GenericRecord testRecord = new Record(testSchema);
    testRecord.put("value", BigDecimal.valueOf(10.0));
    DatumWriter<GenericRecord> datumWriter = new
GenericDatumWriter<>(testSchema);
    DataFileWriter<GenericRecord> dataFileWriter = new
DataFileWriter<GenericRecord>(datumWriter);
    File testFile = new File("tmp/test_decimal.avro");
    dataFileWriter.create(testSchema, testFile);
    dataFileWriter.append(testRecord);
    dataFileWriter.close();
}

Any help is appreciated.

-B

Reply via email to