0.9.8.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Schema.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007-2015 Hypertable, Inc.
3  *
4  * This file is part of Hypertable.
5  *
6  * Hypertable is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; version 3 of the
9  * License, or any later version.
10  *
11  * Hypertable is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  * 02110-1301, USA.
20  */
21 
26 
27 #include <Common/Compat.h>
28 #include "Schema.h"
29 
30 #include <Common/Config.h>
31 #include <Common/FileUtils.h>
32 #include <Common/Logger.h>
33 #include <Common/StringExt.h>
34 #include <Common/System.h>
35 #include <Common/XmlParser.h>
36 
37 #include <expat.h>
38 
39 #include <boost/algorithm/string.hpp>
40 
41 extern "C" {
42 #include <ctype.h>
43 #include <errno.h>
44 #include <strings.h>
45 #include <sys/types.h>
46 #include <sys/stat.h>
47 }
48 
49 #include <algorithm>
50 #include <cctype>
51 #include <cstdio>
52 #include <cstdlib>
53 #include <iostream>
54 #include <map>
55 #include <set>
56 #include <string>
57 
58 using namespace Hypertable;
59 using namespace Property;
60 using namespace std;
61 
62 #define MAX_COLUMN_ID 255
63 
64 namespace {
65  const std::string maybe_quote(const string &name) {
66  auto valid_char = [](char c) { return isalnum(c); };
67  if (!isalpha(name[0]) ||
68  find_if_not(name.begin(), name.end(), valid_char) != name.end())
69  return String("'") + name + "'";
70  return name;
71  }
72 }
73 
77 Schema::Schema(const Schema &other)
78  : m_arena(1024)
79 {
82 
83  // Set schema attributes
84  m_generation = other.m_generation;
85  m_version = other.m_version;
87 
88  // Create access groups
89  for (auto src_ag : other.m_access_groups) {
90  AccessGroupSpec *ag = new AccessGroupSpec(src_ag->get_name());
91 
92  if (src_ag->options().is_set_replication())
93  ag->set_option_replication(src_ag->get_option_replication());
94  if (src_ag->options().is_set_blocksize())
95  ag->set_option_blocksize(src_ag->get_option_blocksize());
96  if (src_ag->options().is_set_compressor())
97  ag->set_option_compressor(src_ag->get_option_compressor());
98  if (src_ag->options().is_set_bloom_filter())
99  ag->set_option_bloom_filter(src_ag->get_option_bloom_filter());
100  if (src_ag->options().is_set_in_memory())
101  ag->set_option_in_memory(src_ag->get_option_in_memory());
102 
103  if (src_ag->defaults().is_set_max_versions())
104  ag->set_default_max_versions(src_ag->get_default_max_versions());
105  if (src_ag->defaults().is_set_ttl())
106  ag->set_default_ttl(src_ag->get_default_ttl());
107  if (src_ag->defaults().is_set_time_order_desc())
108  ag->set_default_time_order_desc(src_ag->get_default_time_order_desc());
109  if (src_ag->defaults().is_set_counter())
110  ag->set_default_counter(src_ag->get_default_counter());
111 
112  ag->set_generation(src_ag->get_generation());
113 
114  // Populate access group with column families
115  for (auto src_cf : src_ag->columns())
116  ag->add_column(new ColumnFamilySpec(*src_cf));
117 
118  m_access_group_map.insert(make_pair(m_arena.dup(ag->get_name()), ag));
119  m_access_groups.push_back(ag);
120 
121  }
122 
125 
126  validate();
127 
128 }
129 
131  for_each(m_access_groups.begin(), m_access_groups.end(),
132  [](AccessGroupSpec *ag) { delete ag; });
133 }
134 
135 
136 namespace {
137 
138  class XmlParserSchema : public XmlParser {
139  public:
140  XmlParserSchema(Schema *schema, const char *s, int len) :
141  XmlParser(s,len,{"AccessGroup","AccessGroupDefaults","ColumnFamilyDefaults"}),
142  m_schema(schema) {}
143 
144  void start_element(const XML_Char *name, const XML_Char **atts) override {
145  if (m_element_stack.empty()) {
146  for (int i=0; atts[i] != 0; i+=2) {
147  if (!strcasecmp(atts[i], "generation"))
148  m_schema->set_generation(content_to_i64(atts[i], atts[i+1]));
149  else if (!strcasecmp(atts[i], "version"))
150  m_schema->set_version(content_to_i32(atts[i], atts[i+1]));
151  else if (!strcasecmp(atts[i], "group_commit_interval"))
152  m_schema->set_group_commit_interval(content_to_i32(atts[i], atts[i+1]));
153  else if (!strcasecmp(atts[i], "compressor"))
154  m_schema->access_group_defaults().set_compressor(atts[i+1]);
155  else
157  "Unrecognized attribute (%s) in Schema element", atts[i]);
158  }
159  }
160  else if (strcasecmp(name, "Generation") &&
161  strcasecmp(name, "GroupCommitInterval"))
163  "Unrecognized Schema element (%s)", name);
164  }
165 
166  void end_element(const XML_Char *name, const string &content) override {
167  if (!strcasecmp(name, "Generation"))
168  m_schema->set_generation(content_to_i64(name, content));
169  else if (!strcasecmp(name, "GroupCommitInterval"))
170  m_schema->set_group_commit_interval(content_to_i32(name, content));
171  else if (!m_element_stack.empty())
173  "Unrecognized Schema element (%s)", name);
174  }
175 
176  void sub_parse(const XML_Char *name, const char *s, int len) override {
177  if (!strcasecmp(name, "AccessGroup")) {
178  AccessGroupSpec *ag_spec = new AccessGroupSpec();
179  try { ag_spec->parse_xml(s, len); }
180  catch (Exception &) { delete ag_spec; throw; }
181  m_schema->add_access_group(ag_spec);
182  }
183  else if (!strcasecmp(name, "AccessGroupDefaults")) {
184  AccessGroupOptions defaults;
185  defaults.parse_xml(s, len);
186  m_schema->set_access_group_defaults(defaults);
187  }
188  else if (!strcasecmp(name, "ColumnFamilyDefaults")) {
189  ColumnFamilyOptions defaults;
190  defaults.parse_xml(s, len);
191  m_schema->set_column_family_defaults(defaults);
192  }
193  }
194 
195  private:
196  Schema *m_schema;
197  };
198 
199 }
200 
201 
202 Schema *Schema::new_instance(const string &buf) {
203  Schema *schema = new Schema();
204  XmlParserSchema parser(schema, buf.c_str(), buf.length());
205  try {
206  parser.parse();
207  schema->validate();
208  }
209  catch (Exception &) {
210  delete schema;
211  throw;
212  }
213  return schema;
214 }
215 
217  m_generation = 0;
218  for (auto ag : m_access_groups)
219  for (auto cf : ag->columns())
220  cf->set_generation(0);
221 }
222 
224  bool changed {};
225  for (auto ag : m_access_groups) {
226  auto orig_ag = original.get_access_group(ag->get_name());
227  if (orig_ag == nullptr || ag->clear_generation_if_changed(*orig_ag)) {
228  m_generation = 0;
229  changed = true;
230  }
231  }
232  if (!changed) {
233  for (auto ag : original.get_access_groups()) {
234  if (get_access_group(ag->get_name()) == nullptr) {
235  m_generation = 0;
236  changed = true;
237  break;
238  }
239  }
240  }
241  return changed;
242 }
243 
244 void Schema::update_generation(int64_t generation) {
245  int64_t max_id = get_max_column_family_id();
246  for (auto ag : m_access_groups) {
247  for (auto cf : ag->columns()) {
248  if (cf->get_generation() == 0) {
249  if (cf->get_id() == 0)
250  cf->set_id(++max_id);
251  cf->set_generation(generation);
252  ag->set_generation(generation);
253  m_generation = generation;
254  }
255  else
256  HT_ASSERT(cf->get_id());
257  }
258  if (ag->get_generation() == 0)
259  ag->set_generation(generation);
260  }
261  validate();
262 }
263 
264 
265 const string Schema::render_xml(bool with_ids) {
266  string output = "<Schema";
267  if (m_version != 0)
268  output += format(" version=\"%d\"", (int)m_version);
269  output += ">\n";
270 
271  if (with_ids)
272  output += format(" <Generation>%lld</Generation>\n", (Lld)m_generation);
273 
274  if (m_group_commit_interval > 0)
275  output += format(" <GroupCommitInterval>%u</GroupCommitInterval>\n", m_group_commit_interval);
276 
277  output += " <AccessGroupDefaults>\n";
278  output += m_ag_defaults.render_xml(" ");
279  output += " </AccessGroupDefaults>\n";
280 
281  output += " <ColumnFamilyDefaults>\n";
282  output += m_cf_defaults.render_xml(" ");
283  output += " </ColumnFamilyDefaults>\n";
284 
285  for (auto ag_spec : m_access_groups)
286  output += ag_spec->render_xml(" ", with_ids);
287 
288  output += "</Schema>\n";
289  return output;
290 }
291 
292 const string Schema::render_hql(const string &table_name) {
293  string output = "CREATE TABLE ";
294  output += maybe_quote(table_name);
295  output += " (\n";
296 
297  for (auto ag_spec : m_access_groups) {
298  for (auto cf_spec : ag_spec->columns()) {
299  if (!cf_spec->get_deleted()) {
300  output += cf_spec->render_hql();
301  output += ",\n";
302  }
303  }
304  }
305 
306  size_t i = 1;
307  for (auto ag_spec : m_access_groups) {
308  output += ag_spec->render_hql();
309  output += i == m_access_groups.size() ? "\n" : ",\n";
310  i++;
311  }
312  output += ")";
313 
314  if (m_group_commit_interval > 0)
315  output += format(" GROUP_COMMIT_INTERVAL %u", m_group_commit_interval);
316 
317  output += m_ag_defaults.render_hql();
318  output += m_cf_defaults.render_hql();
319  return output;
320 }
321 
322 
329  int32_t max {};
330  for (auto ag : m_access_groups)
331  for (auto cf : ag->columns())
332  if (cf->get_id() > max)
333  max = cf->get_id();
334  return max;
335 }
336 
338  int parts {};
339  for (auto ag : m_access_groups) {
340  for (auto cf : ag->columns()) {
341  if (!cf->get_deleted()) {
342  parts |= TableParts::PRIMARY;
343  if (cf->get_value_index())
344  parts |= TableParts::VALUE_INDEX;
345  if (cf->get_qualifier_index())
347  }
348  }
349  }
350  return TableParts(parts);
351 }
352 
353 
355 
356  // Add to access group map
357  auto res = m_access_group_map.insert(
358  make_pair(m_arena.dup(ag->get_name()), ag));
359  if (!res.second)
361  "Attempt to add access group '%s' which already exists",
362  ag->get_name().c_str());
363 
364  set<string> column_families;
365  for (auto cf : ag->columns())
366  column_families.insert(cf->get_name());
367 
368  size_t column_count {};
369  for (auto ag : m_access_groups) {
370  column_count += ag->columns().size();
371  for (auto cf : ag->columns()) {
372  if (column_families.count(cf->get_name()))
374  "Column family '%s' already defined",
375  cf->get_name().c_str());
376  }
377  }
378 
379  if (column_count + ag->columns().size() > MAX_COLUMN_ID)
381  "Attempt to add > %d column families to table",
382  MAX_COLUMN_ID);
383 
384  // Add to access group vector
385  m_access_groups.push_back(ag);
386 
387  // Merge table defaults into added access group
389 
390  // Merge table defaults into each added column
391  for (auto cf : ag->columns())
393 
394 }
395 
397  auto iter = m_column_family_map.find(name.c_str());
398  if (iter != m_column_family_map.end()) {
399  ColumnFamilySpec *cf = iter->second;
400  auto ag_map_iter = m_access_group_map.find(cf->get_access_group().c_str());
401  HT_ASSERT(ag_map_iter != m_access_group_map.end());
402  ag_map_iter->second->remove_column(name);
403  if (cf->get_id()) {
404  m_column_family_id_map.erase(cf->get_id());
405  m_counter_mask[cf->get_id()] = false;
406  }
407  m_column_family_map.erase(iter);
408  return cf;
409  }
410  return nullptr;
411 }
412 
413 
415  AccessGroupSpec *old_ag {};
416  auto iter = m_access_group_map.find(new_ag->get_name().c_str());
417  if (iter != m_access_group_map.end()) {
418  old_ag = iter->second;
419  m_access_group_map.erase(iter);
420  AccessGroupSpecs new_ags(m_access_groups.size());
421  auto it = copy_if(m_access_groups.begin(), m_access_groups.end(),
422  new_ags.begin(),
423  [old_ag](AccessGroupSpec *ag){return ag != old_ag;});
424  new_ags.resize(distance(new_ags.begin(), it));
425  m_access_groups.swap(new_ags);
426  }
427  add_access_group(new_ag);
428  return old_ag;
429 }
430 
431 bool Schema::column_family_exists(int32_t id, bool get_deleted) const
432 {
433  auto cf_iter = m_column_family_id_map.find(id);
434  if (cf_iter != m_column_family_id_map.end()) {
435  if (get_deleted || !cf_iter->second->get_deleted())
436  return true;
437  }
438  return false;
439 }
440 
441 bool Schema::access_group_exists(const string &name) const
442 {
443  auto ag_iter = m_access_group_map.find(name.c_str());
444  return (ag_iter != m_access_group_map.end());
445 }
446 
447 void Schema::rename_column_family(const string &old_name, const string &new_name) {
448  ColumnFamilySpec *cf;
449 
450  // update key and ColumnFamily in m_column_family_map
451  auto cf_map_it = m_column_family_map.find(old_name.c_str());
452  if (cf_map_it == m_column_family_map.end())
454  "Source column '%s' of rename does not exist", old_name.c_str());
455 
456  if (old_name != new_name) {
457  cf = cf_map_it->second;
458  cf->set_name(new_name);
459  cf->set_generation(0);
460  auto res = m_column_family_map.insert(
461  make_pair(m_arena.dup(cf->get_name()), cf));
462  if (!res.second)
464  "Destination column '%s' of rename already exists",
465  cf->get_name().c_str());
466  m_column_family_map.erase(cf_map_it);
467  }
468 }
469 
470 void Schema::drop_column_family(const string &name) {
471 
472  auto cf_map_it = m_column_family_map.find(name.c_str());
473  if (cf_map_it == m_column_family_map.end())
475  "Column family to drop (%s) does not exist",
476  name.c_str());
477 
478  ColumnFamilySpec *cf = cf_map_it->second;
479 
480  auto ag_it = m_access_group_map.find(cf->get_access_group().c_str());
481  if (ag_it == m_access_group_map.end())
483  "Invalid access group '%s' for column family '%s'",
484  cf->get_access_group().c_str(), cf->get_name().c_str());
485 
486  auto ag_cfs_it = find(ag_it->second->columns().begin(),
487  ag_it->second->columns().end(), cf);
488  if (ag_cfs_it == ag_it->second->columns().end())
490  "Column family '%s' not found in access group '%s'",
491  cf->get_name().c_str(), cf->get_access_group().c_str());
492 
493  auto cfs_it = find(m_column_families.begin(),
494  m_column_families.end(), cf);
495  if (cfs_it == m_column_families.end())
497  "Column family '%s' not found in Schema list of columns",
498  cf->get_name().c_str());
499 
500  ag_it->second->drop_column(name);
501 
502  m_column_family_map.erase(cf_map_it);
503 }
504 
506  size_t column_count {};
507  map<string, string> column_to_ag_map;
508  m_column_families.clear();
509  m_column_family_map.clear();
510  m_column_family_id_map.clear();
511  m_counter_mask.clear();
512  m_counter_mask.resize(256);
513  for (auto ag_spec : m_access_groups) {
514  column_count += ag_spec->columns().size();
515  if (column_count > MAX_COLUMN_ID)
517  "Attempt to add > %d column families to table",
518  MAX_COLUMN_ID);
519  for (auto cf_spec : ag_spec->columns()) {
520  if (cf_spec->get_access_group().empty())
521  cf_spec->set_access_group(ag_spec->get_name());
522  auto iter = column_to_ag_map.find(cf_spec->get_name());
523  if (iter != column_to_ag_map.end())
525  "Column '%s' assigned to two access groups (%s & %s)",
526  cf_spec->get_name().c_str(), iter->second.c_str(),
527  ag_spec->get_name().c_str());
528  column_to_ag_map.insert(make_pair(cf_spec->get_name(), ag_spec->get_name()));
529  m_column_families.push_back(cf_spec);
530  m_column_family_map.insert(make_pair(m_arena.dup(cf_spec->get_name()), cf_spec));
531  if (cf_spec->get_id()) {
532  m_column_family_id_map.insert(make_pair(cf_spec->get_id(), cf_spec));
533  if (cf_spec->get_option_counter())
534  m_counter_mask[cf_spec->get_id()] = true;
535  }
536  }
537  }
538 }
539 
541  try {
542  cf_spec->merge_options(m_cf_defaults);
543  }
544  catch (Exception &e) {
545  HT_THROWF(e.code(), "Merging column '%s' options with table defaults: %s",
546  cf_spec->get_name().c_str(), e.what());
547  }
548 }
549 
551  try {
552  ag_spec->merge_options(m_ag_defaults);
553  }
554  catch (Exception &e) {
555  HT_THROWF(e.code(), "Merging access group '%s' options with table defaults: %s",
556  ag_spec->get_name().c_str(), e.what());
557  }
558 }
ColumnFamilyOptions m_cf_defaults
Default column family options.
Definition: Schema.h:441
Retrieves system information (hardware, installation directory, etc)
void set_default_max_versions(int32_t max_versions)
Sets default max versions column family option.
void parse_xml(const char *base, int len)
Parses XML options document.
void set_default_ttl(time_t ttl)
Sets default ttl column family option.
Schema specification.
Definition: Schema.h:52
#define MAX_COLUMN_ID
Definition: Schema.cc:62
~Schema()
Destructor.
Definition: Schema.cc:130
void set_generation(int64_t generation)
Sets generation.
CstrColumnFamilyMap m_column_family_map
Definition: Schema.h:455
std::string String
A String is simply a typedef to std::string.
Definition: String.h:44
void validate()
Validates schema and reconstructs data structures.
Definition: Schema.cc:505
String format(const char *fmt,...)
Returns a String using printf like format facilities Vanilla snprintf is about 1.5x faster than this...
Definition: String.cc:37
std::vector< AccessGroupSpec * > AccessGroupSpecs
Vector of AccessGroupSpec pointers.
void set_default_counter(bool value)
Sets default counter column family option.
const std::string render_hql() const
Renders options in HQL format.
void parse_xml(const char *base, int len)
Parses XML options specification.
void set_option_bloom_filter(const std::string &bloomfilter)
Sets bloom filter option.
void rename_column_family(const String &old_name, const String &new_name)
Renames a column family.
Definition: Schema.cc:447
void set_option_compressor(const std::string &compressor)
Sets compressor option.
Column family specification.
void set_name(const std::string &name)
Sets column family name.
Specification for column family options.
CharArena m_arena
Definition: Schema.h:426
STL namespace.
ColumnFamilySpecs m_column_families
&Column family specifications
Definition: Schema.h:451
std::map< int32_t, ColumnFamilySpec * > m_column_family_id_map
Map of column family specifications (key == ID)
Definition: Schema.h:458
void set_generation(int64_t generation)
Sets generation.
std::map< const char *, AccessGroupSpec *, LtCstr, CstrAlloc > CstrAccessGroupMap
Map of access group specifications.
Definition: Schema.h:447
Specification for access group options.
Represents a set of table parts (sub-tables).
Definition: TableParts.h:47
const std::string render_xml(const std::string &line_prefix, bool with_ids=false) const
Renders access group specification in XML format.
Declarations for Schema.
AccessGroupSpecs & get_access_groups()
Returns reference to access group vector.
Definition: Schema.h:234
CstrAccessGroupMap m_access_group_map
Definition: Schema.h:448
#define HT_ASSERT(_e_)
Definition: Logger.h:396
std::map< const char *, ColumnFamilySpec *, LtCstr, CstrAlloc > CstrColumnFamilyMap
Map of column family specifications (key == name)
Definition: Schema.h:454
void drop_column_family(const String &name)
Drops column family.
Definition: Schema.cc:470
File system utility functions.
CharT * dup(const CharT *s)
Duplicate a null terminated string; memory is allocated from the pool.
Definition: PageArena.h:274
void parse_xml(const char *base, int len)
Parses XML access group specification.
TableParts get_table_parts()
Gets table parts.
Definition: Schema.cc:337
bool access_group_exists(const std::string &name) const
Checks if access group exists.
Definition: Schema.cc:441
void merge_options(const ColumnFamilyOptions &other)
Merges options from another ColumnFamilyOptions object.
Definitions for XmlParser.
const std::string & get_name() const
Gets access group name.
const std::string render_xml(const std::string &line_prefix) const
Renders options in XML format.
AccessGroupSpec * get_access_group(const std::string &name)
Gets an access group specification given its name.
Definition: Schema.h:242
Logging routines and macros.
void merge_options(const AccessGroupOptions &options)
Merges options with those from another AccessGroupOptions object.
AccessGroupOptions m_ag_defaults
Default access group options.
Definition: Schema.h:438
STL Strict Weak Ordering for comparing c-style strings.
Definition: StringExt.h:45
Compatibility Macros for C/C++.
int32_t m_version
Version number.
Definition: Schema.h:432
const std::string & get_access_group() const
Gets access group name.
int32_t get_id() const
Gets column ID.
const std::string render_hql() const
Renders options in HQL format.
Access group specification.
bool clear_generation_if_changed(Schema &original)
Clears generation if different than original.
Definition: Schema.cc:223
Hypertable definitions
static Schema * new_instance(const std::string &buf)
Creates schema object from XML schema string.
Definition: Schema.cc:202
const std::string & get_name() const
Gets column family name.
long long int Lld
Shortcut for printf formats.
Definition: String.h:53
void add_access_group(AccessGroupSpec *ag)
Adds access group specification.
Definition: Schema.cc:354
AccessGroupSpecs m_access_groups
Access group specifications.
Definition: Schema.h:444
bool column_family_exists(int32_t id, bool get_deleted=false) const
Checks if column family exists.
Definition: Schema.cc:431
std::vector< bool > m_counter_mask
Bitmask describing which column families are counters.
Definition: Schema.h:461
Base class for XML document parsers.
Definition: XmlParser.h:94
ColumnFamilySpecs & columns()
Returns reference to column specifications.
void set_option_in_memory(bool value)
Sets in memory option.
#define HT_THROWF(_code_, _fmt_,...)
Definition: Error.h:490
void merge_table_defaults(ColumnFamilySpec *cf_spec)
Merges default column family options into a column family spec.
Definition: Schema.cc:540
void clear_generation()
Clears generation values.
Definition: Schema.cc:216
const std::string render_hql(const std::string &table_name)
Renders schema as HQL CREATE TABLE statement.
Definition: Schema.cc:292
This is a generic exception class for Hypertable.
Definition: Error.h:314
AccessGroupSpec * replace_access_group(AccessGroupSpec *new_ag)
Replaces access group specification.
Definition: Schema.cc:414
const std::string render_xml(const std::string &line_prefix) const
Renders options in XML format.
PageArenaAllocator< const char * > CstrAlloc
Definition: Schema.h:425
int32_t get_max_column_family_id()
Gets the maximum column family ID.
Definition: Schema.cc:328
int32_t m_group_commit_interval
Group commit interval.
Definition: Schema.h:435
Configuration settings.
Schema()
Default constructor.
Definition: Schema.h:56
void set_default_time_order_desc(bool value)
Sets default time order desc column family option.
int64_t m_generation
Generation.
Definition: Schema.h:429
String extensions and helpers: sets, maps, append operators etc.
void set_option_replication(int16_t replication)
Sets replication option.
void add_column(ColumnFamilySpec *cf)
Adds column family specification.
ColumnFamilySpec * remove_column_family(const std::string &name)
Removes column family.
Definition: Schema.cc:396
const std::string render_xml(bool with_ids=false)
Renders schema in XML format.
Definition: Schema.cc:265
int code() const
Returns the error code.
Definition: Error.h:391
void update_generation(int64_t generation)
Updates generation and assigns column family IDs.
Definition: Schema.cc:244
void set_option_blocksize(int32_t blocksize)
Sets blocksize option.
const std::string render_hql() const
Renders access group specification in HQL format.