Skip to content

[client-v2] Fix reading Array(Nullable(T)) when values are read as another class - #3293

Open
payallenka wants to merge 2 commits into
ClickHouse:mainfrom
payallenka:fix/3283-nullable-array-item-type
Open

payallenka wants to merge 2 commits into
ClickHouse:mainfrom
payallenka:fix/3283-nullable-array-item-type

Conversation

@payallenka

@payallenka payallenka commented Nov 4, 2026 •

Copy link
Copy Markdown

Summary

Reading an Array(Nullable(T)) column fails with IllegalArgumentException: array element type mismatch when readValue returns a different class than the one resolveArrayItemClass predicts for T. The reported cases:

Element type Array allocated as readValue returns
UInt64 (#3283) UnsignedLong[] BigInteger
DateTime, DateTime64 (#3287) LocalDateTime[] ZonedDateTime
IPv6 holding an IPv4-mapped address Inet6Address[] Inet4Address

Other types disagree with the table too (Tuple → Object[], Interval* → Duration/Period, String with binary strings → StringValue). So instead of correcting each entry, the nullable branch of readArrayItem now reads the elements first and allocates the array with the most specific common class of the non-null values. resolveArrayItemClass is used only when every element is NULL. There I corrected UInt64 (BigInteger), DateTime/DateTime32/DateTime64 (ZonedDateTime) and Tuple (Object[]), so an all-NULL array gets the same component type as one with values. For element types that already worked, the result is unchanged.

Closes #3283
Closes #3287

Checklist


Note

Medium Risk
Changes core binary array decoding for all nullable array columns; behavior should match actual read types but affects JDBC/client-v2 result shapes for edge cases like UInt64 and DateTime arrays.

Overview
Fixes IllegalArgumentException when reading Array(Nullable(T)) from RowBinary/Native paths because ArrayValue was sized with resolveArrayItemClass, while readValue often returns a different class (e.g. BigInteger for UInt64, ZonedDateTime for DateTime64, Inet4Address for IPv4-mapped IPv6).

For nullable element columns, readArrayItem now reads all elements first, picks the most specific common superclass of non-null values via new commonSuperclass, and only falls back to resolveArrayItemClass when every element is NULL. resolveArrayItemClass for nullable types is updated for UInt64, DateTime/DateTime32/DateTime64, and Tuple so all-null arrays match populated ones.

Adds testNullableArraysOfTypesReadAsOtherClasses and a changelog note for #3283 / #3287.

Reviewed by Cursor Bugbot for commit 2bdba37. Bugbot is set up for automated code reviews on this repo. Configure here.


Update (Payal Lenka, 2026-11-06): the first commit broke Array(Nullable(Point)), as Cursor Bugbot reported: a Point is read as double[], which ArrayValue cannot store in the Object[][] it allocates for array classes. 4bacdc3 uses an Object array for primitive array values, and testNullableArraysOfArrayBackedTypes covers Point, Ring and Tuple. It fails without that commit.

This also corrects the sentence above that the result is unchanged for types that already worked. The values are unchanged, but the array's component type can now be more specific where it was declared as Object (for example HashMap[] instead of Object[] for Array(Nullable(JSON))).

mvn -pl client-v2,jdbc-v2 install passes with -Duser.timezone=UTC: client-v2 826 + 1201, jdbc-v2 1975 + 799 (21 skipped).

Reading Array(Nullable(T)) failed with "array element type mismatch"
when readValue returns a different class than the one declared for T:
UInt64 (BigInteger, array was UnsignedLong[]), DateTime and DateTime64
(ZonedDateTime, array was LocalDateTime[]) and IPv6 holding IPv4-mapped
addresses (Inet4Address).

Allocate the array with the common class of the values read, and use the
declared type only for an array of NULLs. Correct that fallback for
UInt64, DateTime and Tuple.

Fixes ClickHouse#3283
Fixes ClickHouse#3287
@payallenka
payallenka force-pushed the fix/3283-nullable-array-item-type branch from 9935557 to 2bdba37 Compare November 4, 2026 19:59

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

Reviewed by Cursor Bugbot for commit 2bdba37. Configure here.

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Typing nullable arrays by the values read made Array(Nullable(Point))
fail: a Point is read as double[], and ArrayValue allocates Object[][]
for an array class, which cannot hold a double[]. Use an Object array
for primitive array values, as before.
@payallenka

Copy link
Copy Markdown
Author

CLA assistant check Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.You have signed the CLA already but the status is still pending? Let us recheck it.

Already Agreed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants