Insert Fails for Array(Tuple) in JDBC v2 (Worked in v1)
We previously encountered a similar issue (#1862), and the suggested solution worked at that time. However, after migrating to jdbc-v2 (version 0.8.4), the same approach no longer works.
Currently, we're attempting to insert data into a column of type Array(Tuple(String, String)) using the method recommended in this comment, but the operation now fails with the following error:
Failed to create array
java.sql.SQLException:
at com.clickhouse.jdbc.ConnectionImpl.createArrayOf(ConnectionImpl.java:515)
at com.zaxxer.hikari.pool.HikariProxyConnection.createArrayOf(HikariProxyConnection.java)
.....
.....
Caused by: java.lang.IllegalArgumentException: No enum constant com.clickhouse.data.ClickHouseDataType.Tuple(String, String)
at java.base/java.lang.Enum.valueOf(Enum.java:273)
at com.clickhouse.data.ClickHouseDataType.valueOf(ClickHouseDataType.java:50)
at com.clickhouse.jdbc.ConnectionImpl.createArrayOf(ConnectionImpl.java:513)
at com.zaxxer.hikari.pool.HikariProxyConnection.createArrayOf(HikariProxyConnection.java)
This used to work on 0.7.2 and jdbc-v1. Is there an updated way to insert an Array(Tuple(String, String)) column using jdbc-v2?
@aira-xite thank you for reporting! We will look into it.
@aira-xite would you please check this test com.clickhouse.jdbc.DataTypeTests#testArrayTypes:
creating table
runQuery("CREATE TABLE test_arrays (order Int8, "
+ "array Array(Int8), arraystr Array(String), arraytuple Array(Tuple(Int8, String)), arraydate Array(Date)"
+ ") ENGINE = MergeTree ORDER BY ()");
create values
Tuple[] arraytuple = new Tuple[rand.nextInt(10) + 1];
for (int i = 0; i < arraytuple.length; i++) {
arraytuple[i] = new Tuple(rand.nextInt(256) - 128, "string" + rand.nextInt(1000));
}
inserting values
try (Connection conn = getConnection()) {
try (PreparedStatement stmt = conn.prepareStatement("INSERT INTO test_arrays VALUES ( 1, ?, ?, ?, ?)")) {
stmt.setArray(1, conn.createArrayOf("Int8", array));
stmt.setArray(2, conn.createArrayOf("String", arraystr));
stmt.setArray(3, conn.createArrayOf("Tuple", arraytuple)); // < ----
stmt.setArray(4, conn.createArrayOf("Date", arraydate));
stmt.executeUpdate();
}
}
So just an array of Tuple.
Please let me know if this works for you.
We will do more tests around that.
Good day, @aira-xite!
I'm currently working on the issue:
Tupleis eventually a structure without field names.- Using
java.sql.Arrayas Tuple is not correct way to solve your case because Array may contain elements of only one data type. - In the new release we are going to utilize
java.sql.Structto represent nested types likeTuple - We will fix the issue but in this case you would need to pass array of
StructnotArray. Sorry about that.
A few questions:
- what is the source or array of
Tuple(String, String? is it a collection? - Would it be more convenient to pass collection/array or Tuples to
setObject()?
Thanks!