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
9namespace DB
10{
11
12namespace 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 */
22class IColumnDummy : public IColumn
23{
24public:
25 IColumnDummy() : s(0) {}
26 IColumnDummy(size_t s_) : s(s_) {}
27
28public:
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
149protected:
150 size_t s;
151};
152
153}
154