diff --git a/client-v2/src/test/java/com/clickhouse/client/datatypes/DataTypeTests.java b/client-v2/src/test/java/com/clickhouse/client/datatypes/DataTypeTests.java index 9ae67693d..6cd659c43 100644 --- a/client-v2/src/test/java/com/clickhouse/client/datatypes/DataTypeTests.java +++ b/client-v2/src/test/java/com/clickhouse/client/datatypes/DataTypeTests.java @@ -33,6 +33,7 @@ import java.lang.reflect.Method; import java.math.BigDecimal; import java.math.RoundingMode; +import java.sql.Connection; import java.time.Instant; import java.time.LocalDateTime; import java.time.Period; diff --git a/jdbc-v2/src/main/java/com/clickhouse/jdbc/internal/JdbcUtils.java b/jdbc-v2/src/main/java/com/clickhouse/jdbc/internal/JdbcUtils.java index cbc07d28c..e47a7cdbb 100644 --- a/jdbc-v2/src/main/java/com/clickhouse/jdbc/internal/JdbcUtils.java +++ b/jdbc-v2/src/main/java/com/clickhouse/jdbc/internal/JdbcUtils.java @@ -33,6 +33,7 @@ import java.util.Set; import java.util.Stack; import java.util.TreeMap; +import java.util.UUID; import java.util.function.Function; public class JdbcUtils { @@ -62,11 +63,13 @@ private static Map generateTypeMap() { map.put(ClickHouseDataType.UInt256, JDBCType.OTHER); map.put(ClickHouseDataType.Float32, JDBCType.FLOAT); map.put(ClickHouseDataType.Float64, JDBCType.DOUBLE); + map.put(ClickHouseDataType.BFloat16, JDBCType.FLOAT); map.put(ClickHouseDataType.Bool, JDBCType.BOOLEAN); map.put(ClickHouseDataType.Decimal, JDBCType.DECIMAL); map.put(ClickHouseDataType.Decimal32, JDBCType.DECIMAL); map.put(ClickHouseDataType.Decimal64, JDBCType.DECIMAL); map.put(ClickHouseDataType.Decimal128, JDBCType.DECIMAL); + map.put(ClickHouseDataType.Decimal256, JDBCType.DECIMAL); map.put(ClickHouseDataType.String, JDBCType.VARCHAR); map.put(ClickHouseDataType.FixedString, JDBCType.VARCHAR); map.put(ClickHouseDataType.Enum, JDBCType.VARCHAR); @@ -81,15 +84,41 @@ private static Map generateTypeMap() { map.put(ClickHouseDataType.Time64, JDBCType.TIME); map.put(ClickHouseDataType.Array, JDBCType.ARRAY); map.put(ClickHouseDataType.Nested, JDBCType.ARRAY); - map.put(ClickHouseDataType.Map, JDBCType.JAVA_OBJECT); + map.put(ClickHouseDataType.Map, JDBCType.OTHER); map.put(ClickHouseDataType.Point, JDBCType.ARRAY); map.put(ClickHouseDataType.Ring, JDBCType.ARRAY); map.put(ClickHouseDataType.Polygon, JDBCType.ARRAY); map.put(ClickHouseDataType.LineString, JDBCType.ARRAY); map.put(ClickHouseDataType.MultiPolygon, JDBCType.ARRAY); map.put(ClickHouseDataType.MultiLineString, JDBCType.ARRAY); + map.put(ClickHouseDataType.Geometry, JDBCType.ARRAY); map.put(ClickHouseDataType.Tuple, JDBCType.OTHER); map.put(ClickHouseDataType.Nothing, JDBCType.OTHER); + map.put(ClickHouseDataType.UUID, JDBCType.OTHER); + map.put(ClickHouseDataType.IPv6, JDBCType.OTHER); + map.put(ClickHouseDataType.IPv4, JDBCType.OTHER); + map.put(ClickHouseDataType.IntervalNanosecond, JDBCType.BIGINT); + map.put(ClickHouseDataType.IntervalMillisecond, JDBCType.BIGINT); + map.put(ClickHouseDataType.IntervalMicrosecond, JDBCType.BIGINT); + map.put(ClickHouseDataType.IntervalSecond, JDBCType.BIGINT); + map.put(ClickHouseDataType.IntervalMinute, JDBCType.BIGINT); + map.put(ClickHouseDataType.IntervalHour, JDBCType.BIGINT); + map.put(ClickHouseDataType.IntervalDay, JDBCType.BIGINT); + map.put(ClickHouseDataType.IntervalMonth, JDBCType.BIGINT); + map.put(ClickHouseDataType.IntervalWeek, JDBCType.BIGINT); + map.put(ClickHouseDataType.IntervalQuarter, JDBCType.BIGINT); + map.put(ClickHouseDataType.IntervalYear, JDBCType.BIGINT); + map.put(ClickHouseDataType.JSON, JDBCType.OTHER); + map.put(ClickHouseDataType.Object, JDBCType.OTHER); + map.put(ClickHouseDataType.LowCardinality, JDBCType.OTHER); + map.put(ClickHouseDataType.Nullable, JDBCType.OTHER); + map.put(ClickHouseDataType.SimpleAggregateFunction, JDBCType.OTHER); + map.put(ClickHouseDataType.AggregateFunction, JDBCType.OTHER); + map.put(ClickHouseDataType.Variant, JDBCType.OTHER); + map.put(ClickHouseDataType.Dynamic, JDBCType.OTHER); + map.put(ClickHouseDataType.QBit, JDBCType.OTHER); + + return ImmutableMap.copyOf(map); } @@ -171,6 +200,12 @@ private static Map> getDataTypeClassMap() { case MultiPolygon: map.put(e.getKey(), double[][][][].class); break; + case UUID: + map.put(e.getKey(), UUID.class); + break; + case IPv4: + case IPv6: + // should be mapped to Object because require conversion. default: map.put(e.getKey(), Object.class); } diff --git a/jdbc-v2/src/test/java/com/clickhouse/jdbc/DataTypeTests.java b/jdbc-v2/src/test/java/com/clickhouse/jdbc/DataTypeTests.java index 4216eb061..34613101e 100644 --- a/jdbc-v2/src/test/java/com/clickhouse/jdbc/DataTypeTests.java +++ b/jdbc-v2/src/test/java/com/clickhouse/jdbc/DataTypeTests.java @@ -12,6 +12,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.testng.Assert; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -340,6 +341,25 @@ public void testUUIDTypes() throws Exception { } } + + @Test(groups = {"integration"}) + public void testArrayOfUUID() throws Exception { + try (Connection connection = getJdbcConnection(); + Statement stmt = connection.createStatement(); + ResultSet rs = stmt.executeQuery("SELECT '2d1f626d-eb07-4c81-be3d-ac1173f0d018'::UUID f_elem, ['2d1f626d-eb07-4c81-be3d-ac1173f0d018']::Array(UUID) arr")) { + + Assert.assertTrue(rs.next()); + UUID fElem = (UUID) rs.getObject(1); + Array colValue = rs.getArray(2); + Object[] arr = (Object[]) colValue.getArray(); + Assert.assertEquals(fElem, arr[0]); + + ResultSet arrRs = colValue.getResultSet(); + arrRs.next(); + Assert.assertEquals(fElem, arrRs.getObject(2)); + } + } + @Test(groups = { "integration" }) public void testDecimalTypes() throws SQLException { runQuery("CREATE TABLE test_decimals (order Int8, " @@ -781,6 +801,56 @@ public void testIpAddressTypes() throws SQLException, UnknownHostException { } } + + @Test(groups = {"integration"}) + public void testArrayOfIpAddress() throws Exception { + try (Connection connection = getJdbcConnection(); + Statement stmt = connection.createStatement(); + ResultSet rs = stmt.executeQuery("SELECT ['90.176.75.97'::IPv4] addrs1, ['2001:adb8:85a3:1:2:8a2e:370:7334'::IPv6] addrs2, ['2001:adb8:85a3:1:2:8a2e:370:7334'::IPv6, null] addrs3")) { + + InetAddress ipv4AddressByIp = Inet4Address.getByName("90.176.75.97"); + InetAddress ipv6Address = Inet6Address.getByName("2001:adb8:85a3:1:2:8a2e:370:7334"); + + Assert.assertTrue(rs.next()); + { + // IPv4 + Array addrs1 = rs.getArray(1); + Object[] arr = (Object[]) addrs1.getArray(); + Assert.assertEquals(ipv4AddressByIp, arr[0]); + + ResultSet arrRs = addrs1.getResultSet(); + arrRs.next(); + Assert.assertEquals(ipv4AddressByIp, arrRs.getObject(2)); + } + + { + // IPv6 + Array addrs2 = rs.getArray(2); + Object[] arr = (Object[]) addrs2.getArray(); + Assert.assertEquals(ipv6Address, arr[0]); + + ResultSet arrRs = addrs2.getResultSet(); + arrRs.next(); + Assert.assertEquals(ipv6Address, arrRs.getObject(2)); + } + + { + // IPv6 + Array addrs3 = rs.getArray(3); + Assert.assertEquals(addrs3.getBaseTypeName(), "Nullable(IPv6)"); + Object[] arr = (Object[]) addrs3.getArray(); + Assert.assertEquals(ipv6Address, arr[0]); + + ResultSet arrRs = addrs3.getResultSet(); + arrRs.next(); + Assert.assertEquals(ipv6Address, arrRs.getObject(2)); + arrRs.next(); + Assert.assertNull(arrRs.getObject(2)); + } + } + } + + @Test(groups = { "integration" }) public void testFloatTypes() throws SQLException { runQuery("CREATE TABLE test_floats (order Int8, " @@ -1176,6 +1246,33 @@ public void testMapTypesWithArrayValues() throws SQLException { } } + @Test(groups = {"integration"}) + public void testArrayOfMaps() throws Exception { + try (Connection connection = getJdbcConnection(); + Statement stmt = connection.createStatement(); + ResultSet rs = stmt.executeQuery("SELECT [map('a', 1, 'b', 2)::Map(String, Int32)] arr1")) { + + Assert.assertTrue(rs.next()); + { + // Array(Map(String, Int32)) + Array arrMap1 = rs.getArray(1); + Assert.assertEquals(arrMap1.getBaseTypeName(), "Map(String, Int32)"); + Object[] arr = (Object[]) arrMap1.getArray(); + @SuppressWarnings("unchecked") + Map map1 = (Map) arr[0]; + Assert.assertEquals(map1.get("a"), Integer.valueOf(1)); + Assert.assertEquals(map1.get("b"), Integer.valueOf(2)); + + ResultSet arrRs = arrMap1.getResultSet(); + arrRs.next(); + @SuppressWarnings("unchecked") + Map rsMap1 = (Map) arrRs.getObject(2); + Assert.assertEquals(rsMap1.get("a"), Integer.valueOf(1)); + Assert.assertEquals(rsMap1.get("b"), Integer.valueOf(2)); + } + } + } + @Test(groups = { "integration" }) public void testNullableTypesSimpleStatement() throws SQLException { runQuery("CREATE TABLE test_nullable (order Int8, " diff --git a/jdbc-v2/src/test/java/com/clickhouse/jdbc/internal/JdbcUtilsTest.java b/jdbc-v2/src/test/java/com/clickhouse/jdbc/internal/JdbcUtilsTest.java index 3b64a1fe4..3227be6ad 100644 --- a/jdbc-v2/src/test/java/com/clickhouse/jdbc/internal/JdbcUtilsTest.java +++ b/jdbc-v2/src/test/java/com/clickhouse/jdbc/internal/JdbcUtilsTest.java @@ -2,6 +2,8 @@ import com.clickhouse.client.api.data_formats.internal.BinaryStreamReader; import com.clickhouse.data.ClickHouseColumn; +import com.clickhouse.data.ClickHouseDataType; +import org.testng.Assert; import org.testng.annotations.*; import java.math.BigDecimal; @@ -100,4 +102,11 @@ public void testConvertToJavaTimeInstant() throws Exception { assertEquals(JdbcUtils.convert(timestamp.atZone(ZoneId.of("UTC")), Instant.class), timestamp); assertEquals(JdbcUtils.convert(timestamp.atZone(ZoneId.of("UTC+7")), Instant.class), timestamp); } + + @Test(groups = {"unit"}) + public void testAllDataTypesMapped() { + for (ClickHouseDataType dt : ClickHouseDataType.values()) { + Assert.assertNotNull(JdbcUtils.convertToJavaClass(dt), "Data type " + dt + " has no mapping to java class"); + } + } } diff --git a/jdbc-v2/src/test/java/com/clickhouse/jdbc/metadata/ResultSetMetaDataImplTest.java b/jdbc-v2/src/test/java/com/clickhouse/jdbc/metadata/ResultSetMetaDataImplTest.java index 268da183f..498188cc9 100644 --- a/jdbc-v2/src/test/java/com/clickhouse/jdbc/metadata/ResultSetMetaDataImplTest.java +++ b/jdbc-v2/src/test/java/com/clickhouse/jdbc/metadata/ResultSetMetaDataImplTest.java @@ -136,7 +136,7 @@ public void testGetColumnTypeMap() throws Exception { try (Statement stmt = conn.createStatement()) { ResultSet rs = stmt.executeQuery("select map('a', 1) as a"); ResultSetMetaData rsmd = rs.getMetaData(); - assertEquals(rsmd.getColumnType(1), Types.JAVA_OBJECT); + assertEquals(rsmd.getColumnType(1), Types.OTHER); assertEquals(rsmd.getColumnClassName(1), Object.class.getName()); } }