YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/client/schema.h
Line
Count
Source (jump to first uncovered line)
1
//
2
// Licensed to the Apache Software Foundation (ASF) under one
3
// or more contributor license agreements.  See the NOTICE file
4
// distributed with this work for additional information
5
// regarding copyright ownership.  The ASF licenses this file
6
// to you under the Apache License, Version 2.0 (the
7
// "License"); you may not use this file except in compliance
8
// with the License.  You may obtain a copy of the License at
9
//
10
//   http://www.apache.org/licenses/LICENSE-2.0
11
//
12
// Unless required by applicable law or agreed to in writing,
13
// software distributed under the License is distributed on an
14
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
// KIND, either express or implied.  See the License for the
16
// specific language governing permissions and limitations
17
// under the License.
18
//
19
// The following only applies to changes made to this file as part of YugaByte development.
20
//
21
// Portions Copyright (c) YugaByte, Inc.
22
//
23
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
24
// in compliance with the License.  You may obtain a copy of the License at
25
//
26
// http://www.apache.org/licenses/LICENSE-2.0
27
//
28
// Unless required by applicable law or agreed to in writing, software distributed under the License
29
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
30
// or implied.  See the License for the specific language governing permissions and limitations
31
// under the License.
32
//
33
// This module defines the schema that will be used when creating tables.
34
//
35
// Note on primary key definitions.
36
// - There are two different APIs to define primary key. They cannot be used together but can be
37
//   used interchangeably for the same purpose (This is different from Kudu's original design which
38
//   uses one API for single-column key and another for multi-column key).
39
// - First API:
40
//   Each column of a primary key can be specified as hash or regular primary key.
41
//   Function PrimaryKey()
42
//   Function HashPrimaryKey().
43
// - Second API:
44
//   All hash and regular primary columns can be specified together in a list.
45
//   Function YBSchemaBuilder::SetPrimaryKey().
46
#ifndef YB_CLIENT_SCHEMA_H
47
#define YB_CLIENT_SCHEMA_H
48
49
#include <string>
50
#include <vector>
51
52
#include "yb/client/client_fwd.h"
53
#include "yb/client/value.h"
54
#include "yb/common/schema.h"
55
#include "yb/common/pg_types.h"
56
57
#include "yb/common/common_types.pb.h"
58
#include "yb/common/value.pb.h"
59
60
#include "yb/util/status_fwd.h"
61
62
namespace yb {
63
64
// the types used internally and sent over the wire to the tserver
65
typedef QLValuePB::ValueCase InternalType;
66
67
class ColumnSchema;
68
class YBPartialRow;
69
class Schema;
70
class TableProperties;
71
72
namespace tools {
73
class TsAdminClient;
74
}
75
76
namespace client {
77
78
namespace internal {
79
80
const Schema& GetSchema(const YBSchema& schema);
81
Schema& GetSchema(YBSchema* schema);
82
83
} // namespace internal
84
85
class YBClient;
86
class YBSchema;
87
class YBSchemaBuilder;
88
class YBOperation;
89
90
class YBColumnSchema {
91
 public:
92
  static InternalType ToInternalDataType(const std::shared_ptr<QLType>& ql_type);
93
  static std::string DataTypeToString(DataType type);
94
95
  // DEPRECATED: use YBSchemaBuilder instead.
96
  // TODO(KUDU-809): make this hard-to-use constructor private. Clients should use
97
  // the Builder API. Currently only the Python API uses this old API.
98
  YBColumnSchema(const std::string &name,
99
                 const std::shared_ptr<QLType>& type,
100
                 bool is_nullable = false,
101
                 bool is_hash_key = false,
102
                 bool is_static = false,
103
                 bool is_counter = false,
104
                 int32_t order = 0,
105
                 SortingType sorting_type = SortingType::kNotSpecified,
106
                 int32_t pg_type_oid = kPgInvalidOid);
107
  YBColumnSchema(const YBColumnSchema& other);
108
  ~YBColumnSchema();
109
110
  YBColumnSchema& operator=(const YBColumnSchema& other);
111
112
  void CopyFrom(const YBColumnSchema& other);
113
114
  bool Equals(const YBColumnSchema& other) const;
115
116
  // Getters to expose column schema information.
117
  const std::string& name() const;
118
  const std::shared_ptr<QLType>& type() const;
119
  bool is_hash_key() const;
120
  bool is_nullable() const;
121
  bool is_static() const;
122
  bool is_counter() const;
123
  int32_t order() const;
124
  int32_t pg_type_oid() const;
125
  SortingType sorting_type() const;
126
127
 private:
128
  friend class YBColumnSpec;
129
  friend class YBSchema;
130
  friend class YBSchemaBuilder;
131
  // YBTableAlterer::Data needs to be a friend. Friending the parent class
132
  // is transitive to nested classes. See http://tiny.cloudera.com/jwtui
133
  friend class YBTableAlterer;
134
135
  YBColumnSchema();
136
137
  std::unique_ptr<ColumnSchema> col_;
138
};
139
140
// Builder API for specifying or altering a column within a table schema.
141
// This cannot be constructed directly, but rather is returned from
142
// YBSchemaBuilder::AddColumn() to specify a column within a Schema.
143
//
144
// TODO(KUDU-861): this API will also be used for an improved AlterTable API.
145
class YBColumnSpec {
146
 public:
147
  explicit YBColumnSpec(const std::string& col_name);
148
149
  ~YBColumnSpec();
150
151
  // Operations only relevant for Create Table
152
  // ------------------------------------------------------------
153
154
  // Set this column to be the primary key of the table.
155
  //
156
  // This may only be used to set non-composite primary keys. If a composite
157
  // key is desired, use YBSchemaBuilder::SetPrimaryKey(). This may not be
158
  // used in conjunction with YBSchemaBuilder::SetPrimaryKey().
159
  //
160
  // Only relevant for a CreateTable operation. Primary keys may not be changed
161
  // after a table is created.
162
  YBColumnSpec* PrimaryKey();
163
164
  // Set this column to be a hash primary key column of the table. A hash value of all hash columns
165
  // in the primary key will be used to determine what partition (tablet) a particular row falls in.
166
  YBColumnSpec* HashPrimaryKey();
167
168
  // Set this column to be static. A static column is a column whose value is shared among rows of
169
  // the same hash key.
170
  YBColumnSpec* StaticColumn();
171
172
  // Set this column to be not nullable.
173
  // Column nullability may not be changed once a table is created.
174
  YBColumnSpec* NotNull();
175
176
  // Set this column to be nullable (the default).
177
  // Column nullability may not be changed once a table is created.
178
  YBColumnSpec* Nullable();
179
180
  // Set the type of this column.
181
  // Column types may not be changed once a table is created.
182
  YBColumnSpec* Type(const std::shared_ptr<QLType>& type);
183
184
  // Convenience function for setting a simple (i.e. non-parametric) data type.
185
  YBColumnSpec* Type(DataType type);
186
187
  // Specify the user-defined order of the column.
188
  YBColumnSpec* Order(int32_t order);
189
190
  // Specify the user-defined sorting direction.
191
  YBColumnSpec* SetSortingType(SortingType sorting_type);
192
193
  // Identify this column as counter.
194
  YBColumnSpec* Counter();
195
196
  // PgTypeOid
197
  YBColumnSpec* PgTypeOid(int32_t oid);
198
199
  // Add JSON operation.
200
  YBColumnSpec* JsonOp(JsonOperatorPB op, const std::string& str_value);
201
  YBColumnSpec* JsonOp(JsonOperatorPB op, int32_t int_value);
202
203
  // Operations only relevant for Alter Table
204
  // ------------------------------------------------------------
205
206
  // Rename this column.
207
  YBColumnSpec* RenameTo(const std::string& new_name);
208
209
 private:
210
  class Data;
211
  friend class YBSchemaBuilder;
212
  friend class YBTableAlterer;
213
214
  CHECKED_STATUS ToColumnSchema(YBColumnSchema* col) const;
215
216
  YBColumnSpec* JsonOp(JsonOperatorPB op, const QLValuePB& value);
217
218
  // Owned.
219
  Data* data_;
220
};
221
222
// Builder API for constructing a YBSchema object.
223
// The API here is a "fluent" style of programming, such that the resulting code
224
// looks somewhat like a SQL "CREATE TABLE" statement. For example:
225
//
226
// SQL:
227
//   CREATE TABLE t (
228
//     my_key int not null primary key,
229
//     a float
230
//   );
231
//
232
// is represented as:
233
//
234
//   YBSchemaBuilder t;
235
//   t.AddColumn("my_key")->Type(YBColumnSchema::INT32)->NotNull()->PrimaryKey();
236
//   t.AddColumn("a")->Type(YBColumnSchema::FLOAT);
237
//   YBSchema schema;
238
//   t.Build(&schema);
239
class YBSchemaBuilder {
240
 public:
241
  YBSchemaBuilder();
242
  ~YBSchemaBuilder();
243
244
  // Return a YBColumnSpec for a new column within the Schema.
245
  // The returned object is owned by the YBSchemaBuilder.
246
  YBColumnSpec* AddColumn(const std::string& name);
247
248
  // Set the primary key of the new Schema based on the given column names. The first
249
  // 'key_hash_col_count' columns in the primary are hash columns whose values will be used for
250
  // table partitioning. This may be used to specify a compound primary key.
251
  YBSchemaBuilder* SetPrimaryKey(const std::vector<std::string>& key_col_names,
252
                                 size_t key_hash_col_count = 0);
253
254
  YBSchemaBuilder* SetTableProperties(const TableProperties& table_properties);
255
256
  YBSchemaBuilder* SetSchemaName(const std::string& pgschema_name);
257
258
  std::string SchemaName();
259
260
  // Resets 'schema' to the result of this builder.
261
  //
262
  // If the Schema is invalid for any reason (eg missing types, duplicate column names, etc)
263
  // a bad Status will be returned.
264
  CHECKED_STATUS Build(YBSchema* schema);
265
266
 private:
267
  class Data;
268
  // Owned.
269
  Data* data_;
270
};
271
272
class YBSchema {
273
 public:
274
  YBSchema();
275
276
  explicit YBSchema(const Schema& schema);
277
278
  YBSchema(const YBSchema& other);
279
  YBSchema(YBSchema&& other);
280
  ~YBSchema();
281
282
  YBSchema& operator=(const YBSchema& other);
283
  YBSchema& operator=(YBSchema&& other);
284
  void CopyFrom(const YBSchema& other);
285
  void MoveFrom(YBSchema&& other);
286
287
  // DEPRECATED: will be removed soon.
288
  CHECKED_STATUS Reset(const std::vector<YBColumnSchema>& columns, size_t key_columns,
289
                       const TableProperties& table_properties) WARN_UNUSED_RESULT;
290
291
  void Reset(std::unique_ptr<Schema> schema);
292
293
  bool Equals(const YBSchema& other) const;
294
295
  bool EquivalentForDataCopy(const YBSchema& other) const;
296
297
  Result<bool> Equals(const SchemaPB& pb_schema) const;
298
299
  // Two schemas are equivalent if it's possible to copy data from one table to the
300
  // other containing these two schemas.
301
  // For example, columns and columns types are the same, but table properties
302
  // might be different in areas that are not relevant (e.g. TTL).
303
  Result<bool> EquivalentForDataCopy(const SchemaPB& pb_schema) const;
304
305
  const TableProperties& table_properties() const;
306
307
  YBColumnSchema Column(size_t idx) const;
308
  YBColumnSchema ColumnById(int32_t id) const;
309
310
  // Returns column id provided its index.
311
  int32_t ColumnId(size_t idx) const;
312
313
  // Returns the number of columns in hash primary keys.
314
  size_t num_hash_key_columns() const;
315
316
  // Number of range key columns.
317
  size_t num_range_key_columns() const;
318
319
  // Returns the number of columns in primary keys.
320
  size_t num_key_columns() const;
321
322
  // Returns the total number of columns.
323
  size_t num_columns() const;
324
325
  uint32_t version() const;
326
  void set_version(uint32_t version);
327
  bool is_compatible_with_previous_version() const;
328
  void set_is_compatible_with_previous_version(bool is_compat);
329
330
  // Get the indexes of the primary key columns within this Schema.
331
  // In current versions of YB, these will always be contiguous column
332
  // indexes starting with 0. However, in future versions this assumption
333
  // may not hold, so callers should not assume it is the case.
334
  std::vector<size_t> GetPrimaryKeyColumnIndexes() const;
335
336
  // Create a new row corresponding to this schema.
337
  //
338
  // The new row refers to this YBSchema object, so must be destroyed before
339
  // the YBSchema object.
340
  //
341
  // The caller takes ownership of the created row.
342
  std::unique_ptr<YBPartialRow> NewRow() const;
343
344
  const std::vector<ColumnSchema>& columns() const;
345
346
  ssize_t FindColumn(const GStringPiece& name) const;
347
348
  std::string ToString() const;
349
350
 private:
351
  friend YBSchema YBSchemaFromSchema(const Schema& schema);
352
  friend const Schema& internal::GetSchema(const YBSchema& schema);
353
  friend Schema& internal::GetSchema(YBSchema* schema);
354
355
  std::unique_ptr<Schema> schema_;
356
  uint32_t version_;
357
  bool is_compatible_with_previous_version_ = false;
358
};
359
360
0
inline bool operator==(const YBSchema& lhs, const YBSchema& rhs) {
361
0
  return lhs.Equals(rhs);
362
0
}
363
364
0
inline std::ostream& operator<<(std::ostream& out, const YBSchema& schema) {
365
0
  return out << schema.ToString();
366
0
}
367
368
} // namespace client
369
} // namespace yb
370
371
#endif // YB_CLIENT_SCHEMA_H