You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by rs...@apache.org on 2021/08/26 16:28:57 UTC

[avro] branch master updated: AVRO-2648: Incorrect validation of numeric default values (#739)

This is an automated email from the ASF dual-hosted git repository.

rskraba pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/avro.git


The following commit(s) were added to refs/heads/master by this push:
     new 411b6b9  AVRO-2648: Incorrect validation of numeric default values (#739)
411b6b9 is described below

commit 411b6b9cbe4046abdc9cc4293ebd9f2548f37b64
Author: Jeffrey Mullins <mu...@gmail.com>
AuthorDate: Thu Aug 26 12:28:18 2021 -0400

    AVRO-2648: Incorrect validation of numeric default values (#739)
    
    * AVRO-2648: Incorrect validation of numeric default values
    
    Validation of numeric default values in Java is incorrect and results
    in API inconsistencies. Consider the following examples:
    
    Double values as int field default values:
    public void testDoubleAsIntDefaultValue() {
      Schema.Field field = new Schema.Field("myField",
              Schema.create(Schema.Type.INT), "doc", 1.1);
      field.hasDefaultValue(); // true
      field.defaultValue(); // internal DoubleNode (1.1)
      field.defaultVal(); // null
      GenericData.get().getDefaultValue(field); // Integer (1)
    
      field = new Schema.Field("myField",
              Schema.create(Schema.Type.INT), "doc", 1.0);
      field.hasDefaultValue(); // true
      field.defaultValue(); // internal DoubleNode (1.0)
      field.defaultVal(); // null
      GenericData.get().getDefaultValue(field); // Integer (1)
    }
    
    Invalid long value as int field default value:
    public void testInvalidLongAsIntDefault() {
      Schema.Field field = new Schema.Field("myField",
             Schema.create(Schema.Type.INT), "doc", Integer.MAX_VALUE + 1L);
      field.hasDefaultValue(); // true
      field.defaultValue(); // internal LongNode (2147483648)
      field.defaultVal(); // Long (2147483648)
      GenericData.get().getDefaultValue(field); // Integer (-2147483648)
    }
    
    This PR makes changes to invalidate incorrect default values for INT and
    LONG schemas, including all floating point values, e.g. 1.0.
    Additionally it contains changes to try and return the appropriate
    Object type given the schema type.
    
    This change is necessary for correctness and consitency but also
    because users cannot disable default value validation and handle
    these cases on their own since the underlying Field.defaultValue()
    is no longer public. Users only have access to default values
    mutated by Field.defaultVal() and GenericData.getDefaultValue().
    
    Notes on JacksonUtils.toObject():
     - This method is used to convert the underlying JsonNode default value
      to an Object when Field.defaultVal() is called. This method is
      invoked regardless of whether default value validation is true or
      false.
     - For LongNode values we continue to return Long values for INT
       schemas in the case we cannot safely convert to an Integer.
       This behavior, while maintained, is inconsistent with that
       of FloatNode / DoubleNode where null is returned for INT
       and LONG schemas. Additional changes may be needed for
       further consistency.
    
    * AVRO-2648: Fix testLongDefaultValue()
    
    Co-authored-by: Jeffrey Mullins <jm...@bloomberg.net>
    Co-authored-by: Fokko Driesprong <fo...@apache.org>
---
 lang/java/avro/src/test/java/org/apache/avro/TestSchema.java | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lang/java/avro/src/test/java/org/apache/avro/TestSchema.java b/lang/java/avro/src/test/java/org/apache/avro/TestSchema.java
index 90d235b..4b2a78b 100644
--- a/lang/java/avro/src/test/java/org/apache/avro/TestSchema.java
+++ b/lang/java/avro/src/test/java/org/apache/avro/TestSchema.java
@@ -216,6 +216,7 @@ public class TestSchema {
     assertEquals(parent, parentWithoutInlinedChildReference);
   }
 
+  @Test
   public void testIntDefaultValue() {
     Schema.Field field = new Schema.Field("myField", Schema.create(Schema.Type.INT), "doc", 1);
     assertTrue(field.hasDefaultValue());