clickhouse-java
clickhouse-java copied to clipboard
[jdbc-v2] embedded Array value not converted to List
Describe your feedback
ATM, it seems jdbc-v2 cannot properly convert the embedded array value returned from the getObject function to java.sql.array types.
For example, if a query fetching data type Map(String, Array(Int8)), the value returned from jdbc driver would be of Java type LinkedHashMap<String, BinaryStreamReader$ArrayValue>. Because the BinaryStreamReader does not have type hint information to handle convertArray, it would return the original ArrayValue type instead.
Perhaps we could:
- Return array as
java.util.Listby default (like map) - Modify
AbstractBinaryFormatReaderandBinaryStreamReader, and pass the compositeClickHouseDataTypetoBinaryStreamReaderreadValue
Code example
@Test(groups = { "integration" })
public void testCompositeTypes() throws SQLException {
runQuery("CREATE TABLE test_composite (order Int8, "
+ "map Map(String, Array(Int8)),"
+ "tuple Tuple(Array(Int8), Map(String, String))"
+ ") ENGINE = MergeTree ORDER BY ()");
Map<String, List> map = Map.of("mk1", Arrays.asList(11,12,13),
"mk2", Arrays.asList(21,22,23),
"mk3", Arrays.asList(31,32,33));
Tuple tuple = new Tuple(Arrays.asList(1,2,3),
Map.of("k1","v1","k2","v2","k3","v3"));
try (Connection conn = getConnection()) {
try (PreparedStatement stmt = conn.prepareStatement("INSERT INTO test_composite VALUES ( 1, ?, ? )")) {
stmt.setObject(1, map);
stmt.setObject(2, tuple);
stmt.executeUpdate();
}
}
// Check the results
try (Connection conn = getConnection()) {
try (Statement stmt = conn.createStatement()) {
try (ResultSet rs = stmt.executeQuery("SELECT * FROM test_composite ORDER BY order")) {
assertTrue(rs.next());
Map<Object, Object> mapResult = (Map<Object, Object>) rs.getObject("map");
assertEquals(mapResult.size(), 3);
for (String key: map.keySet()) {
assertEquals(mapResult.get(key), map.get(key));
}
Object[] tupleResult = (Object[]) rs.getObject("tuple");
assertEquals(tupleResult[0], tuple.getValue(0));
assertEquals(tupleResult[1], tuple.getValue(1));
}
}
}
}