ClickHouse / ClickHouse/clickhouse-cpp

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

Aperta
#504 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub
Lingua principale
C
Stelle
382
Fork
209
Merge medio
1g 22h
PR unite (30g)
13

Descrizione

>
> 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`.

Guida per i contributori

Nessuna guida per i contributori indicizzata per questo repository

Direzione di ricerca

Inizia da clickhouse/columns/factory.cpp, nella parte relativa alla gestione di Nullable, e confrontala con ut/roundtrip_tests.cpp in Map_LowCardinalityTString_LowCardinalityTNullableString_. Esamina ColumnRef::As e GetType().GetName() per le colonne ricevute da ClickHouse, invece di considerare soltanto le colonne costruite localmente. Il lavoro è completato quando i dati LowCardinality(Nullable(String)) possono essere letti da una risposta reale di ClickHouse ed esiste un test di regressione.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
cpp
Ambito
databases
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Tranquilla
Chiarezza
Abbastanza chiara
Idoneità per principianti
48/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.