|
2 | 2 |
|
3 | 3 | #include "utils.h" |
4 | 4 |
|
5 | | -namespace clickhouse { |
6 | | - |
7 | | -ColumnPoint::ColumnPoint() |
8 | | - : Column(Type::CreatePoint()), |
9 | | - data_(std::make_shared<ColumnTupleT<ColumnFloat64, ColumnFloat64>>( |
10 | | - std::make_tuple(std::make_shared<ColumnFloat64>(), std::make_shared<ColumnFloat64>()))) { |
11 | | -} |
12 | | - |
13 | | -ColumnPoint::ColumnPoint(ColumnRef data) |
14 | | - : Column(Type::CreatePoint()), data_(WrapColumn<ColumnTupleT<ColumnFloat64, ColumnFloat64>>(std::move(data))) { |
15 | | -} |
16 | | - |
17 | | -void ColumnPoint::Append(const Point& value) { |
18 | | - data_->Append(value); |
19 | | -} |
20 | | - |
21 | | -void ColumnPoint::Clear() { |
22 | | - data_->Clear(); |
23 | | -} |
24 | | - |
25 | | -const ColumnPoint::Point ColumnPoint::At(size_t n) const { |
26 | | - return data_->At(n); |
27 | | -} |
28 | | - |
29 | | -const ColumnPoint::Point ColumnPoint::operator[](size_t n) const { |
30 | | - return data_->At(n); |
31 | | -} |
32 | | - |
33 | | -void ColumnPoint::Append(ColumnRef column) { |
34 | | - if (auto col = column->As<ColumnPoint>()) { |
35 | | - data_->Append(col->data_->As<Column>()); |
| 5 | +namespace { |
| 6 | +using namespace ::clickhouse; |
| 7 | + |
| 8 | +template <Type::Code type_code> |
| 9 | +TypeRef CreateGeoType() { |
| 10 | + if constexpr (type_code == Type::Code::Point) { |
| 11 | + return Type::CreatePoint(); |
| 12 | + } else if constexpr (type_code == Type::Code::Ring) { |
| 13 | + return Type::CreateRing(); |
| 14 | + } else if constexpr (type_code == Type::Code::Polygon) { |
| 15 | + return Type::CreatePolygon(); |
| 16 | + } else if constexpr (type_code == Type::Code::MultiPolygon) { |
| 17 | + return Type::CreateMultiPolygon(); |
36 | 18 | } |
37 | 19 | } |
38 | 20 |
|
39 | | -bool ColumnPoint::LoadBody(InputStream* input, size_t rows) { |
40 | | - return data_->LoadBody(input, rows); |
41 | | -} |
42 | | - |
43 | | -void ColumnPoint::SaveBody(OutputStream* output) { |
44 | | - data_->SaveBody(output); |
45 | | -} |
46 | | - |
47 | | -size_t ColumnPoint::Size() const { |
48 | | - return data_->Size(); |
49 | | -} |
50 | | - |
51 | | -ColumnRef ColumnPoint::Slice(size_t begin, size_t len) const { |
52 | | - return std::make_shared<ColumnPoint>(data_->Slice(begin, len)); |
53 | | -} |
54 | | - |
55 | | -ColumnRef ColumnPoint::CloneEmpty() const { |
56 | | - return std::make_shared<ColumnPoint>(); |
57 | | -} |
58 | | - |
59 | | -void ColumnPoint::Swap(Column& other) { |
60 | | - auto& col = dynamic_cast<ColumnPoint&>(other); |
61 | | - data_.swap(col.data_); |
62 | | -} |
63 | | - |
64 | | -ColumnRing::ColumnRing() : Column(Type::CreateRing()), data_(std::make_shared<ColumnArrayT<ColumnPoint>>()) { |
65 | | -} |
66 | | - |
67 | | -ColumnRing::ColumnRing(ColumnRef data) : Column(Type::CreateRing()), data_(WrapColumn<ColumnArrayT<ColumnPoint>>(std::move(data))) { |
68 | | -} |
69 | | - |
70 | | -void ColumnRing::Clear() { |
71 | | - data_->Clear(); |
72 | | -} |
73 | | - |
74 | | -const ColumnRing::Ring ColumnRing::At(size_t n) const { |
75 | | - return data_->At(n); |
76 | | -} |
77 | | - |
78 | | -const ColumnRing::Ring ColumnRing::operator[](size_t n) const { |
79 | | - return data_->At(n); |
80 | | -} |
81 | | - |
82 | | -void ColumnRing::Append(ColumnRef column) { |
83 | | - if (auto col = column->As<ColumnRing>()) { |
84 | | - data_->Append(col->data_->As<Column>()); |
| 21 | +template <typename ColumnType> |
| 22 | +std::shared_ptr<ColumnType> CreateColumn() { |
| 23 | + if constexpr (std::is_same_v<ColumnType, ColumnTupleT<ColumnFloat64, ColumnFloat64>>) { |
| 24 | + return std::make_shared<ColumnTupleT<ColumnFloat64, ColumnFloat64>>( |
| 25 | + std::make_tuple(std::make_shared<ColumnFloat64>(), std::make_shared<ColumnFloat64>())); |
| 26 | + } else { |
| 27 | + return std::make_shared<ColumnType>(); |
85 | 28 | } |
86 | 29 | } |
87 | 30 |
|
88 | | -bool ColumnRing::LoadBody(InputStream* input, size_t rows) { |
89 | | - return data_->LoadBody(input, rows); |
90 | | -} |
91 | | - |
92 | | -void ColumnRing::SaveBody(OutputStream* output) { |
93 | | - data_->SaveBody(output); |
94 | | -} |
95 | | - |
96 | | -size_t ColumnRing::Size() const { |
97 | | - return data_->Size(); |
98 | | -} |
99 | | - |
100 | | -ColumnRef ColumnRing::Slice(size_t begin, size_t len) const { |
101 | | - return std::make_shared<ColumnRing>(data_->Slice(begin, len)); |
102 | | -} |
103 | | - |
104 | | -ColumnRef ColumnRing::CloneEmpty() const { |
105 | | - return std::make_shared<ColumnRing>(); |
106 | | -} |
| 31 | +} // namespace |
107 | 32 |
|
108 | | -void ColumnRing::Swap(Column& other) { |
109 | | - auto& col = dynamic_cast<ColumnRing&>(other); |
110 | | - data_.swap(col.data_); |
111 | | -} |
| 33 | +namespace clickhouse { |
112 | 34 |
|
113 | | -ColumnPolygon::ColumnPolygon() : Column(Type::CreatePolygon()), data_(std::make_shared<ColumnArrayT<ColumnRing>>()) { |
| 35 | +template <typename NestedColumnType, Type::Code type_code> |
| 36 | +ColumnGeo<NestedColumnType, type_code>::ColumnGeo() |
| 37 | + : Column(std::move(CreateGeoType<type_code>())), |
| 38 | + data_(std::move(CreateColumn<NestedColumnType>())) { |
114 | 39 | } |
115 | 40 |
|
116 | | -ColumnPolygon::ColumnPolygon(ColumnRef data) : Column(Type::CreatePolygon()), data_(WrapColumn<ColumnArrayT<ColumnRing>>(std::move(data))) { |
| 41 | +template <typename NestedColumnType, Type::Code type_code> |
| 42 | +ColumnGeo<NestedColumnType, type_code>::ColumnGeo(ColumnRef data) |
| 43 | + : Column(std::move(CreateGeoType<type_code>())) |
| 44 | + , data_(std::move(WrapColumn<NestedColumnType>(std::move(data)))) { |
117 | 45 | } |
118 | 46 |
|
119 | | -void ColumnPolygon::Clear() { |
| 47 | +template <typename NestedColumnType, Type::Code type_code> |
| 48 | +void ColumnGeo<NestedColumnType, type_code>::Clear() { |
120 | 49 | data_->Clear(); |
121 | 50 | } |
122 | 51 |
|
123 | | -const ColumnPolygon::Polygon ColumnPolygon::At(size_t n) const { |
| 52 | +template <typename NestedColumnType, Type::Code type_code> |
| 53 | +const typename ColumnGeo<NestedColumnType, type_code>::ValueType ColumnGeo<NestedColumnType, type_code>::At(size_t n) const { |
124 | 54 | return data_->At(n); |
125 | 55 | } |
126 | 56 |
|
127 | | -const ColumnPolygon::Polygon ColumnPolygon::operator[](size_t n) const { |
| 57 | +template <typename NestedColumnType, Type::Code type_code> |
| 58 | +const typename ColumnGeo<NestedColumnType, type_code>::ValueType ColumnGeo<NestedColumnType, type_code>::operator[](size_t n) const { |
128 | 59 | return data_->At(n); |
129 | 60 | } |
130 | 61 |
|
131 | | -void ColumnPolygon::Append(ColumnRef column) { |
132 | | - if (auto col = column->As<ColumnPolygon>()) { |
133 | | - data_->Append(col->data_->As<Column>()); |
| 62 | +template <typename NestedColumnType, Type::Code type_code> |
| 63 | +void ColumnGeo<NestedColumnType, type_code>::Append(ColumnRef column) { |
| 64 | + if (auto col = column->template As<ColumnGeo>()) { |
| 65 | + data_->Append(col->data_->template As<Column>()); |
134 | 66 | } |
135 | 67 | } |
136 | 68 |
|
137 | | -bool ColumnPolygon::LoadBody(InputStream* input, size_t rows) { |
| 69 | +template <typename NestedColumnType, Type::Code type_code> |
| 70 | +bool ColumnGeo<NestedColumnType, type_code>::LoadBody(InputStream* input, size_t rows) { |
138 | 71 | return data_->LoadBody(input, rows); |
139 | 72 | } |
140 | 73 |
|
141 | | -void ColumnPolygon::SaveBody(OutputStream* output) { |
| 74 | +template <typename NestedColumnType, Type::Code type_code> |
| 75 | +void ColumnGeo<NestedColumnType, type_code>::SaveBody(OutputStream* output) { |
142 | 76 | data_->SaveBody(output); |
143 | 77 | } |
144 | 78 |
|
145 | | -size_t ColumnPolygon::Size() const { |
| 79 | +template <typename NestedColumnType, Type::Code type_code> |
| 80 | +size_t ColumnGeo<NestedColumnType, type_code>::Size() const { |
146 | 81 | return data_->Size(); |
147 | 82 | } |
148 | 83 |
|
149 | | -ColumnRef ColumnPolygon::Slice(size_t begin, size_t len) const { |
150 | | - return std::make_shared<ColumnPolygon>(data_->Slice(begin, len)); |
| 84 | +template <typename NestedColumnType, Type::Code type_code> |
| 85 | +ColumnRef ColumnGeo<NestedColumnType, type_code>::Slice(size_t begin, size_t len) const { |
| 86 | + return std::make_shared<ColumnGeo>(data_->Slice(begin, len)); |
151 | 87 | } |
152 | 88 |
|
153 | | -ColumnRef ColumnPolygon::CloneEmpty() const { |
154 | | - return std::make_shared<ColumnPolygon>(); |
| 89 | +template <typename NestedColumnType, Type::Code type_code> |
| 90 | +ColumnRef ColumnGeo<NestedColumnType, type_code>::CloneEmpty() const { |
| 91 | + return std::make_shared<ColumnGeo>(); |
155 | 92 | } |
156 | 93 |
|
157 | | -void ColumnPolygon::Swap(Column& other) { |
158 | | - auto& col = dynamic_cast<ColumnPolygon&>(other); |
| 94 | +template <typename NestedColumnType, Type::Code type_code> |
| 95 | +void ColumnGeo<NestedColumnType, type_code>::Swap(Column& other) { |
| 96 | + auto& col = dynamic_cast<ColumnGeo&>(other); |
159 | 97 | data_.swap(col.data_); |
160 | 98 | } |
161 | 99 |
|
162 | | -ColumnMultiPolygon::ColumnMultiPolygon() : Column(Type::CreateMultiPolygon()), data_(std::make_shared<ColumnArrayT<ColumnPolygon>>()) { |
163 | | -} |
164 | | - |
165 | | -ColumnMultiPolygon::ColumnMultiPolygon(ColumnRef data) |
166 | | - : Column(Type::CreateMultiPolygon()), data_(WrapColumn<ColumnArrayT<ColumnPolygon>>(std::move(data))) { |
167 | | -} |
168 | | - |
169 | | -void ColumnMultiPolygon::Clear() { |
170 | | - data_->Clear(); |
171 | | -} |
172 | | - |
173 | | -const ColumnMultiPolygon::MultiPolygon ColumnMultiPolygon::At(size_t n) const { |
174 | | - return data_->At(n); |
175 | | -} |
176 | | - |
177 | | -const ColumnMultiPolygon::MultiPolygon ColumnMultiPolygon::operator[](size_t n) const { |
178 | | - return data_->At(n); |
179 | | -} |
180 | | - |
181 | | -void ColumnMultiPolygon::Append(ColumnRef column) { |
182 | | - if (auto col = column->As<ColumnMultiPolygon>()) { |
183 | | - data_->Append(col->data_->As<Column>()); |
184 | | - } |
185 | | -} |
186 | | - |
187 | | -bool ColumnMultiPolygon::LoadBody(InputStream* input, size_t rows) { |
188 | | - return data_->LoadBody(input, rows); |
189 | | -} |
190 | | - |
191 | | -void ColumnMultiPolygon::SaveBody(OutputStream* output) { |
192 | | - data_->SaveBody(output); |
193 | | -} |
| 100 | +template class ColumnGeo<ColumnTupleT<ColumnFloat64, ColumnFloat64>, Type::Code::Point>; |
194 | 101 |
|
195 | | -size_t ColumnMultiPolygon::Size() const { |
196 | | - return data_->Size(); |
197 | | -} |
| 102 | +template class ColumnGeo<ColumnArrayT<ColumnPoint>, Type::Code::Ring>; |
198 | 103 |
|
199 | | -ColumnRef ColumnMultiPolygon::Slice(size_t begin, size_t len) const { |
200 | | - return std::make_shared<ColumnMultiPolygon>(data_->Slice(begin, len)); |
201 | | -} |
202 | | - |
203 | | -ColumnRef ColumnMultiPolygon::CloneEmpty() const { |
204 | | - return std::make_shared<ColumnMultiPolygon>(); |
205 | | -} |
| 104 | +template class ColumnGeo<ColumnArrayT<ColumnRing>, Type::Code::Polygon>; |
206 | 105 |
|
207 | | -void ColumnMultiPolygon::Swap(Column& other) { |
208 | | - auto& col = dynamic_cast<ColumnMultiPolygon&>(other); |
209 | | - data_.swap(col.data_); |
210 | | -} |
| 106 | +template class ColumnGeo<ColumnArrayT<ColumnPolygon>, Type::Code::MultiPolygon>; |
211 | 107 |
|
212 | 108 | } // namespace clickhouse |
0 commit comments