From 1bd18d86a16af509bb389f40ab83ee6466b18f70 Mon Sep 17 00:00:00 2001 From: alexradzin Date: Sun, 2 Jun 2024 15:43:34 +0300 Subject: [PATCH] FIR-33431: implemented getObject with type map --- .../tests/PreparedStatementTest.java | 14 ++++++++- .../jdbc/resultset/FireboltResultSet.java | 29 +++++++++++++++---- .../jdbc/resultset/FireboltResultSetTest.java | 10 ++++++- 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/src/integrationTest/java/integration/tests/PreparedStatementTest.java b/src/integrationTest/java/integration/tests/PreparedStatementTest.java index 44eed8c61..090788c2c 100644 --- a/src/integrationTest/java/integration/tests/PreparedStatementTest.java +++ b/src/integrationTest/java/integration/tests/PreparedStatementTest.java @@ -118,7 +118,19 @@ Stream numericTypes() { (CheckedTriFunction) (s, i, v) -> { s.setLong(i, v.longValue()); return null; - }, (CheckedBiFunction) (rs, i) -> (int) rs.getLong(i)) + }, (CheckedBiFunction) (rs, i) -> (int) rs.getLong(i)), + + Arguments.of("getObject(Long.class)", + (CheckedTriFunction) (s, i, v) -> { + s.setLong(i, v.longValue()); + return null; + }, (CheckedBiFunction) (rs, i) -> rs.getObject(i, Long.class).intValue()), + + Arguments.of("getObject(i, java.util.Map.of(\"long\", Integer.class)", + (CheckedTriFunction) (s, i, v) -> { + s.setLong(i, v.longValue()); + return null; + }, (CheckedBiFunction) (rs, i) -> (int) rs.getObject(i, java.util.Map.of("long", Integer.class))) ); } diff --git a/src/main/java/com/firebolt/jdbc/resultset/FireboltResultSet.java b/src/main/java/com/firebolt/jdbc/resultset/FireboltResultSet.java index 324df5beb..724ef32cf 100644 --- a/src/main/java/com/firebolt/jdbc/resultset/FireboltResultSet.java +++ b/src/main/java/com/firebolt/jdbc/resultset/FireboltResultSet.java @@ -36,6 +36,7 @@ import java.sql.Blob; import java.sql.Clob; import java.sql.Date; +import java.sql.JDBCType; import java.sql.NClob; import java.sql.Ref; import java.sql.ResultSet; @@ -50,6 +51,7 @@ import java.util.Calendar; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.TimeZone; import java.util.TreeMap; @@ -57,6 +59,7 @@ import java.util.logging.Logger; import java.util.stream.Collectors; import java.util.stream.IntStream; +import java.util.stream.Stream; import static com.firebolt.jdbc.type.BaseType.isNull; import static com.firebolt.jdbc.util.StringUtil.splitAll; @@ -951,10 +954,26 @@ public Statement getStatement() { } @Override - @NotImplemented - @ExcludeFromJacocoGeneratedReport public Object getObject(int columnIndex, Map> map) throws SQLException { - throw new FireboltSQLFeatureNotSupportedException(); + FireboltDataType dataType = resultSetMetaData.getColumn(columnIndex).getType().getDataType(); + BaseType columnType = dataType.getBaseType(); + Map> caseInsensitiveMap = new TreeMap<>(CASE_INSENSITIVE_ORDER); + caseInsensitiveMap.putAll(map); + Class type = getAllNames(dataType).map(caseInsensitiveMap::get).filter(Objects::nonNull).findFirst() + .orElseThrow(() -> new FireboltException(format("Cannot find type %s in provided types map", dataType))); + return getObject(columnIndex, type); + } + + private Stream getAllNames(FireboltDataType dataType) { + return Stream.concat(Stream.of(dataType.getDisplayName(), getJdbcType(dataType)).filter(Objects::nonNull), Stream.of(dataType.getAliases())); + } + + private String getJdbcType(FireboltDataType dataType) { + try { + return JDBCType.valueOf(dataType.getSqlType()).getName(); + } catch (IllegalArgumentException e) { + return null; + } } @Override @@ -975,10 +994,8 @@ public Clob getClob(int columnIndex) throws SQLException { } @Override - @NotImplemented - @ExcludeFromJacocoGeneratedReport public Object getObject(String columnLabel, Map> map) throws SQLException { - throw new FireboltSQLFeatureNotSupportedException(); + return getObject(findColumn(columnLabel), map); } @Override diff --git a/src/test/java/com/firebolt/jdbc/resultset/FireboltResultSetTest.java b/src/test/java/com/firebolt/jdbc/resultset/FireboltResultSetTest.java index c7255c483..6cb51133f 100644 --- a/src/test/java/com/firebolt/jdbc/resultset/FireboltResultSetTest.java +++ b/src/test/java/com/firebolt/jdbc/resultset/FireboltResultSetTest.java @@ -44,6 +44,7 @@ import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.util.Calendar; +import java.util.Map; import java.util.TimeZone; import java.util.concurrent.Callable; @@ -192,7 +193,7 @@ void unsupported() throws SQLException { assertThrows(SQLFeatureNotSupportedException.class, () -> resultSet.updateFloat("label", 0.0f)); assertThrows(SQLFeatureNotSupportedException.class, () -> resultSet.updateDouble("label", 0.0)); assertThrows(SQLFeatureNotSupportedException.class, () -> resultSet.updateBigDecimal("label", new BigDecimal(0))); - ; + assertThrows(SQLFeatureNotSupportedException.class, () -> resultSet.updateString("label", "")); assertThrows(SQLFeatureNotSupportedException.class, () -> resultSet.updateBytes("label", new byte[0])); assertThrows(SQLFeatureNotSupportedException.class, () -> resultSet.updateDate("label", new Date(0))); @@ -428,6 +429,11 @@ void shouldReturnInt() throws SQLException { assertEquals(1, resultSet.getInt(1)); assertEquals(1, resultSet.getInt("id")); assertEquals(1, resultSet.getObject(1, Long.class)); + assertEquals(1L, resultSet.getObject(1, Map.of("int", Long.class))); + assertEquals(1L, resultSet.getObject("id", Map.of("INTEGER", Long.class))); + assertEquals(1., resultSet.getObject(1, Map.of("int32", Double.class))); + assertThrows(SQLException.class, () -> resultSet.getObject(1, Map.of("real", Double.class))); // exising type that does not match column type + assertThrows(SQLException.class, () -> resultSet.getObject(1, Map.of("notatype", Double.class))); // type alias that does not exist resultSet.next(); assertEquals(2, resultSet.getInt(1)); @@ -446,6 +452,8 @@ void shouldReturnFloat() throws SQLException { assertEquals(14.6f, resultSet.getFloat(6)); assertEquals(14.6f, resultSet.getFloat("a_double")); assertEquals(14.6f, resultSet.getObject(6, Float.class)); + assertEquals(14.6, resultSet.getObject(6, Map.of("Float32", Double.class))); + assertEquals((short)14, resultSet.getObject(6, Map.of("Float32", Short.class))); resultSet.next(); assertEquals(0, resultSet.getFloat(6));