YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

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