Repository navigation
Conversation
The type parser had no entry for Nested, so a column typed
Array(Nested(key String, value String)) was created as Array(Void)
and the native block stream fell out of sync ("Can't cast from Void",
"some data was not read"). A top-level Nested column, which the server
sends with flatten_nested = 0, was rejected as unsupported.
The server defines Nested as a custom name over Array(Tuple(...))
(DataTypeNested.cpp). The parser now recognises Nested as its own
node, like Map and SimpleAggregateFunction, and the column factory
builds an Array of the named Tuple from it, sharing the Tuple code.
Closes ClickHouse#571
Hakaou
commented
Oct 17, 2026
| } else { | ||
| return nullptr; | ||
| } | ||
| case TypeAst::Nested: { |
Author
There was a problem hiding this comment.
Same shape as the Map case just below: the surface type becomes its Array of Tuple here, so the parser and the AST stay faithful to the type name the server sends. The Tuple body moved to CreateTupleColumn unchanged so both cases share it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #571.
TypeParserhad no entry forNested, so the name became aVoidterminal. At the rootValidateASTrejects it ("unsupported column type"), but inside a container nothing checks it:Array(Nested(key String, value String))was created asArray(Void),ColumnNothingreads one byte per row and the block stream desynchronises.Change
TypeParserrecognisesNestedas its own AST node, next toMapandSimpleAggregateFunction(TypeAst::Metagains a value; the AST keeps the server's type name).CreateColumnFromAstbuilds anArrayof the namedTuplefor it, the same way theMapcase builds itsArray(Tuple). TheTuplecase body moves toCreateTupleColumnso both cases share it; a bareNestedwithout fields givesnullptrlike any unsupported type.DataTypeNested.cppbuildsDataTypeArray(DataTypeTuple(types, names))under a custom name.Trade-off, named: the created column reports the structural type name,
Array(Tuple(key String, value UInt8)), notNested(...). The server accepts that name onINSERT, named or unnamed tuple alike (checked withclickhouse local26.11 and covered byArrayOfNested_InsertFromClient). A dedicatedNestedcolumn type would add public API for no behavioural gain, so I did not go that way; happy to discuss.Tests
type_parser_ut:Nested(...)parses to aNestednode with named elements, insideArray, with a backtick-quoted field name, and with a field itself namedNested.CreateColumnByType_ut:Nested,Array(Nested),Map(String, Nested),Nested(a Nested(...))give the expected column types; a bareNestedgivesnullptr.client_ut(both fixtures, no compression and LZ4): select from a server-typedArray(Nested(...))column with empty inner and outer arrays; insert from the client, rendered back by the server withtoString; a top-levelNestedcolumn withflatten_nested = 0.Before this change, on
masterfc5d98f against ClickHouse 26.11.1:CreateColumnByType("Array(Nested(key String, value UInt8))")Array(Void)Array(Array(Tuple(key String, value UInt8)))Selecton that column, no compressionCan't cast from VoidSelecton that column, LZ4some data was not readSelecton aNestedcolumn,flatten_nested = 0unsupported column type: Nested(key String, value UInt8)Array(Nested(...))Full suite: 1 138 tests pass locally (macOS arm64, Apple clang 21, server 26.11.1 master build). Parser, factory, client and roundtrip suites also pass under AddressSanitizer and UBSan.
Out of scope, two notes
ValidateASTonly checks the root, so any other unknown type nested in a container still decodes asVoidsilently.SELECT []relies on that path today:Nothingis not registered and decodes asVoidby accident, one byte per row on both sides. Would you take a follow-up that registersNothingand validates recursively, so an unknown type fails loudly instead of desynchronising the stream?InsertDatatest (client_ut.cpp625 to 627) when the server returns the eight rows in one block: the expectation indexesTEST_DATApast its four rows. Test code only, fixed separately in Compare InsertData rows against both datasets regardless of block boundaries #576.