Repository navigation
Description
Description
Reading a column of type Array(Nullable(UInt64)) with client-v2 0.11.0 throws, whatever the values are. Array(UInt64) (non-nullable) reads fine, and so did Array(Nullable(UInt64)) in 0.9.2.
The cause seems to be in BinaryStreamReader.readArrayItem. For nullable element types it allocates the array with resolveArrayItemClass(itemTypeColumn), which returns ClickHouseDataType.UInt64.getWiderObjectClass(), i.e. com.clickhouse.data.value.UnsignedLong. But readValue returns a java.math.BigInteger for UInt64 (readBigIntegerLE(INT64_SIZE, true)), so Array.set fails on the first element.
UInt8/UInt16/UInt32 are not affected: their widened classes (Short/Integer/Long) match what readValue returns. UInt64 is the only unsigned type where the two disagree.
In 0.9.2 the nullable branch was new ArrayValue(Object.class, len), which could hold the BigInteger. The typed allocation via resolveArrayItemClass (apparently introduced with the "nullable arrays return boxed arrays" change noted in v0.11.0-rc1) is what regressed.
Steps to reproduce
- Start ClickHouse server 26.8.36.3.
- Run
SELECT [toNullable(toUInt64(0)), toNullable(toUInt64(1))] AS vwith client-v2 0.11.0 and read the result. - Reading the record throws.
Error Log or Exception StackTrace
com.clickhouse.client.api.ClientException: Failed to read value for column v
at com.clickhouse.client.api.data_formats.internal.BinaryStreamReader.readValue(BinaryStreamReader.java:307)
at com.clickhouse.client.api.data_formats.internal.AbstractBinaryFormatReader.readRecord(AbstractBinaryFormatReader.java:195)
at com.clickhouse.client.api.data_formats.internal.AbstractBinaryFormatReader.readNextRecord(AbstractBinaryFormatReader.java:242)
...
Caused by: java.lang.IllegalArgumentException: Failed to set value at index: 0 value 0 of class java.math.BigInteger when array type is class [Lcom.clickhouse.data.value.UnsignedLong;
at com.clickhouse.client.api.data_formats.internal.BinaryStreamReader$ArrayValue.set(BinaryStreamReader.java:959)
at com.clickhouse.client.api.data_formats.internal.BinaryStreamReader.readArrayItem(BinaryStreamReader.java:807)
at com.clickhouse.client.api.data_formats.internal.BinaryStreamReader.readArray(BinaryStreamReader.java:785)
at com.clickhouse.client.api.data_formats.internal.BinaryStreamReader.readValue(BinaryStreamReader.java:282)
... 28 more
Caused by: java.lang.IllegalArgumentException: array element type mismatch
at java.base/java.lang.reflect.Array.set(Native Method)
at com.clickhouse.client.api.data_formats.internal.BinaryStreamReader$ArrayValue.set(BinaryStreamReader.java:956)
Expected Behaviour
The record is read and getList("v") returns [0, 1] as BigInteger values (same as Array(UInt64)), and NULL elements as null.
Code Example
try (Client client = new Client.Builder()
.addEndpoint("http://localhost:8123")
.setUsername("default")
.setPassword("")
.build()) {
// works: Array(UInt64)
client.queryAll("SELECT [toUInt64(0), toUInt64(1)] AS v")
.forEach(r -> System.out.println(r.getList("v"))); // [0, 1]
// throws: Array(Nullable(UInt64))
client.queryAll("SELECT [toNullable(toUInt64(0)), toNullable(toUInt64(1))] AS v")
.forEach(r -> System.out.println(r.getList("v")));
}Also reproducible at the reader level: the bytes are valid RowBinary (varint length, then per element a null-marker byte and 8 little-endian bytes), so this is not a server or protocol problem. Any Array(Nullable(UInt64)) triggers it, for example a LAST_VALUE(x) IGNORE NULLS window result placed in an array.
Configuration
Client Configuration
new Client.Builder()
.addEndpoint("http://localhost:8123")
.setUsername("default")
.setPassword("")
.build();(default settings)
Environment
- Client version: client-v2 0.11.0 (worked in 0.9.2)
- Language version: Java 21 (OpenJDK 21.0.9)
- OS: Linux 7.0.0 (x86_64)
ClickHouse Server
- ClickHouse Server version: 26.8.36.3 (
clickhouse/clickhouse-serverDocker image) - ClickHouse Server non-default settings, if any: none relevant
CREATE TABLEstatements for tables involved: none needed, the query above uses literals only- Sample data: none needed
Activity
[client-v2] Type nullable arrays by the values read