ClickHouse / ClickHouse/clickhouse-cpp

Reading LowCardinality(Nullable(String)) column is not supported (for the data received from ClickHouse)

Abierto
#504 0 comentarios 0 reacciones 0 asignados Ver en GitHub
Lenguaje dominante
C
Estrellas
382
Forks
209
Merge medio
2 d 19 h
PR fusionados (30 d)
14

Descripción

>
> Please see https://github.com/ClickHouse/clickhouse-cpp/pull/339
>
>
>
> [This one confirms that it works](https://github.com/ClickHouse/clickhouse-cpp/pull/339/files#diff-5ba05c8bd7182b90fb7e5b5b010e00c29c723612eb084a0b24b6f897fb45c531L215)
>
>
>
> Perhaps, it would be helpful to know the real type of column at run-time with:
>
> ```c++
>
> column->GetType().GetName()
>
> ```

_Originally posted by @Enmk in [#326](https://github.com/ClickHouse/clickhouse-cpp/issues/326#issuecomment-1759450216)_

The [test](https://github.com/ClickHouse/clickhouse-cpp/blob/v2.6.1/ut/roundtrip_tests.cpp#L279) _Map_LowCardinalityTString_LowCardinalityTNullableString_ might succeed, but this is only true because you create the column with the type `ColumnLowCardinalityT>` explicitly in the test.

However, for the real data received from _ClickHouse_ the type of the underlying column will be simply `ColumnLowCardinality`. This is probably due to the [logic](https://github.com/ClickHouse/clickhouse-cpp/blob/v2.6.1/clickhouse/columns/factory.cpp#L226) implemented in https://github.com/ClickHouse/clickhouse-cpp/pull/182:
```
case Type::Nullable:
return std::make_shared(
std::make_shared(
CreateColumnFromAst(GetASTChildElement(nested, 0), settings),
std::make_shared()
)
);
```
Therefore the `dynamic_cast` inside `column->As>>()` will yield _nullptr_.

This is easily illustrated with a simple **typeid** check (assume that `column` is an instance of a `ColumnRef` pointer).

This is what we have for `LowCardinality(String)` column:
```
// ColumnRef column;

auto type_name = column->GetType().GetName(); // "LowCardinality(String)"

auto type_id = typeid(*column).name(); // clickhouse::ColumnLowCardinalityT ("N10clickhouse21ColumnLowCardinalityTINS_12ColumnStringEEE")
```
And this is the result for `LowCardinality(Nullable(String))`:
```
// ColumnRef column;

auto type_name = column->GetType().GetName(); // "LowCardinality(Nullable(String))"

auto type_id = typeid(*column).name(); // clickhouse::ColumnLowCardinality ("N10clickhouse20ColumnLowCardinalityE")
```

The conclusion is that it's not possible to read `LowCardinality(Nullable(String))` column in the current version of _clickhouse-cpp_ (_v2.6.1_):
1. `column->As>>()` doesn't work for the reasons explained above.
2. While `column->As()` does work, it's of no help: trying to wrap the result into `ColumnLowCardinalityT>` will also fail because the nested type is `ColumnNullable` (not `ColumnNullableT`).
3. Declaring `ColumnLowCardinalityT` is not possible because there's no `ValueType` alias in `ColumnNullable`.

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Línea de trabajo

Comienza en clickhouse/columns/factory.cpp, alrededor del manejo de Nullable, y compáralo con ut/roundtrip_tests.cpp en Map_LowCardinalityTString_LowCardinalityTNullableString_. Inspecciona ColumnRef::As y GetType().GetName() para las columnas recibidas de ClickHouse, en lugar de examinar únicamente las columnas construidas localmente. La tarea está terminada cuando los datos LowCardinality(Nullable(String)) se puedan leer de una respuesta real de ClickHouse y exista una prueba de regresión.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
cpp
Área
databases
Tipo de issue
Error
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Tranquilo
Claridad
Bastante claro
Aptitud para principiantes
48/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.