1 | #pragma once |
---|---|
2 | |
3 | #include <DataStreams/IBlockInputStream.h> |
4 | #include <Columns/ColumnLowCardinality.h> |
5 | #include <DataTypes/DataTypeLowCardinality.h> |
6 | #include <Columns/ColumnConst.h> |
7 | |
8 | namespace DB |
9 | { |
10 | |
11 | |
12 | /** Combines several sources into one. |
13 | * Unlike UnionBlockInputStream, it does this sequentially. |
14 | * Blocks of different sources are not interleaved with each other. |
15 | */ |
16 | class ConvertColumnLowCardinalityToFullBlockInputStream : public IBlockInputStream |
17 | { |
18 | public: |
19 | explicit ConvertColumnLowCardinalityToFullBlockInputStream(const BlockInputStreamPtr & input) |
20 | { |
21 | children.push_back(input); |
22 | } |
23 | |
24 | String getName() const override { return "ConvertColumnLowCardinalityToFull"; } |
25 | |
26 | Block getHeader() const override { return convert(children.at(0)->getHeader()); } |
27 | |
28 | protected: |
29 | Block readImpl() override { return convert(children.back()->read()); } |
30 | |
31 | private: |
32 | Block convert(Block && block) const |
33 | { |
34 | for (auto & column : block) |
35 | { |
36 | if (auto * column_const = typeid_cast<const ColumnConst *>(column.column.get())) |
37 | column.column = column_const->removeLowCardinality(); |
38 | else |
39 | column.column = column.column->convertToFullColumnIfLowCardinality(); |
40 | |
41 | if (auto * low_cardinality_type = typeid_cast<const DataTypeLowCardinality *>(column.type.get())) |
42 | column.type = low_cardinality_type->getDictionaryType(); |
43 | } |
44 | |
45 | return std::move(block); |
46 | } |
47 | }; |
48 | |
49 | } |
50 |