ClickHouse / ClickHouse/clickhouse-cpp
Reading LowCardinality(Nullable(String)) column is not supported (for the data received from ClickHouse)
- Ngôn ngữ chính
- C
- Star
- 382
- Fork
- 208
- Merge trung bình
- 2 ngày 19 giờ
- Pull request đã merge (30 ngày)
- 14
Mô tả
>
> 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`.
Hướng dẫn đóng góp
Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này
Hướng nghiên cứu
Bắt đầu với phần xử lý Nullable trong clickhouse/columns/factory.cpp và đối chiếu với Map_LowCardinalityTString_LowCardinalityTNullableString_ trong ut/roundtrip_tests.cpp. Kiểm tra ColumnRef::As và GetType().GetName() đối với các cột nhận được từ ClickHouse, thay vì chỉ kiểm tra các cột được tạo cục bộ. Công việc được xem là hoàn tất khi có thể đọc dữ liệu LowCardinality(Nullable(String)) từ một phản hồi ClickHouse thực tế và có một regression test.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Đánh giá
- Công nghệ
- cpp
- Lĩnh vực
- databases
- Loại issue
- Lỗi
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức độ hoạt động
- Ít trao đổi
- Độ rõ ràng
- Khá rõ ràng
- Mức phù hợp với người mới
- 48/100