Skip to content

Commit

Permalink
Merge pull request #34124 from ClickHouse/backport/22.1/33956
Browse files Browse the repository at this point in the history
Backport #33956 to 22.1: Fix reading of nested tuples
  • Loading branch information
CurtizJ committed Jan 29, 2022
2 parents d15926f + 28d42c2 commit bc393af
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 2 deletions.
16 changes: 14 additions & 2 deletions src/DataTypes/DataTypeTuple.cpp
Expand Up @@ -32,6 +32,7 @@ namespace ErrorCodes
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
extern const int SIZES_OF_COLUMNS_IN_TUPLE_DOESNT_MATCH;
extern const int ILLEGAL_INDEX;
extern const int LOGICAL_ERROR;
}


Expand Down Expand Up @@ -156,8 +157,19 @@ MutableColumnPtr DataTypeTuple::createColumn() const

MutableColumnPtr DataTypeTuple::createColumn(const ISerialization & serialization) const
{
const auto & element_serializations =
assert_cast<const SerializationTuple &>(serialization).getElementsSerializations();
/// If we read subcolumn of nested Tuple, it may be wrapped to SerializationNamed
/// several times to allow to reconstruct the substream path name.
/// Here we don't need substream path name, so we drop first several wrapper serializations.

const auto * current_serialization = &serialization;
while (const auto * serialization_named = typeid_cast<const SerializationNamed *>(current_serialization))
current_serialization = serialization_named->getNested().get();

const auto * serialization_tuple = typeid_cast<const SerializationTuple *>(current_serialization);
if (!serialization_tuple)
throw Exception(ErrorCodes::LOGICAL_ERROR, "Unexpected serialization to create column of type Tuple");

const auto & element_serializations = serialization_tuple->getElementsSerializations();

size_t size = elems.size();
assert(element_serializations.size() == size);
Expand Down
5 changes: 5 additions & 0 deletions src/DataTypes/Serializations/SerializationNamed.h
Expand Up @@ -5,6 +5,11 @@
namespace DB
{

/// Serialization wrapper that acts like nested serialization,
/// but adds a passed name to the substream path like the
/// read column was the tuple element with this name.
/// It's used while reading subcolumns of complex types.
/// In particular while reading components of named tuples.
class SerializationNamed final : public SerializationWrapper
{
private:
Expand Down
7 changes: 7 additions & 0 deletions tests/queries/0_stateless/02184_nested_tuple.reference
@@ -0,0 +1,7 @@
{"endUserIDs":{"_experience":{"aaid":{"id":"id_1","namespace":{"code":"code_1"},"primary":1},"mcid":{"id":"id_2","namespace":{"code":"code_2"},"primary":2}}}}
{"endUserIDs._experience":{"aaid":{"id":"id_1","namespace":{"code":"code_1"},"primary":1},"mcid":{"id":"id_2","namespace":{"code":"code_2"},"primary":2}}}
{"endUserIDs._experience.aaid":{"id":"id_1","namespace":{"code":"code_1"},"primary":1}}
{"endUserIDs._experience.aaid.id":"id_1"}
{"endUserIDs._experience.aaid.namespace":{"code":"code_1"}}
{"endUserIDs._experience.aaid.namespace.code":"code_1"}
{"endUserIDs._experience.aaid.primary":1}
38 changes: 38 additions & 0 deletions tests/queries/0_stateless/02184_nested_tuple.sql
@@ -0,0 +1,38 @@
DROP TABLE IF EXISTS t_nested_tuple;

CREATE TABLE t_nested_tuple
(
endUserIDs Tuple(
_experience Tuple(
aaid Tuple(
id Nullable(String),
namespace Tuple(
code LowCardinality(Nullable(String))
),
primary LowCardinality(Nullable(UInt8))
),
mcid Tuple(
id Nullable(String),
namespace Tuple(
code LowCardinality(Nullable(String))
),
primary LowCardinality(Nullable(UInt8))
)
)
)
)
ENGINE = MergeTree ORDER BY tuple();

SET output_format_json_named_tuples_as_objects = 1;

INSERT INTO t_nested_tuple FORMAT JSONEachRow {"endUserIDs":{"_experience":{"aaid":{"id":"id_1","namespace":{"code":"code_1"},"primary":1},"mcid":{"id":"id_2","namespace":{"code":"code_2"},"primary":2}}}};

SELECT * FROM t_nested_tuple FORMAT JSONEachRow;
SELECT endUserIDs._experience FROM t_nested_tuple FORMAT JSONEachRow;
SELECT endUserIDs._experience.aaid FROM t_nested_tuple FORMAT JSONEachRow;
SELECT endUserIDs._experience.aaid.id FROM t_nested_tuple FORMAT JSONEachRow;
SELECT endUserIDs._experience.aaid.namespace FROM t_nested_tuple FORMAT JSONEachRow;
SELECT endUserIDs._experience.aaid.namespace.code FROM t_nested_tuple FORMAT JSONEachRow;
SELECT endUserIDs._experience.aaid.primary FROM t_nested_tuple FORMAT JSONEachRow;

DROP TABLE t_nested_tuple;

0 comments on commit bc393af

Please sign in to comment.