Commits


Jeffrey Mullins authored and GitHub committed 411b6b9cbe4
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 <jmullins31@bloomberg.net> Co-authored-by: Fokko Driesprong <fokko@apache.org>