Skip to content

Commit

Permalink
NIFI-6117: Fix BIGINT handling in DataTypeUtils
Browse files Browse the repository at this point in the history
Follow numeric type conversion convention used for other integral types.

Signed-off-by: Matthew Burgess <mattyb149@apache.org>

This closes #3371
  • Loading branch information
ijokarumawak authored and joewitt committed Apr 1, 2019
1 parent 5040d94 commit 8a13c68
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1080,15 +1080,11 @@ public static BigInteger toBigInt(final Object value, final String fieldName) {
if (value instanceof BigInteger) {
return (BigInteger) value;
}
if (value instanceof Long) {
return BigInteger.valueOf((Long) value);
}
if (value instanceof Integer) {
return BigInteger.valueOf(((Integer) value).longValue());
}
if (value instanceof Short) {
return BigInteger.valueOf(((Short) value).longValue());

if (value instanceof Number) {
return BigInteger.valueOf(((Number) value).longValue());
}

if (value instanceof String) {
try {
return new BigInteger((String) value);
Expand All @@ -1102,11 +1098,7 @@ public static BigInteger toBigInt(final Object value, final String fieldName) {
}

public static boolean isBigIntTypeCompatible(final Object value) {
return value instanceof BigInteger
|| value instanceof Long
|| value instanceof Integer
|| value instanceof Short
|| value instanceof String;
return isNumberTypeCompatible(value, DataTypeUtils::isIntegral);
}

public static Boolean toBoolean(final Object value, final String fieldName) {
Expand Down Expand Up @@ -1277,7 +1269,10 @@ public static boolean isLongTypeCompatible(final Object value) {
return false;
}

private static boolean isIntegral(final String value, final long minValue, final long maxValue) {
/**
* Check if the value is an integral.
*/
private static boolean isIntegral(final String value) {
if (value == null || value.isEmpty()) {
return false;
}
Expand All @@ -1298,6 +1293,18 @@ private static boolean isIntegral(final String value, final long minValue, final
}
}

return true;
}

/**
* Check if the value is an integral within a value range.
*/
private static boolean isIntegral(final String value, final long minValue, final long maxValue) {

if (!isIntegral(value)) {
return false;
}

try {
final long longValue = Long.parseLong(value);
return longValue >= minValue && longValue <= maxValue;
Expand All @@ -1307,7 +1314,6 @@ private static boolean isIntegral(final String value, final long minValue, final
}
}


public static Integer toInteger(final Object value, final String fieldName) {
if (value == null) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
Expand Down Expand Up @@ -292,27 +293,32 @@ public void testIsCompatibleDataTypeMap() {

@Test
public void testIsCompatibleDataTypeBigint() {
assertTrue(DataTypeUtils.isCompatibleDataType(new BigInteger("12345678901234567890"), RecordFieldType.BIGINT.getDataType()));
assertTrue(DataTypeUtils.isCompatibleDataType(1234567890123456789L, RecordFieldType.BIGINT.getDataType()));
assertTrue(DataTypeUtils.isCompatibleDataType(1, RecordFieldType.BIGINT.getDataType()));
assertTrue(DataTypeUtils.isCompatibleDataType((short) 1, RecordFieldType.BIGINT.getDataType()));
assertTrue(DataTypeUtils.isCompatibleDataType("12345678901234567890", RecordFieldType.BIGINT.getDataType()));
assertTrue(DataTypeUtils.isCompatibleDataType("1234567XYZ", RecordFieldType.BIGINT.getDataType())); // Compatible but the value might not be a valid BigInteger
assertFalse(DataTypeUtils.isCompatibleDataType(3.0f, RecordFieldType.BIGINT.getDataType()));
assertFalse(DataTypeUtils.isCompatibleDataType(3.0, RecordFieldType.BIGINT.getDataType()));
assertFalse(DataTypeUtils.isCompatibleDataType(new Long[]{1L, 2L}, RecordFieldType.BIGINT.getDataType()));
final DataType dataType = RecordFieldType.BIGINT.getDataType();
assertTrue(DataTypeUtils.isCompatibleDataType(new BigInteger("12345678901234567890"), dataType));
assertTrue(DataTypeUtils.isCompatibleDataType(1234567890123456789L, dataType));
assertTrue(DataTypeUtils.isCompatibleDataType(1, dataType));
assertTrue(DataTypeUtils.isCompatibleDataType((short) 1, dataType));
assertTrue(DataTypeUtils.isCompatibleDataType("12345678901234567890", dataType));
assertTrue(DataTypeUtils.isCompatibleDataType(3.1f, dataType));
assertTrue(DataTypeUtils.isCompatibleDataType(3.0, dataType));
assertFalse(DataTypeUtils.isCompatibleDataType("1234567XYZ", dataType));
assertFalse(DataTypeUtils.isCompatibleDataType(new Long[]{1L, 2L}, dataType));
}

@Test
public void testConvertDataTypeBigint() {
assertTrue(DataTypeUtils.convertType(new BigInteger("12345678901234567890"), RecordFieldType.BIGINT.getDataType(), "field") instanceof BigInteger);
assertTrue(DataTypeUtils.convertType(1234567890123456789L, RecordFieldType.BIGINT.getDataType(), "field") instanceof BigInteger);
assertTrue(DataTypeUtils.convertType(1, RecordFieldType.BIGINT.getDataType(), "field") instanceof BigInteger);
assertTrue(DataTypeUtils.convertType((short) 1, RecordFieldType.BIGINT.getDataType(), "field") instanceof BigInteger);
assertTrue(DataTypeUtils.convertType("12345678901234567890", RecordFieldType.BIGINT.getDataType(), "field") instanceof BigInteger);
final Function<Object, BigInteger> toBigInteger = v -> (BigInteger) DataTypeUtils.convertType(v, RecordFieldType.BIGINT.getDataType(), "field");
assertEquals(new BigInteger("12345678901234567890"), toBigInteger.apply(new BigInteger("12345678901234567890")));
assertEquals(new BigInteger("1234567890123456789"), toBigInteger.apply(1234567890123456789L));
assertEquals(new BigInteger("1"), toBigInteger.apply(1));
assertEquals(new BigInteger("1"), toBigInteger.apply((short) 1));
// Decimals are truncated.
assertEquals(new BigInteger("3"), toBigInteger.apply(3.4f));
assertEquals(new BigInteger("3"), toBigInteger.apply(3.9f));
assertEquals(new BigInteger("12345678901234567890"), toBigInteger.apply("12345678901234567890"));
Exception e = null;
try {
DataTypeUtils.convertType("1234567XYZ", RecordFieldType.BIGINT.getDataType(), "field");
toBigInteger.apply("1234567XYZ");
} catch (IllegalTypeConversionException itce) {
e = itce;
}
Expand Down

0 comments on commit 8a13c68

Please sign in to comment.