From 07e4286f9e656d2ba35b7019981965070075807a Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Fri, 5 Jun 2015 11:24:36 +0300 Subject: [PATCH] cql3: Make 'create table' include columns in schema_ptr Make 'create table' statements also specify the following for schema_ptrs: - Partition keys - Regular columns - Static columns Please note that clustering keys are _not_ included because we seem to lack infrastructure like CompoundType and CellNameType to properly enable them. Signed-off-by: Pekka Enberg --- cql3/statements/create_table_statement.cc | 46 +++++----- cql3/statements/create_table_statement.hh | 104 ++++++++++++---------- 2 files changed, 82 insertions(+), 68 deletions(-) diff --git a/cql3/statements/create_table_statement.cc b/cql3/statements/create_table_statement.cc index 9383a35340..89334d5941 100644 --- a/cql3/statements/create_table_statement.cc +++ b/cql3/statements/create_table_statement.cc @@ -67,23 +67,19 @@ void create_table_statement::validate(service::storage_proxy&, const service::cl // validated in announceMigration() } -#if 0 // Column definitions -private List getColumns(CFMetaData cfm) +std::vector create_table_statement::get_columns() { - List columnDefs = new ArrayList<>(columns.size()); - Integer componentIndex = comparator.isCompound() ? comparator.clusteringPrefixSize() : null; - for (Map.Entry col : columns.entrySet()) - { - ColumnIdentifier id = col.getKey(); - columnDefs.add(staticColumns.contains(id) - ? ColumnDefinition.staticDef(cfm, col.getKey().bytes, col.getValue(), componentIndex) - : ColumnDefinition.regularDef(cfm, col.getKey().bytes, col.getValue(), componentIndex)); + std::vector column_defs; + for (auto&& col : _columns) { + column_kind kind = column_kind::regular_column; + if (_static_columns.count(col.first)) { + kind = column_kind::static_column; + } + column_defs.emplace_back(col.first->name(), col.second, kind); } - - return columnDefs; + return column_defs; } -#endif future create_table_statement::announce_migration(service::storage_proxy& proxy, bool is_local_only) { return service::migration_manager::announce_new_column_family(proxy, get_cf_meta_data(), is_local_only).then_wrapped([this] (auto&& f) { @@ -117,13 +113,19 @@ schema_ptr create_table_statement::get_cf_meta_data() { } void create_table_statement::apply_properties_to(schema_builder& builder) { + auto&& columns = get_columns(); + for (auto&& column : columns) { + builder.with_column(column); + } #if 0 cfmd.defaultValidator(defaultValidator) .keyValidator(keyValidator) .addAllColumnDefinitions(getColumns(cfmd)) .isDense(isDense); +#endif - addColumnMetadataFromAliases(cfmd, keyAliases, keyValidator, ColumnDefinition.Kind.PARTITION_KEY); + add_column_metadata_from_aliases(builder, _key_aliases, _key_validator, column_kind::partition_key); +#if 0 addColumnMetadataFromAliases(cfmd, columnAliases, comparator.asAbstractType(), ColumnDefinition.Kind.CLUSTERING_COLUMN); if (valueAlias != null) addColumnMetadataFromAliases(cfmd, Collections.singletonList(valueAlias), defaultValidator, ColumnDefinition.Kind.COMPACT_VALUE); @@ -132,9 +134,9 @@ void create_table_statement::apply_properties_to(schema_builder& builder) { _properties->apply_to_builder(builder); } -#if 0 -private void addColumnMetadataFromAliases(CFMetaData cfm, List aliases, AbstractType comparator, ColumnDefinition.Kind kind) +void create_table_statement::add_column_metadata_from_aliases(schema_builder& builder, std::vector aliases, data_type comparator, column_kind kind) { +#if 0 if (comparator instanceof CompositeType) { CompositeType ct = (CompositeType)comparator; @@ -144,12 +146,14 @@ private void addColumnMetadataFromAliases(CFMetaData cfm, List alias } else { - assert aliases.size() <= 1; - if (!aliases.isEmpty() && aliases.get(0) != null) - cfm.addOrReplaceColumnDefinition(new ColumnDefinition(cfm, aliases.get(0), comparator, null, kind)); - } -} #endif + assert(aliases.size() <= 1); + if (!aliases.empty()) + builder.with_column(aliases[0], comparator, kind); +#if 0 + } +#endif +} } diff --git a/cql3/statements/create_table_statement.hh b/cql3/statements/create_table_statement.hh index 18d34c46b8..f2873bbba5 100644 --- a/cql3/statements/create_table_statement.hh +++ b/cql3/statements/create_table_statement.hh @@ -51,16 +51,17 @@ class create_table_statement : public schema_altering_statement { private: #if 0 private AbstractType defaultValidator; - private AbstractType keyValidator; - - private final List keyAliases = new ArrayList(); +#endif + data_type _key_validator; + std::vector _key_aliases; +#if 0 private final List columnAliases = new ArrayList(); private ByteBuffer valueAlias; private boolean isDense; - - private final Map columns = new HashMap(); #endif + + std::map<::shared_ptr, data_type> _columns; const std::set<::shared_ptr> _static_columns; const ::shared_ptr _properties; const bool _if_not_exists; @@ -80,9 +81,15 @@ public: schema_ptr get_cf_meta_data(); + class raw_statement; + + friend raw_statement; +private: + std::vector get_columns(); + void apply_properties_to(schema_builder& builder); - class raw_statement; + void add_column_metadata_from_aliases(schema_builder& builder, std::vector aliases, data_type comparator, column_kind kind); }; class create_table_statement::raw_statement : public cf_statement { @@ -122,39 +129,39 @@ public: auto stmt = ::make_shared(_cf_name, properties, _if_not_exists, _static_columns); -#if 0 - Map definedMultiCellCollections = null; - for (Map.Entry entry : definitions.entrySet()) - { - ColumnIdentifier id = entry.getKey(); - CQL3Type pt = entry.getValue().prepare(keyspace()); - if (pt.isCollection() && ((CollectionType) pt.getType()).isMultiCell()) - { - if (definedMultiCellCollections == null) - definedMultiCellCollections = new HashMap<>(); - definedMultiCellCollections.put(id.bytes, (CollectionType) pt.getType()); + std::map defined_multi_cell_collections; + for (auto&& entry : _definitions) { + ::shared_ptr id = entry.first; + ::shared_ptr pt = entry.second->prepare(db, keyspace()); + if (pt->is_collection() && pt->get_type()->is_multi_cell()) { + defined_multi_cell_collections.emplace(id->name(), pt->get_type()); } - stmt.columns.put(id, pt.getType()); // we'll remove what is not a column below + stmt->_columns.emplace(id, pt->get_type()); // we'll remove what is not a column below + } + if (_key_aliases.empty()) { + throw exceptions::invalid_request_exception("No PRIMARY KEY specifed (exactly one required)"); + } else if (_key_aliases.size() > 1) { + throw exceptions::invalid_request_exception("Multiple PRIMARY KEYs specifed (exactly one required)"); } - if (keyAliases.isEmpty()) - throw new InvalidRequestException("No PRIMARY KEY specifed (exactly one required)"); - else if (keyAliases.size() > 1) - throw new InvalidRequestException("Multiple PRIMARY KEYs specifed (exactly one required)"); - - List kAliases = keyAliases.get(0); - - List> keyTypes = new ArrayList>(kAliases.size()); - for (ColumnIdentifier alias : kAliases) - { - stmt.keyAliases.add(alias.bytes); - AbstractType t = getTypeAndRemove(stmt.columns, alias); - if (t instanceof CounterColumnType) - throw new InvalidRequestException(String.format("counter type is not supported for PRIMARY KEY part %s", alias)); - if (staticColumns.contains(alias)) - throw new InvalidRequestException(String.format("Static column %s cannot be part of the PRIMARY KEY", alias)); - keyTypes.add(t); + auto& key_aliases = _key_aliases[0]; + std::vector key_types; + for (auto&& alias : key_aliases) { + stmt->_key_aliases.emplace_back(alias->name()); + auto t = get_type_and_remove(stmt->_columns, alias); + if (t->is_counter()) { + throw exceptions::invalid_request_exception(sprint("counter type is not supported for PRIMARY KEY part %s", alias->text())); + } + if (_static_columns.count(alias) > 0) { + throw exceptions::invalid_request_exception(sprint("Static column %s cannot be part of the PRIMARY KEY", alias->text())); + } + key_types.emplace_back(t); } + if (key_types.size() > 1) { + throw std::runtime_error("compound key types are not supported"); + } + stmt->_key_validator = key_types[0]; +#if 0 stmt.keyValidator = keyTypes.size() == 1 ? keyTypes.get(0) : CompositeType.getInstance(keyTypes); // Dense means that no part of the comparator stores a CQL column name. This means @@ -305,20 +312,23 @@ public: return ::make_shared(stmt); } -#if 0 - private AbstractType getTypeAndRemove(Map columns, ColumnIdentifier t) throws InvalidRequestException - { - AbstractType type = columns.get(t); - if (type == null) - throw new InvalidRequestException(String.format("Unknown definition %s referenced in PRIMARY KEY", t)); - if (type.isCollection() && type.isMultiCell()) - throw new InvalidRequestException(String.format("Invalid collection type for PRIMARY KEY component %s", t)); - - columns.remove(t); - Boolean isReversed = definedOrdering.get(t); - return isReversed != null && isReversed ? ReversedType.getInstance(type) : type; + data_type get_type_and_remove(std::map<::shared_ptr, data_type>& columns, ::shared_ptr t) + { + if (columns.count(t) == 0) { + throw exceptions::invalid_request_exception(sprint("Unknown definition %s referenced in PRIMARY KEY", t->text())); } + auto type = columns.at(t); + if (type->is_collection() && type->is_multi_cell()) { + throw exceptions::invalid_request_exception(sprint("Invalid collection type for PRIMARY KEY component %s", t->text())); + } + columns.erase(t); +#if 0 + // FIXME: reversed types are not supported + Boolean isReversed = definedOrdering.get(t); + return isReversed != null && isReversed ? ReversedType.getInstance(type) : type; #endif + return type; + } void add_definition(::shared_ptr def, ::shared_ptr type, bool is_static) { _defined_names.emplace(def);