1 | #pragma once |
2 | |
3 | #include <Common/Arena.h> |
4 | #include <Common/PODArray.h> |
5 | #include <Columns/IColumn.h> |
6 | #include <Columns/ColumnsCommon.h> |
7 | |
8 | |
9 | namespace DB |
10 | { |
11 | |
12 | namespace ErrorCodes |
13 | { |
14 | extern const int SIZES_OF_COLUMNS_DOESNT_MATCH; |
15 | extern const int NOT_IMPLEMENTED; |
16 | } |
17 | |
18 | |
19 | /** Base class for columns-constants that contain a value that is not in the `Field`. |
20 | * Not a full-fledged column and is used in a special way. |
21 | */ |
22 | class IColumnDummy : public IColumn |
23 | { |
24 | public: |
25 | IColumnDummy() : s(0) {} |
26 | IColumnDummy(size_t s_) : s(s_) {} |
27 | |
28 | public: |
29 | virtual MutableColumnPtr cloneDummy(size_t s_) const = 0; |
30 | |
31 | MutableColumnPtr cloneResized(size_t s_) const override { return cloneDummy(s_); } |
32 | size_t size() const override { return s; } |
33 | void insertDefault() override { ++s; } |
34 | void popBack(size_t n) override { s -= n; } |
35 | size_t byteSize() const override { return 0; } |
36 | size_t allocatedBytes() const override { return 0; } |
37 | int compareAt(size_t, size_t, const IColumn &, int) const override { return 0; } |
38 | |
39 | Field operator[](size_t) const override { throw Exception("Cannot get value from " + getName(), ErrorCodes::NOT_IMPLEMENTED); } |
40 | void get(size_t, Field &) const override { throw Exception("Cannot get value from " + getName(), ErrorCodes::NOT_IMPLEMENTED); } |
41 | void insert(const Field &) override { throw Exception("Cannot insert element into " + getName(), ErrorCodes::NOT_IMPLEMENTED); } |
42 | |
43 | StringRef getDataAt(size_t) const override |
44 | { |
45 | return {}; |
46 | } |
47 | |
48 | void insertData(const char *, size_t) override |
49 | { |
50 | ++s; |
51 | } |
52 | |
53 | StringRef serializeValueIntoArena(size_t /*n*/, Arena & arena, char const *& begin) const override |
54 | { |
55 | return { arena.allocContinue(0, begin), 0 }; |
56 | } |
57 | |
58 | const char * deserializeAndInsertFromArena(const char * pos) override |
59 | { |
60 | ++s; |
61 | return pos; |
62 | } |
63 | |
64 | void updateHashWithValue(size_t /*n*/, SipHash & /*hash*/) const override |
65 | { |
66 | } |
67 | |
68 | void insertFrom(const IColumn &, size_t) override |
69 | { |
70 | ++s; |
71 | } |
72 | |
73 | void insertRangeFrom(const IColumn & /*src*/, size_t /*start*/, size_t length) override |
74 | { |
75 | s += length; |
76 | } |
77 | |
78 | ColumnPtr filter(const Filter & filt, ssize_t /*result_size_hint*/) const override |
79 | { |
80 | return cloneDummy(countBytesInFilter(filt)); |
81 | } |
82 | |
83 | ColumnPtr permute(const Permutation & perm, size_t limit) const override |
84 | { |
85 | if (s != perm.size()) |
86 | throw Exception("Size of permutation doesn't match size of column." , ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH); |
87 | |
88 | return cloneDummy(limit ? std::min(s, limit) : s); |
89 | } |
90 | |
91 | ColumnPtr index(const IColumn & indexes, size_t limit) const override |
92 | { |
93 | if (indexes.size() < limit) |
94 | throw Exception("Size of indexes is less than required." , ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH); |
95 | |
96 | return cloneDummy(limit ? limit : s); |
97 | } |
98 | |
99 | void getPermutation(bool /*reverse*/, size_t /*limit*/, int /*nan_direction_hint*/, Permutation & res) const override |
100 | { |
101 | res.resize(s); |
102 | for (size_t i = 0; i < s; ++i) |
103 | res[i] = i; |
104 | } |
105 | |
106 | ColumnPtr replicate(const Offsets & offsets) const override |
107 | { |
108 | if (s != offsets.size()) |
109 | throw Exception("Size of offsets doesn't match size of column." , ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH); |
110 | |
111 | return cloneDummy(offsets.back()); |
112 | } |
113 | |
114 | MutableColumns scatter(ColumnIndex num_columns, const Selector & selector) const override |
115 | { |
116 | if (s != selector.size()) |
117 | throw Exception("Size of selector doesn't match size of column." , ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH); |
118 | |
119 | std::vector<size_t> counts(num_columns); |
120 | for (auto idx : selector) |
121 | ++counts[idx]; |
122 | |
123 | MutableColumns res(num_columns); |
124 | for (size_t i = 0; i < num_columns; ++i) |
125 | res[i] = cloneResized(counts[i]); |
126 | |
127 | return res; |
128 | } |
129 | |
130 | void gather(ColumnGathererStream &) override |
131 | { |
132 | throw Exception("Method gather is not supported for " + getName(), ErrorCodes::NOT_IMPLEMENTED); |
133 | } |
134 | |
135 | void getExtremes(Field &, Field &) const override |
136 | { |
137 | } |
138 | |
139 | void addSize(size_t delta) |
140 | { |
141 | s += delta; |
142 | } |
143 | |
144 | bool isDummy() const override |
145 | { |
146 | return true; |
147 | } |
148 | |
149 | protected: |
150 | size_t s; |
151 | }; |
152 | |
153 | } |
154 | |