Uploaded image for project: 'Apache Avro'
  1. Apache Avro
  2. AVRO-2885

Providing a decimal number in an int field doesn't return an error

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Major
    • Resolution: Fixed
    • 1.8.2, 1.10.0, 1.9.2
    • 1.12.0
    • java

    Description

      I defined a schema with an int field and I'm then using the Java GenericDatumReader to decode records from JSON: I have noticed that the reader also accepts numbers with decimal digits and the resulting record contains the same numbers, coerced to integer values.Here is a runnable example:

      import org.apache.avro.Schema;
      import org.apache.avro.SchemaBuilder;
      import org.apache.avro.generic.GenericDatumReader;
      import org.apache.avro.generic.GenericRecord;
      import org.apache.avro.io.Decoder;
      import org.apache.avro.io.DecoderFactory;
      
      public class AvroIntTest {
      
          public static GenericRecord readFromJson(Schema schema, String record) throws Exception {
              GenericDatumReader<GenericRecord> reader = new GenericDatumReader<>(schema, schema);
              Decoder decoder = DecoderFactory.get().jsonDecoder(schema, record);
              return reader.read(null, decoder);
          }
      
          public static void main(String[] args) throws Exception {
              Schema schema = SchemaBuilder
                      .builder("test")
                      .record("example")
                      .fields()
                      .requiredInt("id")
                      .endRecord();
              String record = "{ \"id\": -1.2 }";
      
              System.out.println(readFromJson(schema, record)); // prints: { "id": -1 }
          }
      
      }
      

      The schema generated by the builder looks like this:

      {
        "type" : "record",
        "name" : "example",
        "namespace" : "test",
        "fields" : [ {
          "name" : "id",
          "type" : "int"
        } ]
      }
      

      I would expect the reader to fail because the type of the value doesn't match the type of the field but it instead "silently" succeeds, converting -1.2 to -1: is this behaviour intended? am I doing something wrong?

      Edit: Digging into it further, I think that the observed behavior is an effect of this line: https://github.com/apache/avro/blob/release-1.8.2/lang/java/avro/src/main/java/org/apache/avro/io/JsonDecoder.java#L168)

      A similar test with the JS implementation seems to confirm that it's not intended behavior:

      var avro = require('avro-js');
      
      var schema = avro.parse('{ "type" : "record", "name" : "example", "namespace" : "test", "fields" : [ { "name" : "id", "type" : "int" } ] }');
      var data = {id: -1.2};
      
      schema.toBuffer(data);
      

      returns, when run:

      Error: invalid "int": -1.2
      

      Attachments

        Issue Links

          Activity

            People

              clesaec Christophe Le Saec
              freidereikhs Federico Ragona
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Time Tracking

                  Estimated:
                  Original Estimate - Not Specified
                  Not Specified
                  Remaining:
                  Remaining Estimate - 0h
                  0h
                  Logged:
                  Time Spent - 40m
                  40m