From 800655c938d7dea24923d499422765dd079ca098 Mon Sep 17 00:00:00 2001 From: Peter Wicks Date: Tue, 15 Sep 2020 12:36:02 -0600 Subject: [PATCH] NIFI-7805 ResultSetRecordSet can't generate a schema if first row contains NULL Decimal Signed-off-by: Pierre Villard This closes #4532. --- .../nifi/serialization/record/ResultSetRecordSet.java | 3 +-- .../serialization/record/ResultSetRecordSetTest.java | 10 ++++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/nifi-commons/nifi-record/src/main/java/org/apache/nifi/serialization/record/ResultSetRecordSet.java b/nifi-commons/nifi-record/src/main/java/org/apache/nifi/serialization/record/ResultSetRecordSet.java index 3b98657353..e6425af0c0 100644 --- a/nifi-commons/nifi-record/src/main/java/org/apache/nifi/serialization/record/ResultSetRecordSet.java +++ b/nifi-commons/nifi-record/src/main/java/org/apache/nifi/serialization/record/ResultSetRecordSet.java @@ -198,8 +198,7 @@ public class ResultSetRecordSet implements RecordSet, Closeable { return RecordFieldType.ARRAY.getArrayDataType(RecordFieldType.BYTE.getDataType()); case Types.NUMERIC: case Types.DECIMAL: - final BigDecimal bigDecimal = rs.getBigDecimal(columnIndex); - return RecordFieldType.DECIMAL.getDecimalDataType(bigDecimal.precision(), bigDecimal.scale()); + return RecordFieldType.DECIMAL.getDecimalDataType(rs.getMetaData().getPrecision(columnIndex), rs.getMetaData().getScale(columnIndex)); case Types.OTHER: { // If we have no records to inspect, we can't really know its schema so we simply use the default data type. if (rs.isAfterLast()) { diff --git a/nifi-commons/nifi-record/src/test/java/org/apache/nifi/serialization/record/ResultSetRecordSetTest.java b/nifi-commons/nifi-record/src/test/java/org/apache/nifi/serialization/record/ResultSetRecordSetTest.java index 5c9a39c543..019e01cae9 100644 --- a/nifi-commons/nifi-record/src/test/java/org/apache/nifi/serialization/record/ResultSetRecordSetTest.java +++ b/nifi-commons/nifi-record/src/test/java/org/apache/nifi/serialization/record/ResultSetRecordSetTest.java @@ -17,6 +17,7 @@ package org.apache.nifi.serialization.record; import org.apache.nifi.serialization.SimpleRecordSchema; +import org.apache.nifi.serialization.record.type.DecimalDataType; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -54,6 +55,7 @@ public class ResultSetRecordSetTest { {14, "bigDecimal1", Types.DECIMAL,RecordFieldType.DECIMAL.getDecimalDataType(7, 3)}, {15, "bigDecimal2", Types.NUMERIC, RecordFieldType.DECIMAL.getDecimalDataType(4, 0)}, {16, "bigDecimal3", Types.JAVA_OBJECT, RecordFieldType.DECIMAL.getDecimalDataType(501, 1)}, + {17, "bigDecimal4", Types.DECIMAL, RecordFieldType.DECIMAL.getDecimalDataType(10, 3)}, }; @Mock @@ -71,11 +73,15 @@ public class ResultSetRecordSetTest { Mockito.when(resultSetMetaData.getColumnLabel((Integer) column[0])).thenReturn((column[1]) + "Col"); Mockito.when(resultSetMetaData.getColumnName((Integer) column[0])).thenReturn((String) column[1]); Mockito.when(resultSetMetaData.getColumnType((Integer) column[0])).thenReturn((Integer) column[2]); + + if(column[3] instanceof DecimalDataType) { + DecimalDataType ddt = (DecimalDataType)column[3]; + Mockito.when(resultSetMetaData.getPrecision((Integer) column[0])).thenReturn(ddt.getPrecision()); + Mockito.when(resultSetMetaData.getScale((Integer) column[0])).thenReturn(ddt.getScale()); + } } // Big decimal values are necessary in order to determine precision and scale - Mockito.when(resultSet.getBigDecimal(14)).thenReturn(BigDecimal.valueOf(1234.567D)); - Mockito.when(resultSet.getBigDecimal(15)).thenReturn(BigDecimal.valueOf(1234L)); Mockito.when(resultSet.getBigDecimal(16)).thenReturn(new BigDecimal(String.join("", Collections.nCopies(500, "1")) + ".1")); // This will be handled by a dedicated branch for Java Objects, needs some further details