Skip to content

Commit

Permalink
[fastserde] Fix issue with generating schema fingerprint
Browse files Browse the repository at this point in the history
when NaN is a default value.
  • Loading branch information
krisso-rtb committed Aug 29, 2023
1 parent ecebef2 commit 1cea078
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"type": "record",
"name": "FloatWithDefaultNaN",
"namespace": "com.linkedin.avro.fastserde.generated.avro",
"doc": "Used to verify Utils.getSchemaFingerprint() method",
"fields": [
{
"name": "floatWithDefaultNaN",
"type": "float",
"default": "NaN"
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,34 @@
import org.testng.Assert;
import org.testng.annotations.Test;

import com.linkedin.avro.fastserde.generated.avro.FloatWithDefaultNaN;


public class UtilsTest {

@Test (groups = "deserializationTest")
public void testGenerateSourcePathFromPackageName() {
Assert.assertEquals(Utils.generateSourcePathFromPackageName("com.linkedin.avro"), Utils.fixSeparatorsToMatchOS("/com/linkedin/avro/"));
}

@Test
void testDefaultValueNaN() {
// given
FloatWithDefaultNaN floatWithDefaultNaN = FloatWithDefaultNaN.newBuilder().build();

// when
float defaultValue = floatWithDefaultNaN.getFloatWithDefaultNaN();

// then
Assert.assertTrue(Float.isNaN(defaultValue));
}

@Test
void testFingerprintOfSchemaWithDefaultNaN() {
// when
int schemaFingerprint = Utils.getSchemaFingerprint(FloatWithDefaultNaN.SCHEMA$);

// then
Assert.assertEquals(schemaFingerprint, 502051122);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -143,20 +143,19 @@ public static boolean isRoundNumber(JsonNode node) {
* Enforces uniform numeric default values across Avro versions
*/
public static JsonNode enforceUniformNumericDefaultValues(Schema.Field field, JsonNode genericDefaultValue) {
BigDecimal numericDefaultValue = genericDefaultValue.decimalValue();
Schema schema = field.schema();
// a default value for a union, must match the first element of the union
Schema.Type defaultType = schema.getType() == UNION ? schema.getTypes().get(0).getType() : schema.getType();

switch (defaultType) {
case INT:
if (!isAMathematicalInteger(numericDefaultValue)) {
if (!isAMathematicalInteger(genericDefaultValue.decimalValue())) {
LOGGER.warn(String.format("Invalid default value: %s for \"int\" field: %s", genericDefaultValue, field.name()));
return genericDefaultValue;
}
return new IntNode(genericDefaultValue.intValue());
case LONG:
if (!isAMathematicalInteger(numericDefaultValue)) {
if (!isAMathematicalInteger(genericDefaultValue.decimalValue())) {
LOGGER.warn(String.format("Invalid default value: %s for \"long\" field: %s", genericDefaultValue, field.name()));
return genericDefaultValue;
}
Expand Down

0 comments on commit 1cea078

Please sign in to comment.