ClickHouse / ClickHouse/clickhouse-cpp
Reading LowCardinality(Nullable(String)) column is not supported (for the data received from ClickHouse)
- 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