Skip to content

Commit 24530a7

Browse files
fix: ensure nullable binary arrays return boxed type arrays instead of Object[] in BinaryStreamReader
1 parent 8ce79b1 commit 24530a7

3 files changed

Lines changed: 33 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
### Bug Fixes
66

7+
- **[client-v2]** Fixed binary array decoding for nullable element types so `Array(Nullable(Float64))` and similar columns now return boxed arrays such as `Double[]` instead of `Object[]`. This keeps null-supporting arrays aligned with their element type while preserving the existing `Object[]` fallback for Variant/Dynamic/Geometry arrays. (https://github.com/ClickHouse/clickhouse-java/issues/2846)
8+
79
- **[client-v2]** Fixed container query parameters being sent unquoted, so `Client.query(sql, params, settings)` binding
810
a `List<LocalDate>` (or an array/`Map`) to a placeholder like `{ids:Array(Date)}` was rejected by the server with
911
`CANNOT_PARSE_INPUT_ASSERTION_FAILED`. Parameter values are now formatted by

client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/BinaryStreamReader.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -625,8 +625,13 @@ public ArrayValue readArray(ClickHouseColumn column) throws IOException {
625625

626626
public ArrayValue readArrayItem(ClickHouseColumn itemTypeColumn, int len) throws IOException {
627627
ArrayValue array;
628-
if (itemTypeColumn.isNullable()
629-
|| itemTypeColumn.getDataType() == ClickHouseDataType.Variant
628+
if (itemTypeColumn.isNullable()) {
629+
Class<?> itemClass = itemTypeColumn.getDataType().getObjectClass();
630+
array = new ArrayValue(itemClass == null ? Object.class : itemClass, len);
631+
for (int i = 0; i < len; i++) {
632+
array.set(i, readValue(itemTypeColumn));
633+
}
634+
} else if (itemTypeColumn.getDataType() == ClickHouseDataType.Variant
630635
|| itemTypeColumn.getDataType() == ClickHouseDataType.Dynamic
631636
|| itemTypeColumn.getDataType() == ClickHouseDataType.Geometry) {
632637
array = new ArrayValue(Object.class, len);

client-v2/src/test/java/com/clickhouse/client/api/data_formats/internal/BinaryStreamReaderTests.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.clickhouse.client.api.data_formats.internal;
22

33
import com.clickhouse.data.ClickHouseColumn;
4+
import com.clickhouse.data.format.BinaryStreamUtils;
45

56
import java.io.ByteArrayInputStream;
67
import java.io.ByteArrayOutputStream;
@@ -204,4 +205,27 @@ public void testReadNullVariantReturnsNull() throws Exception {
204205

205206
Assert.assertNull(reader.readValue(column));
206207
}
208+
209+
@Test
210+
public void testNullableArrayValueUsesBoxedComponentType() throws Exception {
211+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
212+
BinaryStreamUtils.writeVarInt(baos, 2);
213+
BinaryStreamUtils.writeNonNull(baos);
214+
BinaryStreamUtils.writeFloat64(baos, 1.0);
215+
BinaryStreamUtils.writeNonNull(baos);
216+
BinaryStreamUtils.writeFloat64(baos, 2.0);
217+
218+
BinaryStreamReader reader = new BinaryStreamReader(
219+
new ByteArrayInputStream(baos.toByteArray()),
220+
TimeZone.getTimeZone("UTC"),
221+
null,
222+
new BinaryStreamReader.CachingByteBufferAllocator(),
223+
false,
224+
null);
225+
226+
BinaryStreamReader.ArrayValue array = (BinaryStreamReader.ArrayValue) reader.readValue(
227+
ClickHouseColumn.of("v", "Array(Nullable(Float64))"));
228+
229+
Assert.assertEquals(array.getArray().getClass().getComponentType(), Double.class);
230+
}
207231
}

0 commit comments

Comments
 (0)