/Users/deen/code/yugabyte-db/src/yb/client/schema.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 | | |
33 | | #include "yb/client/schema.h" |
34 | | |
35 | | #include <unordered_map> |
36 | | |
37 | | #include <glog/logging.h> |
38 | | |
39 | | #include "yb/client/schema-internal.h" |
40 | | |
41 | | #include "yb/common/partial_row.h" |
42 | | #include "yb/common/ql_type.h" |
43 | | #include "yb/common/schema.h" |
44 | | #include "yb/common/wire_protocol.h" |
45 | | |
46 | | #include "yb/gutil/map-util.h" |
47 | | #include "yb/gutil/strings/substitute.h" |
48 | | |
49 | | #include "yb/util/result.h" |
50 | | #include "yb/util/status_format.h" |
51 | | |
52 | | using std::shared_ptr; |
53 | | using std::unordered_map; |
54 | | using std::vector; |
55 | | using strings::Substitute; |
56 | | |
57 | | namespace yb { |
58 | | namespace client { |
59 | | //////////////////////////////////////////////////////////// |
60 | | // YBColumnSpec |
61 | | //////////////////////////////////////////////////////////// |
62 | | |
63 | | YBColumnSpec::YBColumnSpec(const std::string& name) |
64 | 23.4k | : data_(new Data(name)) { |
65 | 23.4k | } |
66 | | |
67 | 23.4k | YBColumnSpec::~YBColumnSpec() { |
68 | 23.4k | delete data_; |
69 | 23.4k | } |
70 | | |
71 | 23.2k | YBColumnSpec* YBColumnSpec::Type(const std::shared_ptr<QLType>& type) { |
72 | 23.2k | data_->has_type = true; |
73 | 23.2k | data_->type = type; |
74 | 23.2k | return this; |
75 | 23.2k | } |
76 | | |
77 | 21.6k | YBColumnSpec* YBColumnSpec::Order(int32_t order) { |
78 | 21.6k | data_->has_order = true; |
79 | 21.6k | data_->order = order; |
80 | 21.6k | return this; |
81 | 21.6k | } |
82 | | |
83 | 15.8k | YBColumnSpec* YBColumnSpec::SetSortingType(SortingType sorting_type) { |
84 | 15.8k | data_->sorting_type = sorting_type; |
85 | 15.8k | return this; |
86 | 15.8k | } |
87 | | |
88 | 11.1k | YBColumnSpec* YBColumnSpec::PrimaryKey() { |
89 | 11.1k | NotNull(); |
90 | 11.1k | data_->primary_key = true; |
91 | 11.1k | return this; |
92 | 11.1k | } |
93 | | |
94 | 6.83k | YBColumnSpec* YBColumnSpec::HashPrimaryKey() { |
95 | 6.83k | PrimaryKey(); |
96 | 6.83k | data_->hash_primary_key = true; |
97 | 6.83k | return this; |
98 | 6.83k | } |
99 | | |
100 | 43 | YBColumnSpec* YBColumnSpec::StaticColumn() { |
101 | 43 | data_->static_column = true; |
102 | 43 | return this; |
103 | 43 | } |
104 | | |
105 | 12.0k | YBColumnSpec* YBColumnSpec::NotNull() { |
106 | 12.0k | data_->has_nullable = true; |
107 | 12.0k | data_->nullable = false; |
108 | 12.0k | return this; |
109 | 12.0k | } |
110 | | |
111 | 2.40k | YBColumnSpec* YBColumnSpec::Nullable() { |
112 | 2.40k | data_->has_nullable = true; |
113 | 2.40k | data_->nullable = true; |
114 | 2.40k | return this; |
115 | 2.40k | } |
116 | | |
117 | 16 | YBColumnSpec* YBColumnSpec::Counter() { |
118 | 16 | data_->is_counter = true; |
119 | 16 | return this; |
120 | 16 | } |
121 | | |
122 | 14.1k | YBColumnSpec* YBColumnSpec::PgTypeOid(int32_t oid) { |
123 | 14.1k | data_->has_pg_type_oid = true; |
124 | 14.1k | data_->pg_type_oid = oid; |
125 | 14.1k | return this; |
126 | 14.1k | } |
127 | | |
128 | 29 | YBColumnSpec* YBColumnSpec::RenameTo(const std::string& new_name) { |
129 | 29 | data_->has_rename_to = true; |
130 | 29 | data_->rename_to = new_name; |
131 | 29 | return this; |
132 | 29 | } |
133 | | |
134 | 23.2k | Status YBColumnSpec::ToColumnSchema(YBColumnSchema* col) const { |
135 | | // Verify that the user isn't trying to use any methods that |
136 | | // don't make sense for CREATE. |
137 | 23.2k | if (data_->has_rename_to) { |
138 | | // TODO(KUDU-861): adjust these errors as this method will also be used for |
139 | | // ALTER TABLE ADD COLUMN support. |
140 | 0 | return STATUS(NotSupported, "cannot rename a column during CreateTable", |
141 | 0 | data_->name); |
142 | 0 | } |
143 | | |
144 | 23.2k | if (!data_->has_type) { |
145 | 0 | return STATUS(InvalidArgument, "no type provided for column", data_->name); |
146 | 0 | } |
147 | | |
148 | 23.2k | bool nullable = data_->has_nullable ? data_->nullable13.9k : true9.28k ; |
149 | | |
150 | 23.2k | *col = YBColumnSchema(data_->name, data_->type, nullable, data_->hash_primary_key, |
151 | 23.2k | data_->static_column, data_->is_counter, data_->order, |
152 | 23.2k | data_->sorting_type, data_->pg_type_oid); |
153 | | |
154 | 23.2k | return Status::OK(); |
155 | 23.2k | } |
156 | | |
157 | 1.49k | YBColumnSpec* YBColumnSpec::Type(DataType type) { |
158 | 1.49k | return Type(QLType::Create(type)); |
159 | 1.49k | } |
160 | | |
161 | | //////////////////////////////////////////////////////////// |
162 | | // YBSchemaBuilder |
163 | | //////////////////////////////////////////////////////////// |
164 | | |
165 | | class YBSchemaBuilder::Data { |
166 | | public: |
167 | 7.19k | ~Data() { |
168 | | // Rather than delete the specs here, we have to do it in |
169 | | // ~YBSchemaBuilder(), to avoid a circular dependency in the |
170 | | // headers declaring friend classes with nested classes. |
171 | 7.19k | } |
172 | | |
173 | | // These members can be used to specify a subset of columns are primary or hash primary keys. |
174 | | // NOTE: "key_col_names" and "key_hash_col_count" are not used unless "has_key_col_names" is true. |
175 | | bool has_key_col_names = false; |
176 | | vector<string> key_col_names; |
177 | | size_t key_hash_col_count = 0; |
178 | | |
179 | | vector<YBColumnSpec*> specs; |
180 | | TableProperties table_properties; |
181 | | std::string schema_name; |
182 | | }; |
183 | | |
184 | | YBSchemaBuilder::YBSchemaBuilder() |
185 | 7.19k | : data_(new Data()) { |
186 | 7.19k | } |
187 | | |
188 | 7.19k | YBSchemaBuilder::~YBSchemaBuilder() { |
189 | 22.8k | for (YBColumnSpec* spec : data_->specs) { |
190 | | // Can't use STLDeleteElements because YBSchemaBuilder |
191 | | // is a friend of YBColumnSpec in order to access its destructor. |
192 | | // STLDeleteElements is a free function and therefore can't access it. |
193 | 22.8k | delete spec; |
194 | 22.8k | } |
195 | 7.19k | delete data_; |
196 | 7.19k | } |
197 | | |
198 | 22.8k | YBColumnSpec* YBSchemaBuilder::AddColumn(const std::string& name) { |
199 | 22.8k | auto c = new YBColumnSpec(name); |
200 | 22.8k | data_->specs.push_back(c); |
201 | 22.8k | return c; |
202 | 22.8k | } |
203 | | |
204 | | YBSchemaBuilder* YBSchemaBuilder::SetPrimaryKey( |
205 | | const std::vector<std::string>& key_col_names, |
206 | 4 | size_t key_hash_col_count) { |
207 | 4 | data_->has_key_col_names = true; |
208 | 4 | data_->key_col_names = key_col_names; |
209 | 4 | data_->key_hash_col_count = key_hash_col_count; |
210 | 4 | return this; |
211 | 4 | } |
212 | | |
213 | 6.73k | YBSchemaBuilder* YBSchemaBuilder::SetTableProperties(const TableProperties& table_properties) { |
214 | 6.73k | data_->table_properties = table_properties; |
215 | 6.73k | return this; |
216 | 6.73k | } |
217 | | |
218 | 5.05k | YBSchemaBuilder* YBSchemaBuilder::SetSchemaName(const std::string& pgschema_name) { |
219 | 5.05k | data_->schema_name = pgschema_name; |
220 | 5.05k | return this; |
221 | 5.05k | } |
222 | | |
223 | 0 | std::string YBSchemaBuilder::SchemaName() { |
224 | 0 | return data_->schema_name; |
225 | 0 | } |
226 | | |
227 | 7.19k | Status YBSchemaBuilder::Build(YBSchema* schema) { |
228 | 7.19k | std::vector<YBColumnSchema> cols(data_->specs.size(), YBColumnSchema()); |
229 | 30.0k | for (size_t i = 0; i < cols.size(); i++22.8k ) { |
230 | 22.8k | RETURN_NOT_OK(data_->specs[i]->ToColumnSchema(&cols[i])); |
231 | 22.8k | } |
232 | | |
233 | 7.19k | size_t num_key_cols = 0; |
234 | 7.19k | if (!data_->has_key_col_names) { |
235 | | // Change the API to allow specifying each column individually as part of a primary key. |
236 | | // Previously, we must pass an extra list of columns if the key is a compound of columns. |
237 | | // |
238 | | // Removing the following restriction from Kudu: |
239 | | // If they didn't explicitly pass the column names for key, |
240 | | // then they should have set it on exactly one column. |
241 | 7.19k | const YBColumnSpec::Data* reached_primary_column = nullptr; |
242 | 7.19k | const YBColumnSpec::Data* reached_regular_column = nullptr; |
243 | 30.0k | for (size_t i = 0; i < cols.size(); i++22.8k ) { |
244 | 22.8k | auto& column_data = *data_->specs[i]->data_; |
245 | 22.8k | if (column_data.hash_primary_key) { |
246 | 6.83k | num_key_cols++; |
247 | 6.83k | if (reached_primary_column) { |
248 | 1 | return STATUS_FORMAT( |
249 | 1 | InvalidArgument, "Hash primary key column '$0' should be before primary key '$1'", |
250 | 1 | column_data.name, reached_primary_column->name); |
251 | 1 | } |
252 | 6.83k | if (reached_regular_column) { |
253 | 0 | return STATUS_FORMAT( |
254 | 0 | InvalidArgument, "Hash primary key column '$0' should be before regular column '$1'", |
255 | 0 | column_data.name, reached_regular_column->name); |
256 | 0 | } |
257 | | |
258 | 16.0k | } else if (column_data.primary_key) { |
259 | 4.28k | num_key_cols++; |
260 | 4.28k | if (reached_regular_column) { |
261 | 1 | return STATUS_FORMAT( |
262 | 1 | InvalidArgument, "Primary key column '$0' should be before regular column '$1'", |
263 | 1 | column_data.name, reached_regular_column->name); |
264 | 1 | } |
265 | | |
266 | 4.28k | reached_primary_column = &column_data; |
267 | 11.7k | } else { |
268 | 11.7k | reached_regular_column = &column_data; |
269 | 11.7k | } |
270 | 22.8k | } |
271 | | |
272 | 7.18k | if (num_key_cols <= 0) { |
273 | 2 | return STATUS(InvalidArgument, "No primary key specified"); |
274 | 2 | } |
275 | 7.18k | } else { |
276 | | // Build a map from name to index of all of the columns. |
277 | 4 | unordered_map<string, size_t> name_to_idx_map; |
278 | 4 | size_t i = 0; |
279 | 8 | for (YBColumnSpec* spec : data_->specs) { |
280 | | // If they did pass the key column names, then we should not have explicitly |
281 | | // set it on any columns. |
282 | 8 | if (spec->data_->primary_key) { |
283 | 1 | return STATUS(InvalidArgument, "Primary key specified by both SetPrimaryKey() and on a " |
284 | 1 | "specific column", spec->data_->name); |
285 | 1 | } |
286 | | |
287 | | // Set the primary keys here to make sure the two different APIs for ColumnSpecs yield the |
288 | | // same result. |
289 | 7 | if (i < data_->key_hash_col_count) { |
290 | 0 | spec->HashPrimaryKey(); |
291 | 7 | } else { |
292 | 7 | spec->PrimaryKey(); |
293 | 7 | } |
294 | | |
295 | | // If we have a duplicate column name, the Schema::Reset() will catch it later, |
296 | | // anyway. |
297 | 7 | name_to_idx_map[spec->data_->name] = i++; |
298 | 7 | } |
299 | | |
300 | | // Convert the key column names to a set of indexes. |
301 | 3 | vector<size_t> key_col_indexes; |
302 | 5 | for (const string& key_col_name : data_->key_col_names) { |
303 | 5 | size_t idx; |
304 | 5 | if (!FindCopy(name_to_idx_map, key_col_name, &idx)) { |
305 | 1 | return STATUS(InvalidArgument, "Primary key column not defined", key_col_name); |
306 | 1 | } |
307 | 4 | key_col_indexes.push_back(idx); |
308 | 4 | } |
309 | | |
310 | | // Currently we require that the key columns be contiguous at the front |
311 | | // of the schema. We'll lift this restriction later -- hence the more |
312 | | // flexible user-facing API. |
313 | 4 | for (size_t i = 0; 2 i < key_col_indexes.size(); i++2 ) { |
314 | 3 | if (key_col_indexes[i] != i) { |
315 | 1 | return STATUS(InvalidArgument, "Primary key columns must be listed first in the schema", |
316 | 1 | data_->key_col_names[i]); |
317 | 1 | } |
318 | 3 | } |
319 | | |
320 | | // Indicate the first "num_key_cols" are primary key. |
321 | 1 | num_key_cols = key_col_indexes.size(); |
322 | 1 | } |
323 | | |
324 | 7.18k | RETURN_NOT_OK(schema->Reset(cols, num_key_cols, data_->table_properties)); |
325 | 7.18k | internal::GetSchema(schema).SetSchemaName(data_->schema_name); |
326 | | |
327 | 7.18k | return Status::OK(); |
328 | 7.18k | } |
329 | | |
330 | | //////////////////////////////////////////////////////////// |
331 | | // YBColumnSchema |
332 | | //////////////////////////////////////////////////////////// |
333 | | |
334 | 0 | std::string YBColumnSchema::DataTypeToString(DataType type) { |
335 | 0 | return DataType_Name(type); |
336 | 0 | } |
337 | | |
338 | | YBColumnSchema::YBColumnSchema(const std::string &name, |
339 | | const shared_ptr<QLType>& type, |
340 | | bool is_nullable, |
341 | | bool is_hash_key, |
342 | | bool is_static, |
343 | | bool is_counter, |
344 | | int32_t order, |
345 | | SortingType sorting_type, |
346 | 3.46M | int32_t pg_type_oid) { |
347 | 3.46M | col_ = std::make_unique<ColumnSchema>(name, type, is_nullable, is_hash_key, is_static, is_counter, |
348 | 3.46M | order, sorting_type, pg_type_oid); |
349 | 3.46M | } |
350 | | |
351 | 22.8k | YBColumnSchema::YBColumnSchema(const YBColumnSchema& other) { |
352 | 22.8k | CopyFrom(other); |
353 | 22.8k | } |
354 | | |
355 | 7.53k | YBColumnSchema::YBColumnSchema() = default; |
356 | | |
357 | 3.50M | YBColumnSchema::~YBColumnSchema() = default; |
358 | | |
359 | 23.2k | YBColumnSchema& YBColumnSchema::operator=(const YBColumnSchema& other) { |
360 | 23.2k | if (&other != this) { |
361 | 23.2k | CopyFrom(other); |
362 | 23.2k | } |
363 | 23.2k | return *this; |
364 | 23.2k | } |
365 | | |
366 | 46.1k | void YBColumnSchema::CopyFrom(const YBColumnSchema& other) { |
367 | 46.1k | col_.reset(); |
368 | 46.1k | if (other.col_) { |
369 | 23.2k | col_ = std::make_unique<ColumnSchema>(*other.col_); |
370 | 23.2k | } |
371 | 46.1k | } |
372 | | |
373 | 0 | bool YBColumnSchema::Equals(const YBColumnSchema& other) const { |
374 | 0 | return this == &other || col_ == other.col_ || (col_ != nullptr && col_->Equals(*other.col_)); |
375 | 0 | } |
376 | | |
377 | 6.82M | const std::string& YBColumnSchema::name() const { |
378 | 6.82M | return DCHECK_NOTNULL(col_)->name(); |
379 | 6.82M | } |
380 | | |
381 | 0 | bool YBColumnSchema::is_nullable() const { |
382 | 0 | return DCHECK_NOTNULL(col_)->is_nullable(); |
383 | 0 | } |
384 | | |
385 | 0 | bool YBColumnSchema::is_hash_key() const { |
386 | 0 | return DCHECK_NOTNULL(col_)->is_hash_key(); |
387 | 0 | } |
388 | | |
389 | 3.37M | bool YBColumnSchema::is_static() const { |
390 | 3.37M | return DCHECK_NOTNULL(col_)->is_static(); |
391 | 3.37M | } |
392 | | |
393 | 6.73M | const shared_ptr<QLType>& YBColumnSchema::type() const { |
394 | 6.73M | return DCHECK_NOTNULL(col_)->type(); |
395 | 6.73M | } |
396 | | |
397 | 568 | SortingType YBColumnSchema::sorting_type() const { |
398 | 568 | return DCHECK_NOTNULL(col_)->sorting_type(); |
399 | 568 | } |
400 | | |
401 | 3.37M | bool YBColumnSchema::is_counter() const { |
402 | 3.37M | return DCHECK_NOTNULL(col_)->is_counter(); |
403 | 3.37M | } |
404 | | |
405 | 0 | int32_t YBColumnSchema::order() const { |
406 | 0 | return DCHECK_NOTNULL(col_)->order(); |
407 | 0 | } |
408 | | |
409 | 0 | int32_t YBColumnSchema::pg_type_oid() const { |
410 | 0 | return DCHECK_NOTNULL(col_)->pg_type_oid(); |
411 | 0 | } |
412 | | |
413 | 114M | InternalType YBColumnSchema::ToInternalDataType(const std::shared_ptr<QLType>& ql_type) { |
414 | 114M | switch (ql_type->main()) { |
415 | 1.20M | case INT8: |
416 | 1.20M | return InternalType::kInt8Value; |
417 | 726k | case INT16: |
418 | 726k | return InternalType::kInt16Value; |
419 | 50.9M | case INT32: |
420 | 50.9M | return InternalType::kInt32Value; |
421 | 1.20M | case INT64: |
422 | 1.20M | return InternalType::kInt64Value; |
423 | 10.1M | case UINT32: |
424 | 10.1M | return InternalType::kUint32Value; |
425 | 95 | case UINT64: |
426 | 95 | return InternalType::kUint64Value; |
427 | 100k | case FLOAT: |
428 | 100k | return InternalType::kFloatValue; |
429 | 1.24M | case DOUBLE: |
430 | 1.24M | return InternalType::kDoubleValue; |
431 | 15.4k | case DECIMAL: |
432 | 15.4k | return InternalType::kDecimalValue; |
433 | 22.2M | case STRING: |
434 | 22.2M | return InternalType::kStringValue; |
435 | 3.14k | case TIMESTAMP: |
436 | 3.14k | return InternalType::kTimestampValue; |
437 | 254 | case DATE: |
438 | 254 | return InternalType::kDateValue; |
439 | 214 | case TIME: |
440 | 214 | return InternalType::kTimeValue; |
441 | 356k | case INET: |
442 | 356k | return InternalType::kInetaddressValue; |
443 | 10.7k | case JSONB: |
444 | 10.7k | return InternalType::kJsonbValue; |
445 | 327k | case UUID: |
446 | 327k | return InternalType::kUuidValue; |
447 | 416 | case TIMEUUID: |
448 | 416 | return InternalType::kTimeuuidValue; |
449 | 1.93M | case BOOL: |
450 | 1.93M | return InternalType::kBoolValue; |
451 | 23.6M | case BINARY: |
452 | 23.6M | return InternalType::kBinaryValue; |
453 | 365 | case USER_DEFINED_TYPE: FALLTHROUGH_INTENDED; |
454 | 276k | case MAP: |
455 | 276k | return InternalType::kMapValue; |
456 | 135k | case SET: |
457 | 135k | return InternalType::kSetValue; |
458 | 70.7k | case LIST: |
459 | 70.7k | return InternalType::kListValue; |
460 | 2.66k | case VARINT: |
461 | 2.66k | return InternalType::kVarintValue; |
462 | 643 | case FROZEN: |
463 | 643 | return InternalType::kFrozenValue; |
464 | 1.38k | case GIN_NULL: |
465 | 1.38k | return InternalType::kGinNullValue; |
466 | | |
467 | 390 | case TUPLE: FALLTHROUGH_INTENDED; // TODO (mihnea) Tuple type not fully supported yet |
468 | 448 | case NULL_VALUE_TYPE: FALLTHROUGH_INTENDED; |
469 | 448 | case UNKNOWN_DATA: |
470 | 448 | return InternalType::VALUE_NOT_SET; |
471 | | |
472 | 0 | case TYPEARGS: FALLTHROUGH_INTENDED; |
473 | 0 | case UINT8: FALLTHROUGH_INTENDED; |
474 | 0 | case UINT16: |
475 | 0 | break; |
476 | 114M | } |
477 | 0 | LOG(FATAL) << "Internal error: unsupported type " << ql_type->ToString(); |
478 | 0 | return InternalType::VALUE_NOT_SET; |
479 | 114M | } |
480 | | |
481 | | //////////////////////////////////////////////////////////// |
482 | | // YBSchema |
483 | | //////////////////////////////////////////////////////////// |
484 | | |
485 | | namespace internal { |
486 | | |
487 | 3.19M | const Schema& GetSchema(const YBSchema& schema) { |
488 | 3.19M | return *schema.schema_; |
489 | 3.19M | } |
490 | | |
491 | 147k | Schema& GetSchema(YBSchema* schema) { |
492 | 147k | return *schema->schema_; |
493 | 147k | } |
494 | | |
495 | | } // namespace internal |
496 | | |
497 | 150k | YBSchema::YBSchema() {} |
498 | | |
499 | 135k | YBSchema::YBSchema(const YBSchema& other) { |
500 | 135k | CopyFrom(other); |
501 | 135k | } |
502 | | |
503 | 68 | YBSchema::YBSchema(YBSchema&& other) { |
504 | 68 | MoveFrom(std::move(other)); |
505 | 68 | } |
506 | | |
507 | | YBSchema::YBSchema(const Schema& schema) |
508 | 124 | : schema_(new Schema(schema)) { |
509 | 124 | } |
510 | | |
511 | 202k | YBSchema::~YBSchema() { |
512 | 202k | } |
513 | | |
514 | 0 | YBSchema& YBSchema::operator=(const YBSchema& other) { |
515 | 0 | if (&other != this) { |
516 | 0 | CopyFrom(other); |
517 | 0 | } |
518 | 0 | return *this; |
519 | 0 | } |
520 | | |
521 | 12 | YBSchema& YBSchema::operator=(YBSchema&& other) { |
522 | 12 | if (&other != this) { |
523 | 12 | MoveFrom(std::move(other)); |
524 | 12 | } |
525 | 12 | return *this; |
526 | 12 | } |
527 | | |
528 | 135k | void YBSchema::CopyFrom(const YBSchema& other) { |
529 | 135k | schema_.reset(new Schema(*other.schema_)); |
530 | 135k | version_ = other.version(); |
531 | 135k | is_compatible_with_previous_version_ = other.is_compatible_with_previous_version(); |
532 | 135k | } |
533 | | |
534 | 80 | void YBSchema::MoveFrom(YBSchema&& other) { |
535 | 80 | schema_ = std::move(other.schema_); |
536 | 80 | version_ = other.version(); |
537 | 80 | is_compatible_with_previous_version_ = other.is_compatible_with_previous_version(); |
538 | 80 | } |
539 | | |
540 | 140k | void YBSchema::Reset(std::unique_ptr<Schema> schema) { |
541 | 140k | schema_ = std::move(schema); |
542 | 140k | } |
543 | | |
544 | | Status YBSchema::Reset(const vector<YBColumnSchema>& columns, size_t key_columns, |
545 | 7.18k | const TableProperties& table_properties) { |
546 | 7.18k | vector<ColumnSchema> cols_private; |
547 | 22.8k | for (const YBColumnSchema& col : columns) { |
548 | 22.8k | cols_private.push_back(*col.col_); |
549 | 22.8k | } |
550 | 7.18k | std::unique_ptr<Schema> new_schema(new Schema()); |
551 | 7.18k | RETURN_NOT_OK(new_schema->Reset(cols_private, key_columns, table_properties)); |
552 | | |
553 | 7.18k | schema_ = std::move(new_schema); |
554 | 7.18k | return Status::OK(); |
555 | 7.18k | } |
556 | | |
557 | 0 | bool YBSchema::Equals(const YBSchema& other) const { |
558 | 0 | return this == &other || |
559 | 0 | (schema_.get() && other.schema_.get() && schema_->Equals(*other.schema_)); |
560 | 0 | } |
561 | | |
562 | 0 | bool YBSchema::EquivalentForDataCopy(const YBSchema& other) const { |
563 | 0 | return this == &other || |
564 | 0 | (schema_.get() && other.schema_.get() && schema_->EquivalentForDataCopy(*other.schema_)); |
565 | 0 | } |
566 | | |
567 | 0 | Result<bool> YBSchema::Equals(const SchemaPB& other) const { |
568 | 0 | Schema schema; |
569 | 0 | RETURN_NOT_OK(SchemaFromPB(other, &schema)); |
570 | | |
571 | 0 | YBSchema yb_schema(schema); |
572 | 0 | return Equals(yb_schema); |
573 | 0 | } |
574 | | |
575 | 0 | Result<bool> YBSchema::EquivalentForDataCopy(const SchemaPB& other) const { |
576 | 0 | Schema schema; |
577 | 0 | RETURN_NOT_OK(SchemaFromPB(other, &schema)); |
578 | | |
579 | 0 | YBSchema yb_schema(schema); |
580 | 0 | return EquivalentForDataCopy(yb_schema); |
581 | 0 | } |
582 | | |
583 | 3.24M | const TableProperties& YBSchema::table_properties() const { |
584 | 3.24M | return schema_->table_properties(); |
585 | 3.24M | } |
586 | | |
587 | 3.45M | YBColumnSchema YBSchema::Column(size_t idx) const { |
588 | 3.45M | ColumnSchema col(schema_->column(idx)); |
589 | 3.45M | return YBColumnSchema(col.name(), col.type(), col.is_nullable(), col.is_hash_key(), |
590 | 3.45M | col.is_static(), col.is_counter(), col.order(), col.sorting_type()); |
591 | 3.45M | } |
592 | | |
593 | 0 | YBColumnSchema YBSchema::ColumnById(int32_t column_id) const { |
594 | 0 | return Column(schema_->find_column_by_id(yb::ColumnId(column_id))); |
595 | 0 | } |
596 | | |
597 | 3.89M | int32_t YBSchema::ColumnId(size_t idx) const { |
598 | 3.89M | return schema_->column_id(idx); |
599 | 3.89M | } |
600 | | |
601 | 0 | std::unique_ptr<YBPartialRow> YBSchema::NewRow() const { |
602 | 0 | return std::make_unique<YBPartialRow>(schema_.get()); |
603 | 0 | } |
604 | | |
605 | 3.45M | const std::vector<ColumnSchema>& YBSchema::columns() const { |
606 | 3.45M | return schema_->columns(); |
607 | 3.45M | } |
608 | | |
609 | 4.19M | size_t YBSchema::num_columns() const { |
610 | 4.19M | return schema_->num_columns(); |
611 | 4.19M | } |
612 | | |
613 | 4.99M | size_t YBSchema::num_key_columns() const { |
614 | 4.99M | return schema_->num_key_columns(); |
615 | 4.99M | } |
616 | | |
617 | 4.47M | size_t YBSchema::num_hash_key_columns() const { |
618 | 4.47M | return schema_->num_hash_key_columns(); |
619 | 4.47M | } |
620 | | |
621 | 219 | size_t YBSchema::num_range_key_columns() const { |
622 | 219 | return schema_->num_range_key_columns(); |
623 | 219 | } |
624 | | |
625 | 0 | bool YBSchema::has_colocation_id() const { |
626 | 0 | return schema_->has_colocation_id(); |
627 | 0 | } |
628 | | |
629 | 0 | ColocationId YBSchema::colocation_id() const { |
630 | 0 | return schema_->colocation_id(); |
631 | 0 | } |
632 | | |
633 | 11.5M | bool YBSchema::is_compatible_with_previous_version() const { |
634 | 11.5M | return is_compatible_with_previous_version_; |
635 | 11.5M | } |
636 | | |
637 | 140k | void YBSchema::set_is_compatible_with_previous_version(bool is_compatible) { |
638 | 140k | is_compatible_with_previous_version_ = is_compatible; |
639 | 140k | } |
640 | | |
641 | 11.5M | uint32_t YBSchema::version() const { |
642 | 11.5M | return version_; |
643 | 11.5M | } |
644 | | |
645 | 140k | void YBSchema::set_version(uint32_t version) { |
646 | 140k | version_ = version; |
647 | 140k | } |
648 | | |
649 | 1 | std::vector<size_t> YBSchema::GetPrimaryKeyColumnIndexes() const { |
650 | 1 | std::vector<size_t> result(num_key_columns()); |
651 | 3 | for (size_t i = 0; i < num_key_columns(); i++2 ) { |
652 | 2 | result[i] = i; |
653 | 2 | } |
654 | 1 | return result; |
655 | 1 | } |
656 | | |
657 | 0 | string YBSchema::ToString() const { |
658 | 0 | return schema_->ToString(); |
659 | 0 | } |
660 | | |
661 | 272 | ssize_t YBSchema::FindColumn(const GStringPiece& name) const { |
662 | 272 | return schema_->find_column(name); |
663 | 272 | } |
664 | | |
665 | | } // namespace client |
666 | | } // namespace yb |