-
Notifications
You must be signed in to change notification settings - Fork 170
/
Copy pathschema.hh
840 lines (745 loc) · 28.9 KB
/
schema.hh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
/*
* Copyright (C) 2015 ScyllaDB
*/
/*
* This file is part of Scylla.
*
* Scylla is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Scylla is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Scylla. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <unordered_map>
#include <boost/range/iterator_range.hpp>
#include <boost/range/join.hpp>
#include <boost/range/algorithm/transform.hpp>
#include <boost/lexical_cast.hpp>
#include "cql3/column_specification.hh"
#include "core/shared_ptr.hh"
#include "types.hh"
#include "compound.hh"
#include "gc_clock.hh"
#include "unimplemented.hh"
#include "utils/UUID.hh"
#include "compress.hh"
#include "compaction_strategy.hh"
#include "caching_options.hh"
#include "stdx.hh"
using column_count_type = uint32_t;
// Column ID, unique within column_kind
using column_id = column_count_type;
// Cluster-wide identifier of schema version of particular table.
//
// The version changes the value not only on structural changes but also
// temporal. For example, schemas with the same set of columns but created at
// different times should have different versions. This allows nodes to detect
// if the version they see was already synchronized with or not even if it has
// the same structure as the past versions.
//
// Schema changes merged in any order should result in the same final version.
//
// When table_schema_version changes, schema_tables::calculate_schema_digest() should
// also change when schema mutations are applied.
using table_schema_version = utils::UUID;
class schema;
class schema_registry_entry;
class schema_builder;
// Useful functions to manipulate the schema's comparator field
namespace cell_comparator {
sstring to_sstring(const schema& s);
bool check_compound(sstring comparator);
void read_collections(schema_builder& builder, sstring comparator);
}
namespace db {
class extensions;
}
// make sure these match the order we like columns back from schema
enum class column_kind { partition_key, clustering_key, static_column, regular_column };
enum class column_view_virtual { no, yes };
sstring to_sstring(column_kind k);
bool is_compatible(column_kind k1, column_kind k2);
enum class cf_type : uint8_t {
standard,
super,
};
inline sstring cf_type_to_sstring(cf_type t) {
if (t == cf_type::standard) {
return "Standard";
} else if (t == cf_type::super) {
return "Super";
}
throw std::invalid_argument(sprint("unknown type: %d\n", uint8_t(t)));
}
inline cf_type sstring_to_cf_type(sstring name) {
if (name == "Standard") {
return cf_type::standard;
} else if (name == "Super") {
return cf_type::super;
}
throw std::invalid_argument(sprint("unknown type: %s\n", name));
}
struct speculative_retry {
enum class type {
NONE, CUSTOM, PERCENTILE, ALWAYS
};
private:
type _t;
double _v;
public:
speculative_retry(type t, double v) : _t(t), _v(v) {}
sstring to_sstring() const {
if (_t == type::NONE) {
return "NONE";
} else if (_t == type::ALWAYS) {
return "ALWAYS";
} else if (_t == type::CUSTOM) {
return sprint("%.2fms", _v);
} else if (_t == type::PERCENTILE) {
return sprint("%.1fPERCENTILE", 100 * _v);
} else {
throw std::invalid_argument(sprint("unknown type: %d\n", uint8_t(_t)));
}
}
static speculative_retry from_sstring(sstring str) {
std::transform(str.begin(), str.end(), str.begin(), ::toupper);
sstring ms("MS");
sstring percentile("PERCENTILE");
auto convert = [&str] (sstring& t) {
try {
return boost::lexical_cast<double>(str.substr(0, str.size() - t.size()));
} catch (boost::bad_lexical_cast& e) {
throw std::invalid_argument(sprint("cannot convert %s to speculative_retry\n", str));
}
};
type t;
double v = 0;
if (str == "NONE") {
t = type::NONE;
} else if (str == "ALWAYS") {
t = type::ALWAYS;
} else if (str.compare(str.size() - ms.size(), ms.size(), ms) == 0) {
t = type::CUSTOM;
v = convert(ms);
} else if (str.compare(str.size() - percentile.size(), percentile.size(), percentile) == 0) {
t = type::PERCENTILE;
v = convert(percentile) / 100;
} else {
throw std::invalid_argument(sprint("cannot convert %s to speculative_retry\n", str));
}
return speculative_retry(t, v);
}
type get_type() const {
return _t;
}
double get_value() const {
return _v;
}
bool operator==(const speculative_retry& other) const {
return _t == other._t && _v == other._v;
}
bool operator!=(const speculative_retry& other) const {
return !(*this == other);
}
};
typedef std::unordered_map<sstring, sstring> index_options_map;
enum class index_metadata_kind {
keys,
custom,
composites,
};
class index_metadata final {
utils::UUID _id;
sstring _name;
index_metadata_kind _kind;
index_options_map _options;
public:
index_metadata(const sstring& name, const index_options_map& options, index_metadata_kind kind);
bool operator==(const index_metadata& other) const;
bool equals_noname(const index_metadata& other) const;
const utils::UUID& id() const;
const sstring& name() const;
const index_metadata_kind kind() const;
const index_options_map& options() const;
static sstring get_default_index_name(const sstring& cf_name, std::experimental::optional<sstring> root);
};
class column_definition final {
public:
struct name_comparator {
data_type type;
name_comparator(data_type type) : type(type) {}
bool operator()(const column_definition& cd1, const column_definition& cd2) const {
return type->less(cd1.name(), cd2.name());
}
};
private:
bytes _name;
api::timestamp_type _dropped_at;
bool _is_atomic;
bool _is_counter;
column_view_virtual _is_view_virtual;
struct thrift_bits {
thrift_bits()
: is_on_all_components(0)
{}
uint8_t is_on_all_components : 1;
// more...?
};
thrift_bits _thrift_bits;
friend class schema;
public:
column_definition(bytes name, data_type type, column_kind kind,
column_id component_index = 0,
column_view_virtual view_virtual = column_view_virtual::no,
api::timestamp_type dropped_at = api::missing_timestamp);
data_type type;
// Unique within (kind, schema instance).
// schema::position() and component_index() depend on the fact that for PK columns this is
// equivalent to component index.
column_id id;
column_kind kind;
::shared_ptr<cql3::column_specification> column_specification;
bool is_static() const { return kind == column_kind::static_column; }
bool is_regular() const { return kind == column_kind::regular_column; }
bool is_partition_key() const { return kind == column_kind::partition_key; }
bool is_clustering_key() const { return kind == column_kind::clustering_key; }
bool is_primary_key() const { return kind == column_kind::partition_key || kind == column_kind::clustering_key; }
bool is_atomic() const { return _is_atomic; }
bool is_multi_cell() const { return !_is_atomic; }
bool is_counter() const { return _is_counter; }
// "virtual columns" appear in a materialized view as placeholders for
// unselected columns, with liveness information but without data, and
// allow view rows to remain alive despite having no data (issue #3362).
// These columns should be hidden from the user's SELECT queries.
bool is_view_virtual() const { return _is_view_virtual == column_view_virtual::yes; }
column_view_virtual view_virtual() const { return _is_view_virtual; }
const sstring& name_as_text() const;
const bytes& name() const;
sstring name_as_cql_string() const;
friend std::ostream& operator<<(std::ostream& os, const column_definition& cd);
friend std::ostream& operator<<(std::ostream& os, const column_definition* cd) {
return cd != nullptr ? os << *cd : os << "(null)";
}
bool has_component_index() const {
return is_primary_key();
}
uint32_t component_index() const {
assert(has_component_index());
return id;
}
uint32_t position() const {
if (has_component_index()) {
return component_index();
}
return 0;
}
bool is_on_all_components() const;
bool is_part_of_cell_name() const {
return is_regular() || is_static();
}
api::timestamp_type dropped_at() const { return _dropped_at; }
friend bool operator==(const column_definition&, const column_definition&);
};
class schema_builder;
/*
* Sub-schema for thrift aspects. Should be kept isolated (and starved)
*/
class thrift_schema {
bool _compound = true;
bool _is_dynamic = false;
public:
bool has_compound_comparator() const;
bool is_dynamic() const;
friend class schema;
};
bool operator==(const column_definition&, const column_definition&);
static constexpr int DEFAULT_MIN_COMPACTION_THRESHOLD = 4;
static constexpr int DEFAULT_MAX_COMPACTION_THRESHOLD = 32;
static constexpr int DEFAULT_MIN_INDEX_INTERVAL = 128;
static constexpr int DEFAULT_GC_GRACE_SECONDS = 864000;
// Unsafe to access across shards.
// Safe to copy across shards.
class column_mapping_entry {
bytes _name;
data_type _type;
bool _is_atomic;
public:
column_mapping_entry(bytes name, data_type type)
: _name(std::move(name)), _type(std::move(type)), _is_atomic(_type->is_atomic()) { }
column_mapping_entry(bytes name, sstring type_name);
column_mapping_entry(const column_mapping_entry&);
column_mapping_entry& operator=(const column_mapping_entry&);
column_mapping_entry(column_mapping_entry&&) = default;
column_mapping_entry& operator=(column_mapping_entry&&) = default;
const bytes& name() const { return _name; }
const data_type& type() const { return _type; }
const sstring& type_name() const { return _type->name(); }
bool is_atomic() const { return _is_atomic; }
};
// Encapsulates information needed for converting mutations between different schema versions.
//
// Unsafe to access across shards.
// Safe to copy across shards.
class column_mapping {
private:
// Contains _n_static definitions for static columns followed by definitions for regular columns,
// both ordered by consecutive column_ids.
// Primary key column sets are not mutable so we don't need to map them.
std::vector<column_mapping_entry> _columns;
column_count_type _n_static = 0;
public:
column_mapping() {}
column_mapping(std::vector<column_mapping_entry> columns, column_count_type n_static)
: _columns(std::move(columns))
, _n_static(n_static)
{ }
const std::vector<column_mapping_entry>& columns() const { return _columns; }
column_count_type n_static() const { return _n_static; }
const column_mapping_entry& column_at(column_kind kind, column_id id) const {
assert(kind == column_kind::regular_column || kind == column_kind::static_column);
return kind == column_kind::regular_column ? regular_column_at(id) : static_column_at(id);
}
const column_mapping_entry& static_column_at(column_id id) const {
if (id >= _n_static) {
throw std::out_of_range(sprint("static column id %d >= %d", id, _n_static));
}
return _columns[id];
}
const column_mapping_entry& regular_column_at(column_id id) const {
auto n_regular = _columns.size() - _n_static;
if (id >= n_regular) {
throw std::out_of_range(sprint("regular column id %d >= %d", id, n_regular));
}
return _columns[id + _n_static];
}
friend std::ostream& operator<<(std::ostream& out, const column_mapping& cm);
};
/**
* Augments a schema with fields related to materialized views.
* Effectively immutable.
*/
class raw_view_info final {
utils::UUID _base_id;
sstring _base_name;
bool _include_all_columns;
sstring _where_clause;
public:
raw_view_info(utils::UUID base_id, sstring base_name, bool include_all_columns, sstring where_clause);
const utils::UUID& base_id() const {
return _base_id;
}
const sstring& base_name() const {
return _base_name;
}
bool include_all_columns() const {
return _include_all_columns;
}
const sstring& where_clause() const {
return _where_clause;
}
friend bool operator==(const raw_view_info&, const raw_view_info&);
friend std::ostream& operator<<(std::ostream& os, const raw_view_info& view);
};
bool operator==(const raw_view_info&, const raw_view_info&);
std::ostream& operator<<(std::ostream& os, const raw_view_info& view);
class view_info;
// Represents a column set which is compactible with Cassandra 3.x.
//
// This layout differs from the layout Scylla uses in schema/schema_builder for static compact tables.
// For such tables, Scylla expects all columns to be of regular type and no clustering columns,
// whereas in v3 those columns are static and there is a clustering column with type matching the
// cell name comparator and a regular column with type matching the default validator.
// See issues #2555 and #1474.
class v3_columns {
bool _is_dense = false;
bool _is_compound = false;
std::vector<column_definition> _columns;
std::unordered_map<bytes, const column_definition*> _columns_by_name;
public:
v3_columns(std::vector<column_definition> columns, bool is_dense, bool is_compound);
v3_columns() = default;
v3_columns(v3_columns&&) = default;
v3_columns& operator=(v3_columns&&) = default;
v3_columns(const v3_columns&) = delete;
static v3_columns from_v2_schema(const schema&);
public:
const std::vector<column_definition>& all_columns() const;
const std::unordered_map<bytes, const column_definition*>& columns_by_name() const;
bool is_static_compact() const;
bool is_compact() const;
void apply_to(schema_builder&) const;
};
namespace query {
class partition_slice;
}
/**
* Schema extension. An opaque type representing
* entries in the "extensions" part of a table/view (see schema_tables).
*
* An extension has a name (the mapping key), and it can re-serialize
* itself to bytes again, when we write back into schema tables.
*
* Code using a particular extension can locate it by name in the schema map,
* and barring the "is_placeholder" says true, cast it to whatever might
* be the expeceted implementation.
*
* We allow placeholder object since an extension written to schema tables
* might be unavailable on next boot/other node. To avoid loosing the config data,
* a placeholder object is put into schema map, which at least can
* re-serialize the data back.
*
*/
class schema_extension {
public:
virtual ~schema_extension() {};
virtual bytes serialize() const = 0;
virtual bool is_placeholder() const {
return false;
}
};
/*
* Effectively immutable.
* Not safe to access across cores because of shared_ptr's.
* Use global_schema_ptr for safe across-shard access.
*/
class schema final : public enable_lw_shared_from_this<schema> {
friend class v3_columns;
public:
struct dropped_column {
data_type type;
api::timestamp_type timestamp;
bool operator==(const dropped_column& rhs) const {
return type == rhs.type && timestamp == rhs.timestamp;
}
};
using extensions_map = std::map<sstring, ::shared_ptr<schema_extension>>;
private:
// More complex fields are derived from these inside rebuild().
// Contains only fields which can be safely default-copied.
struct raw_schema {
raw_schema(utils::UUID id);
utils::UUID _id;
sstring _ks_name;
sstring _cf_name;
// regular columns are sorted by name
// static columns are sorted by name, but present only when there's any clustering column
std::vector<column_definition> _columns;
sstring _comment;
gc_clock::duration _default_time_to_live = gc_clock::duration::zero();
data_type _regular_column_name_type;
data_type _default_validation_class = bytes_type;
double _bloom_filter_fp_chance = 0.01;
compression_parameters _compressor_params;
extensions_map _extensions;
bool _is_dense = false;
bool _is_compound = true;
bool _is_counter = false;
cf_type _type = cf_type::standard;
int32_t _gc_grace_seconds = DEFAULT_GC_GRACE_SECONDS;
double _dc_local_read_repair_chance = 0.1;
double _read_repair_chance = 0.0;
double _crc_check_chance = 1;
int32_t _min_compaction_threshold = DEFAULT_MIN_COMPACTION_THRESHOLD;
int32_t _max_compaction_threshold = DEFAULT_MAX_COMPACTION_THRESHOLD;
int32_t _min_index_interval = DEFAULT_MIN_INDEX_INTERVAL;
int32_t _max_index_interval = 2048;
int32_t _memtable_flush_period = 0;
speculative_retry _speculative_retry = ::speculative_retry(speculative_retry::type::PERCENTILE, 0.99);
// FIXME: SizeTiered doesn't really work yet. Being it marked here only means that this is the strategy
// we will use by default - when we have the choice.
sstables::compaction_strategy_type _compaction_strategy = sstables::compaction_strategy_type::size_tiered;
std::map<sstring, sstring> _compaction_strategy_options;
bool _compaction_enabled = true;
caching_options _caching_options;
table_schema_version _version;
std::unordered_map<sstring, dropped_column> _dropped_columns;
std::map<bytes, data_type> _collections;
std::unordered_map<sstring, index_metadata> _indices_by_name;
};
raw_schema _raw;
thrift_schema _thrift;
v3_columns _v3_columns;
mutable schema_registry_entry* _registry_entry = nullptr;
std::unique_ptr<::view_info> _view_info;
const std::array<column_count_type, 3> _offsets;
inline column_count_type column_offset(column_kind k) const {
return k == column_kind::partition_key ? 0 : _offsets[column_count_type(k) - 1];
}
std::unordered_map<bytes, const column_definition*> _columns_by_name;
lw_shared_ptr<compound_type<allow_prefixes::no>> _partition_key_type;
lw_shared_ptr<compound_type<allow_prefixes::yes>> _clustering_key_type;
column_mapping _column_mapping;
shared_ptr<query::partition_slice> _full_slice;
column_count_type _clustering_key_size;
column_count_type _regular_column_count;
column_count_type _static_column_count;
extensions_map& extensions() {
return _raw._extensions;
}
friend class db::extensions;
friend class schema_builder;
public:
using row_column_ids_are_ordered_by_name = std::true_type;
typedef std::vector<column_definition> columns_type;
typedef typename columns_type::iterator iterator;
typedef typename columns_type::const_iterator const_iterator;
typedef boost::iterator_range<iterator> iterator_range_type;
typedef boost::iterator_range<const_iterator> const_iterator_range_type;
static constexpr int32_t NAME_LENGTH = 48;
struct column {
bytes name;
data_type type;
};
private:
::shared_ptr<cql3::column_specification> make_column_specification(const column_definition& def);
void rebuild();
schema(const raw_schema&, stdx::optional<raw_view_info>);
public:
// deprecated, use schema_builder.
schema(std::experimental::optional<utils::UUID> id,
sstring ks_name,
sstring cf_name,
std::vector<column> partition_key,
std::vector<column> clustering_key,
std::vector<column> regular_columns,
std::vector<column> static_columns,
data_type regular_column_name_type,
sstring comment = {});
schema(const schema&);
~schema();
table_schema_version version() const {
return _raw._version;
}
double bloom_filter_fp_chance() const {
return _raw._bloom_filter_fp_chance;
}
sstring thrift_key_validator() const;
const compression_parameters& get_compressor_params() const {
return _raw._compressor_params;
}
const extensions_map& extensions() const {
return _raw._extensions;
}
bool is_dense() const {
return _raw._is_dense;
}
bool is_compound() const {
return _raw._is_compound;
}
bool is_cql3_table() const {
return !is_super() && !is_dense() && is_compound();
}
bool is_compact_table() const {
return !is_cql3_table();
}
bool is_static_compact_table() const {
return !is_super() && !is_dense() && !is_compound();
}
thrift_schema& thrift() {
return _thrift;
}
const thrift_schema& thrift() const {
return _thrift;
}
const utils::UUID& id() const {
return _raw._id;
}
const sstring& comment() const {
return _raw._comment;
}
bool is_counter() const {
return _raw._is_counter;
}
const cf_type type() const {
return _raw._type;
}
bool is_super() const {
return _raw._type == cf_type::super;
}
gc_clock::duration gc_grace_seconds() const {
auto seconds = std::chrono::seconds(_raw._gc_grace_seconds);
return std::chrono::duration_cast<gc_clock::duration>(seconds);
}
double dc_local_read_repair_chance() const {
return _raw._dc_local_read_repair_chance;
}
double read_repair_chance() const {
return _raw._read_repair_chance;
}
double crc_check_chance() const {
return _raw._crc_check_chance;
}
int32_t min_compaction_threshold() const {
return _raw._min_compaction_threshold;
}
int32_t max_compaction_threshold() const {
return _raw._max_compaction_threshold;
}
int32_t min_index_interval() const {
return _raw._min_index_interval;
}
int32_t max_index_interval() const {
return _raw._max_index_interval;
}
int32_t memtable_flush_period() const {
return _raw._memtable_flush_period;
}
sstables::compaction_strategy_type configured_compaction_strategy() const {
return _raw._compaction_strategy;
}
sstables::compaction_strategy_type compaction_strategy() const {
return _raw._compaction_enabled ? _raw._compaction_strategy : sstables::compaction_strategy_type::null;
}
const std::map<sstring, sstring>& compaction_strategy_options() const {
return _raw._compaction_strategy_options;
}
bool compaction_enabled() const {
return _raw._compaction_enabled;
}
const ::speculative_retry& speculative_retry() const {
return _raw._speculative_retry;
}
const ::caching_options& caching_options() const {
return _raw._caching_options;
}
const column_definition* get_column_definition(const bytes& name) const;
const column_definition& column_at(column_kind, column_id) const;
const_iterator regular_begin() const;
const_iterator regular_end() const;
const_iterator regular_lower_bound(const bytes& name) const;
const_iterator regular_upper_bound(const bytes& name) const;
const_iterator static_begin() const;
const_iterator static_end() const;
const_iterator static_lower_bound(const bytes& name) const;
const_iterator static_upper_bound(const bytes& name) const;
data_type column_name_type(const column_definition& def) const;
const column_definition& clustering_column_at(column_id id) const;
const column_definition& regular_column_at(column_id id) const;
const column_definition& static_column_at(column_id id) const;
bool is_last_partition_key(const column_definition& def) const;
bool has_multi_cell_collections() const;
bool has_static_columns() const;
column_count_type columns_count(column_kind kind) const;
column_count_type partition_key_size() const;
column_count_type clustering_key_size() const { return _clustering_key_size; }
column_count_type static_columns_count() const { return _static_column_count; }
column_count_type regular_columns_count() const { return _regular_column_count; }
// Returns a range of column definitions
const_iterator_range_type partition_key_columns() const;
// Returns a range of column definitions
const_iterator_range_type clustering_key_columns() const;
// Returns a range of column definitions
const_iterator_range_type static_columns() const;
// Returns a range of column definitions
const_iterator_range_type regular_columns() const;
// Returns a range of column definitions
typedef boost::range::joined_range<const_iterator_range_type, const_iterator_range_type>
select_order_range;
select_order_range all_columns_in_select_order() const;
uint32_t position(const column_definition& column) const;
const columns_type& all_columns() const {
return _raw._columns;
}
const std::unordered_map<bytes, const column_definition*>& columns_by_name() const {
return _columns_by_name;
}
const auto& dropped_columns() const {
return _raw._dropped_columns;
}
const auto& collections() const {
return _raw._collections;
}
gc_clock::duration default_time_to_live() const {
return _raw._default_time_to_live;
}
data_type make_legacy_default_validator() const;
const sstring& ks_name() const {
return _raw._ks_name;
}
const sstring& cf_name() const {
return _raw._cf_name;
}
const lw_shared_ptr<compound_type<allow_prefixes::no>>& partition_key_type() const {
return _partition_key_type;
}
const lw_shared_ptr<compound_type<allow_prefixes::yes>>& clustering_key_type() const {
return _clustering_key_type;
}
const lw_shared_ptr<compound_type<allow_prefixes::yes>>& clustering_key_prefix_type() const {
return _clustering_key_type;
}
const data_type& regular_column_name_type() const {
return _raw._regular_column_name_type;
}
const data_type& static_column_name_type() const {
return utf8_type;
}
const std::unique_ptr<::view_info>& view_info() const {
return _view_info;
}
bool is_view() const {
return bool(_view_info);
}
const query::partition_slice& full_slice() const {
return *_full_slice;
}
// Returns all index names of this schema.
std::vector<sstring> index_names() const;
// Returns all indices of this schema.
std::vector<index_metadata> indices() const;
const std::unordered_map<sstring, index_metadata>& all_indices() const;
// Search for an index with a given name.
bool has_index(const sstring& index_name) const;
// Search for an existing index with same kind and options.
stdx::optional<index_metadata> find_index_noname(const index_metadata& target) const;
friend std::ostream& operator<<(std::ostream& os, const schema& s);
friend bool operator==(const schema&, const schema&);
const column_mapping& get_column_mapping() const;
friend class schema_registry_entry;
// May be called from different shard
schema_registry_entry* registry_entry() const noexcept;
// Returns true iff this schema version was synced with on current node.
// Schema version is said to be synced with when its mutations were merged
// into current node's schema, so that current node's schema is at least as
// recent as this version.
bool is_synced() const;
bool equal_columns(const schema&) const;
public:
const v3_columns& v3() const {
return _v3_columns;
}
};
bool operator==(const schema&, const schema&);
using schema_ptr = lw_shared_ptr<const schema>;
/**
* Wrapper for schema_ptr used by functions that expect an engaged view_info field.
*/
class view_ptr final {
schema_ptr _schema;
public:
explicit view_ptr(schema_ptr schema) noexcept : _schema(schema) {
if (schema) {
assert(_schema->is_view());
}
}
const schema& operator*() const noexcept { return *_schema; }
const schema* operator->() const noexcept { return _schema.operator->(); }
const schema* get() const noexcept { return _schema.get(); }
operator schema_ptr() const noexcept {
return _schema;
}
explicit operator bool() const noexcept {
return bool(_schema);
}
friend std::ostream& operator<<(std::ostream& os, const view_ptr& s);
};
std::ostream& operator<<(std::ostream& os, const view_ptr& view);
utils::UUID generate_legacy_id(const sstring& ks_name, const sstring& cf_name);