1#include <IO/WriteHelpers.h>
2
3#include <Columns/ColumnConst.h>
4#include <Columns/ColumnsCommon.h>
5#include <Common/PODArray.h>
6#include <Common/typeid_cast.h>
7
8
9namespace DB
10{
11
12namespace ErrorCodes
13{
14 extern const int SIZES_OF_COLUMNS_DOESNT_MATCH;
15}
16
17ColumnConst::ColumnConst(const ColumnPtr & data_, size_t s_)
18 : data(data_), s(s_)
19{
20 /// Squash Const of Const.
21 while (const ColumnConst * const_data = typeid_cast<const ColumnConst *>(data.get()))
22 data = const_data->getDataColumnPtr();
23
24 if (data->size() != 1)
25 throw Exception("Incorrect size of nested column in constructor of ColumnConst: " + toString(data->size()) + ", must be 1.",
26 ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);
27}
28
29ColumnPtr ColumnConst::convertToFullColumn() const
30{
31 return data->replicate(Offsets(1, s));
32}
33
34ColumnPtr ColumnConst::removeLowCardinality() const
35{
36 return ColumnConst::create(data->convertToFullColumnIfLowCardinality(), s);
37}
38
39ColumnPtr ColumnConst::filter(const Filter & filt, ssize_t /*result_size_hint*/) const
40{
41 if (s != filt.size())
42 throw Exception("Size of filter (" + toString(filt.size()) + ") doesn't match size of column (" + toString(s) + ")",
43 ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);
44
45 return ColumnConst::create(data, countBytesInFilter(filt));
46}
47
48ColumnPtr ColumnConst::replicate(const Offsets & offsets) const
49{
50 if (s != offsets.size())
51 throw Exception("Size of offsets (" + toString(offsets.size()) + ") doesn't match size of column (" + toString(s) + ")",
52 ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);
53
54 size_t replicated_size = 0 == s ? 0 : offsets.back();
55 return ColumnConst::create(data, replicated_size);
56}
57
58ColumnPtr ColumnConst::permute(const Permutation & perm, size_t limit) const
59{
60 if (limit == 0)
61 limit = s;
62 else
63 limit = std::min(s, limit);
64
65 if (perm.size() < limit)
66 throw Exception("Size of permutation (" + toString(perm.size()) + ") is less than required (" + toString(limit) + ")",
67 ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);
68
69 return ColumnConst::create(data, limit);
70}
71
72ColumnPtr ColumnConst::index(const IColumn & indexes, size_t limit) const
73{
74 if (limit == 0)
75 limit = indexes.size();
76
77 if (indexes.size() < limit)
78 throw Exception("Size of indexes (" + toString(indexes.size()) + ") is less than required (" + toString(limit) + ")",
79 ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);
80
81 return ColumnConst::create(data, limit);
82}
83
84MutableColumns ColumnConst::scatter(ColumnIndex num_columns, const Selector & selector) const
85{
86 if (s != selector.size())
87 throw Exception("Size of selector (" + toString(selector.size()) + ") doesn't match size of column (" + toString(s) + ")",
88 ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);
89
90 std::vector<size_t> counts = countColumnsSizeInSelector(num_columns, selector);
91
92 MutableColumns res(num_columns);
93 for (size_t i = 0; i < num_columns; ++i)
94 res[i] = cloneResized(counts[i]);
95
96 return res;
97}
98
99void ColumnConst::getPermutation(bool /*reverse*/, size_t /*limit*/, int /*nan_direction_hint*/, Permutation & res) const
100{
101 res.resize(s);
102 for (size_t i = 0; i < s; ++i)
103 res[i] = i;
104}
105
106}
107