/Users/deen/code/yugabyte-db/src/yb/common/wire_protocol.cc
Line | Count | Source (jump to first uncovered line) |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. You may obtain a copy of the License at |
8 | | // |
9 | | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | | // |
11 | | // Unless required by applicable law or agreed to in writing, |
12 | | // software distributed under the License is distributed on an |
13 | | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | | // KIND, either express or implied. See the License for the |
15 | | // specific language governing permissions and limitations |
16 | | // under the License. |
17 | | // |
18 | | // The following only applies to changes made to this file as part of YugaByte development. |
19 | | // |
20 | | // Portions Copyright (c) YugaByte, Inc. |
21 | | // |
22 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
23 | | // in compliance with the License. You may obtain a copy of the License at |
24 | | // |
25 | | // http://www.apache.org/licenses/LICENSE-2.0 |
26 | | // |
27 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
28 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
29 | | // or implied. See the License for the specific language governing permissions and limitations |
30 | | // under the License. |
31 | | // |
32 | | #include "yb/common/wire_protocol.h" |
33 | | |
34 | | #include <string> |
35 | | #include <vector> |
36 | | |
37 | | #include "yb/common/common.pb.h" |
38 | | #include "yb/common/ql_type.h" |
39 | | #include "yb/common/schema.h" |
40 | | #include "yb/common/wire_protocol.pb.h" |
41 | | |
42 | | #include "yb/gutil/port.h" |
43 | | #include "yb/gutil/stl_util.h" |
44 | | #include "yb/gutil/strings/fastmem.h" |
45 | | #include "yb/gutil/strings/substitute.h" |
46 | | #include "yb/util/enums.h" |
47 | | #include "yb/util/errno.h" |
48 | | #include "yb/util/faststring.h" |
49 | | #include "yb/util/logging.h" |
50 | | #include "yb/util/net/net_util.h" |
51 | | #include "yb/util/net/sockaddr.h" |
52 | | #include "yb/util/result.h" |
53 | | #include "yb/util/slice.h" |
54 | | #include "yb/util/status_format.h" |
55 | | #include "yb/yql/cql/ql/util/errcodes.h" |
56 | | |
57 | | using google::protobuf::RepeatedPtrField; |
58 | | using std::vector; |
59 | | |
60 | | DEFINE_string(use_private_ip, "never", |
61 | | "When to use private IP for connection. " |
62 | | "cloud - would use private IP if destination node is located in the same cloud. " |
63 | | "region - would use private IP if destination node is located in the same cloud and " |
64 | | "region. " |
65 | | "zone - would use private IP if destination node is located in the same cloud, " |
66 | | "region and zone." |
67 | | "never - would never use private IP if broadcast address is specified."); |
68 | | namespace yb { |
69 | | |
70 | | namespace { |
71 | | |
72 | | YB_STRONGLY_TYPED_BOOL(PublicAddressAllowed); |
73 | | |
74 | | template <class Index, class Value> |
75 | | void SetAt( |
76 | 872k | Index index, const Value& value, const Value& default_value, std::vector<Value>* vector) { |
77 | 872k | size_t int_index = static_cast<size_t>(index); |
78 | 872k | size_t new_size = vector->size(); |
79 | 1.04M | while (new_size <= int_index) { |
80 | 168k | new_size = std::max<size_t>(1, new_size * 2); |
81 | 168k | } |
82 | 872k | vector->resize(new_size, default_value); |
83 | 872k | (*vector)[int_index] = value; |
84 | 872k | } |
85 | | |
86 | 28.1k | std::vector<AppStatusPB::ErrorCode> CreateStatusToErrorCode() { |
87 | 28.1k | std::vector<AppStatusPB::ErrorCode> result; |
88 | 28.1k | const auto default_value = AppStatusPB::UNKNOWN_ERROR; |
89 | 28.1k | #define YB_STATUS_CODE(name, pb_name, value, message) \ |
90 | 872k | SetAt(Status::BOOST_PP_CAT(k, name), AppStatusPB::pb_name, default_value, &result); \ |
91 | 872k | static_assert( \ |
92 | 872k | static_cast<int32_t>(to_underlying(AppStatusPB::pb_name)) == \ |
93 | 872k | to_underlying(Status::BOOST_PP_CAT(k, name)), \ |
94 | 872k | "The numeric value of AppStatusPB::" BOOST_PP_STRINGIZE(pb_name) " defined in" \ |
95 | 872k | " wire_protocol.proto does not match the value of Status::k" BOOST_PP_STRINGIZE(name) \ |
96 | 872k | " defined in status.h."); |
97 | 28.1k | #include "yb/util/status_codes.h" |
98 | 28.1k | #undef YB_STATUS_CODE |
99 | 28.1k | return result; |
100 | 28.1k | } |
101 | | |
102 | | const std::vector<AppStatusPB::ErrorCode> kStatusToErrorCode = CreateStatusToErrorCode(); |
103 | | |
104 | 28.1k | std::vector<Status::Code> CreateErrorCodeToStatus() { |
105 | 28.1k | size_t max_index = 0; |
106 | 901k | for (const auto error_code : kStatusToErrorCode) { |
107 | 901k | if (error_code == AppStatusPB::UNKNOWN_ERROR) { |
108 | 28.1k | continue; |
109 | 28.1k | } |
110 | 872k | max_index = std::max(max_index, static_cast<size_t>(error_code)); |
111 | 872k | } |
112 | | |
113 | 28.1k | std::vector<Status::Code> result(max_index + 1); |
114 | 929k | for (size_t int_code = 0; int_code != kStatusToErrorCode.size(); ++int_code901k ) { |
115 | 901k | if (kStatusToErrorCode[int_code] == AppStatusPB::UNKNOWN_ERROR) { |
116 | 28.1k | continue; |
117 | 28.1k | } |
118 | 872k | result[static_cast<size_t>(kStatusToErrorCode[int_code])] = static_cast<Status::Code>(int_code); |
119 | 872k | } |
120 | | |
121 | 28.1k | return result; |
122 | 28.1k | } |
123 | | |
124 | | const std::vector<Status::Code> kErrorCodeToStatus = CreateErrorCodeToStatus(); |
125 | | |
126 | | const HostPortPB& GetHostPort( |
127 | | const google::protobuf::RepeatedPtrField<HostPortPB>& broadcast_addresses, |
128 | | const google::protobuf::RepeatedPtrField<HostPortPB>& private_host_ports, |
129 | 2.17M | PublicAddressAllowed public_address_allowed) { |
130 | 2.17M | if (!broadcast_addresses.empty() && public_address_allowed11.4k ) { |
131 | 10.9k | return broadcast_addresses[0]; |
132 | 10.9k | } |
133 | 2.16M | if (!private_host_ports.empty()) { |
134 | 2.16M | return private_host_ports[0]; |
135 | 2.16M | } |
136 | 100 | static const HostPortPB empty_host_port; |
137 | 100 | return empty_host_port; |
138 | 2.16M | } |
139 | | |
140 | | } // namespace |
141 | | |
142 | 1.86M | void StatusToPB(const Status& status, AppStatusPB* pb) { |
143 | 1.86M | pb->Clear(); |
144 | | |
145 | 1.86M | if (status.ok()) { |
146 | 1 | pb->set_code(AppStatusPB::OK); |
147 | | // OK statuses don't have any message or posix code. |
148 | 1 | return; |
149 | 1 | } |
150 | | |
151 | 1.86M | auto code = static_cast<size_t>(status.code()) < kStatusToErrorCode.size() |
152 | 1.86M | ? kStatusToErrorCode[status.code()]1.85M : AppStatusPB::UNKNOWN_ERROR3.22k ; |
153 | 1.86M | pb->set_code(code); |
154 | 1.86M | if (code == AppStatusPB::UNKNOWN_ERROR) { |
155 | 0 | LOG(WARNING) << "Unknown error code translation connect_from internal error " |
156 | 0 | << status << ": sending UNKNOWN_ERROR"; |
157 | | // For unknown status codes, include the original stringified error |
158 | | // code. |
159 | 0 | pb->set_message(status.CodeAsString() + ": " + status.message().ToBuffer()); |
160 | 1.86M | } else { |
161 | | // Otherwise, just encode the message itself, since the other end |
162 | | // will reconstruct the other parts of the ToString() response. |
163 | 1.86M | pb->set_message(status.message().cdata(), status.message().size()); |
164 | 1.86M | } |
165 | | |
166 | 1.86M | auto error_codes = status.ErrorCodesSlice(); |
167 | 1.86M | pb->set_errors(error_codes.data(), error_codes.size()); |
168 | | // We always has 0 as terminating byte for error codes, so non empty error codes would have |
169 | | // more than one bytes. |
170 | 1.86M | if (error_codes.size() > 1) { |
171 | | // Set old protobuf fields for backward compatibility. |
172 | 531k | Errno err(status); |
173 | 531k | if (err != 0) { |
174 | 18 | pb->set_posix_code(err.value()); |
175 | 18 | } |
176 | 531k | const auto* ql_error_data = status.ErrorData(ql::QLError::kCategory); |
177 | 531k | if (ql_error_data) { |
178 | 0 | pb->set_ql_error_code(static_cast<int64_t>(ql::QLErrorTag::Decode(ql_error_data))); |
179 | 0 | } |
180 | 531k | } |
181 | | |
182 | 1.86M | pb->set_source_file(status.file_name()); |
183 | 1.86M | pb->set_source_line(status.line_number()); |
184 | 1.86M | } |
185 | | |
186 | | struct WireProtocolTabletServerErrorTag { |
187 | | static constexpr uint8_t kCategory = 5; |
188 | | |
189 | | enum Value {}; |
190 | | |
191 | 0 | static size_t EncodedSize(Value value) { |
192 | 0 | return sizeof(Value); |
193 | 0 | } |
194 | | |
195 | 0 | static uint8_t* Encode(Value value, uint8_t* out) { |
196 | 0 | Store<Value, LittleEndian>(out, value); |
197 | 0 | return out + sizeof(Value); |
198 | 0 | } |
199 | | }; |
200 | | |
201 | | // Backward compatibility. |
202 | 0 | Status StatusFromOldPB(const AppStatusPB& pb) { |
203 | 0 | auto code = kErrorCodeToStatus[pb.code()]; |
204 | |
|
205 | 0 | auto status_factory = [code, &pb](const Slice& errors) { |
206 | 0 | return Status( |
207 | 0 | code, pb.source_file().c_str(), pb.source_line(), pb.message(), errors, DupFileName::kTrue); |
208 | 0 | }; |
209 | |
|
210 | 0 | #define ENCODE_ERROR_AND_RETURN_STATUS(Tag, value) \ |
211 | 0 | auto error_code = static_cast<Tag::Value>((value)); \ |
212 | 0 | auto size = 2 + Tag::EncodedSize(error_code); \ |
213 | 0 | uint8_t* buffer = static_cast<uint8_t*>(alloca(size)); \ |
214 | 0 | buffer[0] = Tag::kCategory; \ |
215 | 0 | Tag::Encode(error_code, buffer + 1); \ |
216 | 0 | buffer[size - 1] = 0; \ |
217 | 0 | return status_factory(Slice(buffer, size)); \ |
218 | | /**/ |
219 | |
|
220 | 0 | if (code == Status::kQLError) { |
221 | 0 | if (!pb.has_ql_error_code()) { |
222 | 0 | return STATUS(InternalError, "Query error code missing"); |
223 | 0 | } |
224 | | |
225 | 0 | ENCODE_ERROR_AND_RETURN_STATUS(ql::QLErrorTag, pb.ql_error_code()) |
226 | 0 | } else if (pb.has_posix_code()) { |
227 | 0 | if (code == Status::kIllegalState || code == Status::kLeaderNotReadyToServe || |
228 | 0 | code == Status::kLeaderHasNoLease) { |
229 | |
|
230 | 0 | ENCODE_ERROR_AND_RETURN_STATUS(WireProtocolTabletServerErrorTag, pb.posix_code()) |
231 | 0 | } else { |
232 | 0 | ENCODE_ERROR_AND_RETURN_STATUS(ErrnoTag, pb.posix_code()) |
233 | 0 | } |
234 | 0 | } |
235 | | |
236 | 0 | return Status(code, pb.source_file().c_str(), pb.source_line(), pb.message(), "", |
237 | 0 | nullptr /* error */, DupFileName::kTrue); |
238 | 0 | #undef ENCODE_ERROR_AND_RETURN_STATUS |
239 | 0 | } |
240 | | |
241 | 631k | Status StatusFromPB(const AppStatusPB& pb) { |
242 | 631k | if (pb.code() == AppStatusPB::OK) { |
243 | 1 | return Status::OK(); |
244 | 631k | } else if (pb.code() == AppStatusPB::UNKNOWN_ERROR || |
245 | 631k | static_cast<size_t>(pb.code()) >= kErrorCodeToStatus.size()631k ) { |
246 | 0 | LOG(WARNING) << "Unknown error code in status: " << pb.ShortDebugString(); |
247 | 0 | return STATUS_FORMAT( |
248 | 0 | RuntimeError, "($0 unknown): $1", pb.code(), pb.message()); |
249 | 0 | } |
250 | | |
251 | 631k | if (pb.has_errors()) { |
252 | 630k | return Status(kErrorCodeToStatus[pb.code()], pb.source_file().c_str(), pb.source_line(), |
253 | 630k | pb.message(), pb.errors(), DupFileName::kTrue); |
254 | 630k | } |
255 | | |
256 | 460 | return StatusFromOldPB(pb); |
257 | 631k | } |
258 | | |
259 | 97.2k | void HostPortToPB(const HostPort& host_port, HostPortPB* host_port_pb) { |
260 | 97.2k | host_port_pb->set_host(host_port.host()); |
261 | 97.2k | host_port_pb->set_port(host_port.port()); |
262 | 97.2k | } |
263 | | |
264 | 2.49M | HostPort HostPortFromPB(const HostPortPB& host_port_pb) { |
265 | 2.49M | HostPort host_port; |
266 | 2.49M | host_port.set_host(host_port_pb.host()); |
267 | 2.49M | host_port.set_port(host_port_pb.port()); |
268 | 2.49M | return host_port; |
269 | 2.49M | } |
270 | | |
271 | | bool HasHostPortPB( |
272 | 25 | const google::protobuf::RepeatedPtrField<HostPortPB>& list, const HostPortPB& hp) { |
273 | 25 | for (const auto& i : list) { |
274 | 15 | if (i.host() == hp.host() && i.port() == hp.port()9 ) { |
275 | 5 | return true; |
276 | 5 | } |
277 | 15 | } |
278 | 20 | return false; |
279 | 25 | } |
280 | | |
281 | 0 | Status EndpointFromHostPortPB(const HostPortPB& host_portpb, Endpoint* endpoint) { |
282 | 0 | HostPort host_port = HostPortFromPB(host_portpb); |
283 | 0 | return EndpointFromHostPort(host_port, endpoint); |
284 | 0 | } |
285 | | |
286 | 161k | void HostPortsToPBs(const std::vector<HostPort>& addrs, RepeatedPtrField<HostPortPB>* pbs) { |
287 | 161k | for (const auto& addr : addrs) { |
288 | 97.1k | HostPortToPB(addr, pbs->Add()); |
289 | 97.1k | } |
290 | 161k | } |
291 | | |
292 | 2 | void HostPortsFromPBs(const RepeatedPtrField<HostPortPB>& pbs, std::vector<HostPort>* addrs) { |
293 | 2 | addrs->reserve(pbs.size()); |
294 | 2 | for (const auto& pb : pbs) { |
295 | 2 | addrs->push_back(HostPortFromPB(pb)); |
296 | 2 | } |
297 | 2 | } |
298 | | |
299 | | Status AddHostPortPBs(const std::vector<Endpoint>& addrs, |
300 | 107 | RepeatedPtrField<HostPortPB>* pbs) { |
301 | 108 | for (const auto& addr : addrs) { |
302 | 108 | HostPortPB* pb = pbs->Add(); |
303 | 108 | pb->set_port(addr.port()); |
304 | 108 | if (addr.address().is_unspecified()) { |
305 | 2 | VLOG(4) << " Asked to add unspecified address: " << addr.address()0 ; |
306 | 2 | auto status = GetFQDN(pb->mutable_host()); |
307 | 2 | if (!status.ok()) { |
308 | 0 | std::vector<IpAddress> locals; |
309 | 0 | if (!GetLocalAddresses(FLAGS_net_address_filter, &locals).ok() || |
310 | 0 | locals.empty()) { |
311 | 0 | return status; |
312 | 0 | } |
313 | 0 | for (auto& address : locals) { |
314 | 0 | if (pb == nullptr) { |
315 | 0 | pb = pbs->Add(); |
316 | 0 | pb->set_port(addr.port()); |
317 | 0 | } |
318 | 0 | pb->set_host(address.to_string()); |
319 | 0 | VLOG(4) << "Adding local address: " << pb->host(); |
320 | 0 | pb = nullptr; |
321 | 0 | } |
322 | 2 | } else { |
323 | 2 | VLOG(4) << "Adding FQDN " << pb->host()0 ; |
324 | 2 | } |
325 | 106 | } else { |
326 | 106 | pb->set_host(addr.address().to_string()); |
327 | 106 | VLOG(4) << "Adding specific address: " << pb->host()0 ; |
328 | 106 | } |
329 | 108 | } |
330 | 107 | return Status::OK(); |
331 | 107 | } |
332 | | |
333 | | void SchemaToColocatedTableIdentifierPB( |
334 | 301M | const Schema& schema, ColocatedTableIdentifierPB* colocated_pb) { |
335 | 301M | if (schema.has_colocation_id()) { |
336 | 3.02k | colocated_pb->set_colocation_id(schema.colocation_id()); |
337 | 301M | } else if (schema.has_cotable_id()) { |
338 | 299M | colocated_pb->set_cotable_id(schema.cotable_id().ToString()); |
339 | 299M | } |
340 | | |
341 | 301M | } |
342 | | |
343 | 301M | void SchemaToPB(const Schema& schema, SchemaPB *pb, int flags) { |
344 | 301M | pb->Clear(); |
345 | 301M | SchemaToColocatedTableIdentifierPB(schema, pb->mutable_colocated_table_id()); |
346 | 301M | SchemaToColumnPBs(schema, pb->mutable_columns(), flags); |
347 | 301M | schema.table_properties().ToTablePropertiesPB(pb->mutable_table_properties()); |
348 | 301M | pb->set_pgschema_name(schema.SchemaName()); |
349 | 301M | } |
350 | | |
351 | 0 | void SchemaToPBWithoutIds(const Schema& schema, SchemaPB *pb) { |
352 | 0 | pb->Clear(); |
353 | 0 | SchemaToColumnPBs(schema, pb->mutable_columns(), SCHEMA_PB_WITHOUT_IDS); |
354 | 0 | } |
355 | | |
356 | 5.68M | Status SchemaFromPB(const SchemaPB& pb, Schema *schema) { |
357 | | // Conver the columns. |
358 | 5.68M | vector<ColumnSchema> columns; |
359 | 5.68M | vector<ColumnId> column_ids; |
360 | 5.68M | int num_key_columns = 0; |
361 | 5.68M | RETURN_NOT_OK(ColumnPBsToColumnTuple(pb.columns(), &columns, &column_ids, &num_key_columns)); |
362 | | |
363 | | // Convert the table properties. |
364 | 5.68M | TableProperties table_properties = TableProperties::FromTablePropertiesPB(pb.table_properties()); |
365 | 5.68M | RETURN_NOT_OK(schema->Reset(columns, column_ids, num_key_columns, table_properties)); |
366 | | |
367 | 5.68M | if(pb.has_pgschema_name()) { |
368 | 5.67M | schema->SetSchemaName(pb.pgschema_name()); |
369 | 5.67M | } |
370 | | |
371 | 5.68M | if (pb.has_colocated_table_id()) { |
372 | 5.67M | switch (pb.colocated_table_id().value_case()) { |
373 | 1.22k | case ColocatedTableIdentifierPB::kCotableId: { |
374 | 1.22k | schema->set_cotable_id( |
375 | 1.22k | VERIFY_RESULT(Uuid::FromString(pb.colocated_table_id().cotable_id()))); |
376 | 0 | break; |
377 | 1.22k | } |
378 | 1.46k | case ColocatedTableIdentifierPB::kColocationId: |
379 | 1.46k | schema->set_colocation_id(pb.colocated_table_id().colocation_id()); |
380 | 1.46k | break; |
381 | 5.67M | case ColocatedTableIdentifierPB::VALUE_NOT_SET: |
382 | 5.67M | break; |
383 | 5.67M | } |
384 | 5.67M | } |
385 | 5.69M | return Status::OK(); |
386 | 5.68M | } |
387 | | |
388 | 2.06G | void ColumnSchemaToPB(const ColumnSchema& col_schema, ColumnSchemaPB *pb, int flags) { |
389 | 2.06G | pb->Clear(); |
390 | 2.06G | pb->set_name(col_schema.name()); |
391 | 2.06G | col_schema.type()->ToQLTypePB(pb->mutable_type()); |
392 | 2.06G | pb->set_is_nullable(col_schema.is_nullable()); |
393 | 2.06G | pb->set_is_static(col_schema.is_static()); |
394 | 2.06G | pb->set_is_counter(col_schema.is_counter()); |
395 | 2.06G | pb->set_order(col_schema.order()); |
396 | 2.06G | pb->set_sorting_type(col_schema.sorting_type()); |
397 | 2.06G | pb->set_pg_type_oid(col_schema.pg_type_oid()); |
398 | | // We only need to process the *hash* primary key here. The regular primary key is set by the |
399 | | // conversion for SchemaPB. The reason is that ColumnSchema and ColumnSchemaPB are not matching |
400 | | // 1 to 1 as ColumnSchema doesn't have "is_key" field. That was Kudu's code, and we keep it that |
401 | | // way for now. |
402 | 2.06G | if (col_schema.is_hash_key()) { |
403 | 793k | pb->set_is_key(true); |
404 | 793k | pb->set_is_hash_key(true); |
405 | 793k | } |
406 | 2.06G | } |
407 | | |
408 | | |
409 | 25.5M | ColumnSchema ColumnSchemaFromPB(const ColumnSchemaPB& pb) { |
410 | | // Only "is_hash_key" is used to construct ColumnSchema. The field "is_key" will be read when |
411 | | // processing SchemaPB. |
412 | 25.5M | return ColumnSchema(pb.name(), QLType::FromQLTypePB(pb.type()), pb.is_nullable(), |
413 | 25.5M | pb.is_hash_key(), pb.is_static(), pb.is_counter(), pb.order(), |
414 | 25.5M | SortingType(pb.sorting_type()), pb.pg_type_oid()); |
415 | 25.5M | } |
416 | | |
417 | | CHECKED_STATUS ColumnPBsToColumnTuple( |
418 | | const RepeatedPtrField<ColumnSchemaPB>& column_pbs, |
419 | 5.68M | vector<ColumnSchema>* columns , vector<ColumnId>* column_ids, int* num_key_columns) { |
420 | 5.68M | columns->reserve(column_pbs.size()); |
421 | 5.68M | bool is_handling_key = true; |
422 | 25.5M | for (const ColumnSchemaPB& pb : column_pbs) { |
423 | 25.5M | columns->push_back(ColumnSchemaFromPB(pb)); |
424 | 25.5M | if (pb.is_key()) { |
425 | 9.04M | if (!is_handling_key) { |
426 | 1 | return STATUS(InvalidArgument, |
427 | 1 | "Got out-of-order key column", pb.ShortDebugString()); |
428 | 1 | } |
429 | 9.04M | (*num_key_columns)++; |
430 | 16.4M | } else { |
431 | 16.4M | is_handling_key = false; |
432 | 16.4M | } |
433 | 25.5M | if (pb.has_id()) { |
434 | 25.5M | column_ids->push_back(ColumnId(pb.id())); |
435 | 25.5M | } |
436 | 25.5M | } |
437 | | |
438 | 5.68M | DCHECK_LE((*num_key_columns), columns->size()); |
439 | 5.68M | return Status::OK(); |
440 | 5.68M | } |
441 | | |
442 | | Status ColumnPBsToSchema(const RepeatedPtrField<ColumnSchemaPB>& column_pbs, |
443 | 3 | Schema* schema) { |
444 | | |
445 | 3 | vector<ColumnSchema> columns; |
446 | 3 | vector<ColumnId> column_ids; |
447 | 3 | int num_key_columns = 0; |
448 | 3 | RETURN_NOT_OK(ColumnPBsToColumnTuple(column_pbs, &columns, &column_ids, &num_key_columns)); |
449 | | |
450 | | // TODO(perf): could make the following faster by adding a |
451 | | // Reset() variant which actually takes ownership of the column |
452 | | // vector. |
453 | 2 | return schema->Reset(columns, column_ids, num_key_columns); |
454 | 3 | } |
455 | | |
456 | | void SchemaToColumnPBs(const Schema& schema, |
457 | | RepeatedPtrField<ColumnSchemaPB>* cols, |
458 | 301M | int flags) { |
459 | 301M | cols->Clear(); |
460 | 301M | size_t idx = 0; |
461 | 2.06G | for (const ColumnSchema& col : schema.columns()) { |
462 | 2.06G | ColumnSchemaPB* col_pb = cols->Add(); |
463 | 2.06G | ColumnSchemaToPB(col, col_pb); |
464 | 2.06G | col_pb->set_is_key(idx < schema.num_key_columns()); |
465 | | |
466 | 2.06G | if (schema.has_column_ids() && !(flags & SCHEMA_PB_WITHOUT_IDS)2.06G ) { |
467 | 2.06G | col_pb->set_id(schema.column_id(idx)); |
468 | 2.06G | } |
469 | | |
470 | 2.06G | idx++; |
471 | 2.06G | } |
472 | 301M | } |
473 | | |
474 | 2.18M | Result<UsePrivateIpMode> GetPrivateIpMode() { |
475 | 8.70M | for (auto i : kUsePrivateIpModeList) { |
476 | 8.70M | if (FLAGS_use_private_ip == ToCString(i)) { |
477 | 2.18M | return i; |
478 | 2.18M | } |
479 | 8.70M | } |
480 | 18.4E | return STATUS_FORMAT( |
481 | 2.18M | IllegalState, |
482 | 2.18M | "Invalid value of FLAGS_use_private_ip: $0, using private ip everywhere", |
483 | 2.18M | FLAGS_use_private_ip); |
484 | 2.18M | } |
485 | | |
486 | 2.16M | UsePrivateIpMode GetMode() { |
487 | 2.16M | auto result = GetPrivateIpMode(); |
488 | 2.16M | if (result.ok()) { |
489 | 2.16M | return *result; |
490 | 2.16M | } |
491 | 388 | YB_LOG_EVERY_N_SECS(WARNING, 300) << result.status()0 ; |
492 | 388 | return UsePrivateIpMode::never; |
493 | 2.16M | } |
494 | | |
495 | 2.16M | PublicAddressAllowed UsePublicIp(const CloudInfoPB& connect_to, const CloudInfoPB& connect_from) { |
496 | 2.16M | auto mode = GetMode(); |
497 | | |
498 | 2.16M | if (mode == UsePrivateIpMode::never) { |
499 | 2.15M | return PublicAddressAllowed::kTrue; |
500 | 2.15M | } |
501 | 9.50k | if (connect_to.placement_cloud() != connect_from.placement_cloud()) { |
502 | 8.16k | return PublicAddressAllowed::kTrue; |
503 | 8.16k | } |
504 | 1.34k | if (mode == UsePrivateIpMode::cloud) { |
505 | 485 | return PublicAddressAllowed::kFalse; |
506 | 485 | } |
507 | 864 | if (connect_to.placement_region() != connect_from.placement_region()) { |
508 | 0 | return PublicAddressAllowed::kTrue; |
509 | 0 | } |
510 | 864 | if (mode == UsePrivateIpMode::region) { |
511 | 0 | return PublicAddressAllowed::kFalse; |
512 | 0 | } |
513 | 864 | if (connect_to.placement_zone() != connect_from.placement_zone()) { |
514 | 0 | return PublicAddressAllowed::kTrue; |
515 | 0 | } |
516 | 864 | return mode == UsePrivateIpMode::zone |
517 | 864 | ? PublicAddressAllowed::kFalse0 |
518 | 864 | : PublicAddressAllowed::kTrue; |
519 | 864 | } |
520 | | |
521 | 8.74k | const HostPortPB& PublicHostPort(const ServerRegistrationPB& registration) { |
522 | 8.74k | return GetHostPort(registration.broadcast_addresses(), |
523 | 8.74k | registration.private_rpc_addresses(), |
524 | 8.74k | PublicAddressAllowed::kTrue); |
525 | 8.74k | } |
526 | | |
527 | | const HostPortPB& DesiredHostPort( |
528 | | const google::protobuf::RepeatedPtrField<HostPortPB>& broadcast_addresses, |
529 | | const google::protobuf::RepeatedPtrField<HostPortPB>& private_host_ports, |
530 | | const CloudInfoPB& connect_to, |
531 | 2.16M | const CloudInfoPB& connect_from) { |
532 | 2.16M | return GetHostPort(broadcast_addresses, |
533 | 2.16M | private_host_ports, |
534 | 2.16M | UsePublicIp(connect_to, connect_from)); |
535 | 2.16M | } |
536 | | |
537 | | const HostPortPB& DesiredHostPort(const ServerRegistrationPB& registration, |
538 | 171k | const CloudInfoPB& connect_from) { |
539 | 171k | return DesiredHostPort( |
540 | 171k | registration.broadcast_addresses(), registration.private_rpc_addresses(), |
541 | 171k | registration.cloud_info(), connect_from); |
542 | 171k | } |
543 | | |
544 | | static const std::string kSplitChildTabletIdsCategoryName = "split child tablet IDs"; |
545 | | |
546 | | StatusCategoryRegisterer split_child_tablet_ids_category_registerer( |
547 | | StatusCategoryDescription::Make<SplitChildTabletIdsTag>(&kSplitChildTabletIdsCategoryName)); |
548 | | |
549 | 0 | std::string SplitChildTabletIdsTag::ToMessage(Value value) { |
550 | 0 | return Format("Split child tablet IDs: $0", value); |
551 | 0 | } |
552 | | |
553 | | } // namespace yb |