diff --git a/core/src/main/java/org/apache/calcite/avatica/util/AbstractCursor.java b/core/src/main/java/org/apache/calcite/avatica/util/AbstractCursor.java index fb88dddc3a..f05cbcc6d3 100644 --- a/core/src/main/java/org/apache/calcite/avatica/util/AbstractCursor.java +++ b/core/src/main/java/org/apache/calcite/avatica/util/AbstractCursor.java @@ -682,6 +682,32 @@ public boolean getBoolean() throws SQLException { } } + /** + * Accessor that assumes that the underlying value is a {@link BigDecimal}; + * corresponds to {@link java.sql.Types#DECIMAL}. + */ + private static class BigDecimalAccessor extends BigNumberAccessor { + private BigDecimalAccessor(Getter getter) { + super(getter); + } + + protected Number getNumber() throws SQLException { + return (Number) getObject(); + } + + public BigDecimal getBigDecimal(int scale) throws SQLException { + Number number = getNumber(); + return number == null || number instanceof BigDecimal + ? (BigDecimal) number : BigDecimal.valueOf(number.longValue()); + } + + public BigDecimal getBigDecimal() throws SQLException { + Number number = getNumber(); + return number == null || number instanceof BigDecimal + ? (BigDecimal) number : BigDecimal.valueOf(number.longValue()); + } + } + /** * Accessor that assumes that the underlying value is a {@link Number}; * corresponds to {@link java.sql.Types#NUMERIC} diff --git a/core/src/test/java/org/apache/calcite/avatica/AvaticaResultSetConversionsTest.java b/core/src/test/java/org/apache/calcite/avatica/AvaticaResultSetConversionsTest.java index b61d9e5e43..b8df74e0ad 100644 --- a/core/src/test/java/org/apache/calcite/avatica/AvaticaResultSetConversionsTest.java +++ b/core/src/test/java/org/apache/calcite/avatica/AvaticaResultSetConversionsTest.java @@ -203,6 +203,13 @@ public TestMetaImpl(AvaticaConnection connection) { ColumnMetaData.Rep.NUMBER), "ARRAY", ColumnMetaData.Rep.ARRAY), + DatabaseMetaData.columnNoNulls), + columnMetaData("decimal_array", 18, + ColumnMetaData.array( + ColumnMetaData.scalar(Types.DECIMAL, "DECIMAL", + ColumnMetaData.Rep.PRIMITIVE_DOUBLE), + "ARRAY", + ColumnMetaData.Rep.ARRAY), DatabaseMetaData.columnNoNulls)); List row = Collections.singletonList( @@ -216,7 +223,8 @@ public TestMetaImpl(AvaticaConnection connection) { null, Arrays.asList(123, 18234), Arrays.asList(1476130718123L, 1479123123242L), - Arrays.asList(1476123L, 147912242L) + Arrays.asList(1476123L, 147912242L), + Arrays.asList(1, 1.1) }); CursorFactory factory = CursorFactory.deduce(columns, null); @@ -596,6 +604,24 @@ private ArrayAccessorTestHelper(Getter g) { } } + /** + * Accessor test helper for decimal array column. + */ + private static final class DecimalArrayAccessorTestHelper extends AccessorTestHelper { + private DecimalArrayAccessorTestHelper(Getter g) { + super(g); + } + + @Override public void testGetArray(ResultSet resultSet) throws SQLException { + ColumnMetaData.ScalarType intType = + ColumnMetaData.scalar(Types.DECIMAL, "DECIMAL", ColumnMetaData.Rep.PRIMITIVE_DOUBLE); + Array expectedArray = + new ArrayFactoryImpl(Unsafe.localCalendar().getTimeZone()).createArray( + intType, Arrays.asList(1, 1.1)); + assertTrue(ArrayImpl.equalContents(expectedArray, g.getArray(resultSet))); + } + } + /** * Accessor test helper for date array column. */ @@ -1150,7 +1176,9 @@ public static Collection data() { new TimestampArrayAccessorTestHelper(new OrdinalGetter(17)), new TimestampArrayAccessorTestHelper(new LabelGetter("timestamp_array")), new TimeArrayAccessorTestHelper(new OrdinalGetter(18)), - new TimeArrayAccessorTestHelper(new LabelGetter("time_array"))); + new TimeArrayAccessorTestHelper(new LabelGetter("time_array")), + new DecimalArrayAccessorTestHelper(new OrdinalGetter(19)), + new DecimalArrayAccessorTestHelper(new LabelGetter("decimal_array"))); } private final AccessorTestHelper testHelper;