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
8namespace 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 */
16class ConvertColumnLowCardinalityToFullBlockInputStream : public IBlockInputStream
17{
18public:
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
28protected:
29 Block readImpl() override { return convert(children.back()->read()); }
30
31private:
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