From c7a54448e22def86462c6094d6053639f1a6ef41 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Fri, 5 Jun 2015 12:53:39 +0300 Subject: [PATCH 1/4] cql3: Fix cql3_type::raw_type::is_counter() We can simply delegate to the underlying type. Signed-off-by: Pekka Enberg --- cql3/cql3_type.cc | 5 +---- cql3/cql3_type.hh | 1 + 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/cql3/cql3_type.cc b/cql3/cql3_type.cc index ce9f11929e..935fb6ac29 100644 --- a/cql3/cql3_type.cc +++ b/cql3/cql3_type.cc @@ -24,10 +24,7 @@ public: } virtual bool is_counter() const { - throw std::runtime_error("not implemented"); -#if 0 - return type == Native.COUNTER; -#endif + return _type->is_counter(); } virtual sstring to_string() const { diff --git a/cql3/cql3_type.hh b/cql3/cql3_type.hh index 1506fa6726..37710e7e30 100644 --- a/cql3/cql3_type.hh +++ b/cql3/cql3_type.hh @@ -43,6 +43,7 @@ public: cql3_type(sstring name, data_type type, bool native = true) : _name(std::move(name)), _type(std::move(type)), _native(native) {} bool is_collection() const { return _type->is_collection(); } + bool is_counter() const { return _type->is_counter(); } bool is_native() const { return _native; } data_type get_type() const { return _type; } sstring to_string() const { return _name; } From cf6cdc65413c6c46114188cbd7413344db8e6a5e Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Fri, 5 Jun 2015 11:08:50 +0300 Subject: [PATCH 2/4] cql3: Move create_table_statement code out-of-line Move create_table_statement code out-of-line in preparation for modifying the implementation. Signed-off-by: Pekka Enberg --- configure.py | 1 + cql3/statements/create_table_statement.cc | 167 ++++++++++++++++++++++ cql3/statements/create_table_statement.hh | 133 ++--------------- 3 files changed, 178 insertions(+), 123 deletions(-) create mode 100644 cql3/statements/create_table_statement.cc diff --git a/configure.py b/configure.py index b471349377..6fe795f7ea 100755 --- a/configure.py +++ b/configure.py @@ -383,6 +383,7 @@ urchin_core = (['database.cc', 'cql3/maps.cc', 'cql3/functions/functions.cc', 'cql3/statements/cf_prop_defs.cc', + 'cql3/statements/create_table_statement.cc', 'cql3/statements/schema_altering_statement.cc', 'cql3/statements/modification_statement.cc', 'cql3/statements/update_statement.cc', diff --git a/cql3/statements/create_table_statement.cc b/cql3/statements/create_table_statement.cc new file mode 100644 index 0000000000..74e2ee53f8 --- /dev/null +++ b/cql3/statements/create_table_statement.cc @@ -0,0 +1,167 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Copyright 2015 Cloudius Systems + * + * Modified by Cloudius Systems + */ + +#include "cql3/statements/create_table_statement.hh" + +namespace cql3 { + +namespace statements { + +create_table_statement::create_table_statement(::shared_ptr name, + ::shared_ptr properties, + bool if_not_exists, + std::set<::shared_ptr> static_columns) + : schema_altering_statement{name} + , _static_columns{static_columns} + , _properties{properties} + , _if_not_exists{if_not_exists} +{ +#if 0 + try + { + if (!this.properties.hasProperty(CFPropDefs.KW_COMPRESSION) && CFMetaData.DEFAULT_COMPRESSOR != null) + this.properties.addProperty(CFPropDefs.KW_COMPRESSION, + new HashMap() + {{ + put(CompressionParameters.SSTABLE_COMPRESSION, CFMetaData.DEFAULT_COMPRESSOR); + }}); + } + catch (SyntaxException e) + { + throw new AssertionError(e); + } +#endif +} + +void create_table_statement::check_access(const service::client_state& state) { + warn(unimplemented::cause::PERMISSIONS); +#if 0 + state.hasKeyspaceAccess(keyspace(), Permission.CREATE); +#endif +} + +void create_table_statement::validate(service::storage_proxy&, const service::client_state& state) { + // validated in announceMigration() +} + +#if 0 +// Column definitions +private List getColumns(CFMetaData cfm) +{ + 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)); + } + + return columnDefs; +} +#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) { + try { + f.get(); + return true; + } catch (const exceptions::already_exists_exception& e) { + if (_if_not_exists) { + return false; + } + throw e; + } + }); +} + +shared_ptr create_table_statement::change_event() { + return make_shared(transport::event::schema_change::change_type::CREATED, transport::event::schema_change::target_type::TABLE, keyspace(), column_family()); +} + +/** + * Returns a CFMetaData instance based on the parameters parsed from this + * CREATE statement, or defaults where applicable. + * + * @return a CFMetaData instance corresponding to the values parsed from this statement + * @throws InvalidRequestException on failure to validate parsed parameters + */ +schema_ptr create_table_statement::get_cf_meta_data() { + auto s = make_lw_shared(schema({}, keyspace(), column_family(), + // partition key + {}, + // clustering key + {}, + // regular columns + {}, + // static columns + {}, + // regular column name type + utf8_type, + // comment + "" + )); + apply_properties_to(s.get()); + return s; +} + +void create_table_statement::apply_properties_to(schema* s) { +#if 0 + cfmd.defaultValidator(defaultValidator) + .keyValidator(keyValidator) + .addAllColumnDefinitions(getColumns(cfmd)) + .isDense(isDense); + + addColumnMetadataFromAliases(cfmd, keyAliases, keyValidator, ColumnDefinition.Kind.PARTITION_KEY); + addColumnMetadataFromAliases(cfmd, columnAliases, comparator.asAbstractType(), ColumnDefinition.Kind.CLUSTERING_COLUMN); + if (valueAlias != null) + addColumnMetadataFromAliases(cfmd, Collections.singletonList(valueAlias), defaultValidator, ColumnDefinition.Kind.COMPACT_VALUE); +#endif + + _properties->apply_to_schema(s); +} + +#if 0 +private void addColumnMetadataFromAliases(CFMetaData cfm, List aliases, AbstractType comparator, ColumnDefinition.Kind kind) +{ + if (comparator instanceof CompositeType) + { + CompositeType ct = (CompositeType)comparator; + for (int i = 0; i < aliases.size(); ++i) + if (aliases.get(i) != null) + cfm.addOrReplaceColumnDefinition(new ColumnDefinition(cfm, aliases.get(i), ct.types.get(i), i, kind)); + } + else + { + assert aliases.size() <= 1; + if (!aliases.isEmpty() && aliases.get(0) != null) + cfm.addOrReplaceColumnDefinition(new ColumnDefinition(cfm, aliases.get(0), comparator, null, kind)); + } +} +#endif + +} + +} diff --git a/cql3/statements/create_table_statement.hh b/cql3/statements/create_table_statement.hh index e81e78fb90..30b4fc19a6 100644 --- a/cql3/statements/create_table_statement.hh +++ b/cql3/statements/create_table_statement.hh @@ -65,136 +65,23 @@ private: const ::shared_ptr _properties; const bool _if_not_exists; public: - create_table_statement(::shared_ptr name, ::shared_ptr properties, bool if_not_exists, std::set<::shared_ptr> static_columns) - : schema_altering_statement{name} - , _static_columns{static_columns} - , _properties{properties} - , _if_not_exists{if_not_exists} - { -#if 0 - try - { - if (!this.properties.hasProperty(CFPropDefs.KW_COMPRESSION) && CFMetaData.DEFAULT_COMPRESSOR != null) - this.properties.addProperty(CFPropDefs.KW_COMPRESSION, - new HashMap() - {{ - put(CompressionParameters.SSTABLE_COMPRESSION, CFMetaData.DEFAULT_COMPRESSOR); - }}); - } - catch (SyntaxException e) - { - throw new AssertionError(e); - } -#endif - } + create_table_statement(::shared_ptr name, + ::shared_ptr properties, + bool if_not_exists, + std::set<::shared_ptr> static_columns); - virtual void check_access(const service::client_state& state) override { - warn(unimplemented::cause::PERMISSIONS); -#if 0 - state.hasKeyspaceAccess(keyspace(), Permission.CREATE); -#endif - } + virtual void check_access(const service::client_state& state) override; - virtual void validate(service::storage_proxy&, const service::client_state& state) override { - // validated in announceMigration() - } + virtual void validate(service::storage_proxy&, const service::client_state& state) override; -#if 0 - // Column definitions - private List getColumns(CFMetaData cfm) - { - 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)); - } + virtual future announce_migration(service::storage_proxy& proxy, bool is_local_only) override; - return columnDefs; - } -#endif + virtual shared_ptr change_event() override; - virtual future announce_migration(service::storage_proxy& proxy, bool is_local_only) override { - return service::migration_manager::announce_new_column_family(proxy, get_cf_meta_data(), is_local_only).then_wrapped([this] (auto&& f) { - try { - f.get(); - return true; - } catch (const exceptions::already_exists_exception& e) { - if (_if_not_exists) { - return false; - } - throw e; - } - }); - } + schema_ptr get_cf_meta_data(); - virtual shared_ptr change_event() override { - return make_shared(transport::event::schema_change::change_type::CREATED, transport::event::schema_change::target_type::TABLE, keyspace(), column_family()); - } + void apply_properties_to(schema* s); - /** - * Returns a CFMetaData instance based on the parameters parsed from this - * CREATE statement, or defaults where applicable. - * - * @return a CFMetaData instance corresponding to the values parsed from this statement - * @throws InvalidRequestException on failure to validate parsed parameters - */ - schema_ptr get_cf_meta_data() { - auto s = make_lw_shared(schema({}, keyspace(), column_family(), - // partition key - {}, - // clustering key - {}, - // regular columns - {}, - // static columns - {}, - // regular column name type - utf8_type, - // comment - "" - )); - apply_properties_to(s.get()); - return s; - } - - void apply_properties_to(schema* s) { -#if 0 - cfmd.defaultValidator(defaultValidator) - .keyValidator(keyValidator) - .addAllColumnDefinitions(getColumns(cfmd)) - .isDense(isDense); - - addColumnMetadataFromAliases(cfmd, keyAliases, keyValidator, ColumnDefinition.Kind.PARTITION_KEY); - addColumnMetadataFromAliases(cfmd, columnAliases, comparator.asAbstractType(), ColumnDefinition.Kind.CLUSTERING_COLUMN); - if (valueAlias != null) - addColumnMetadataFromAliases(cfmd, Collections.singletonList(valueAlias), defaultValidator, ColumnDefinition.Kind.COMPACT_VALUE); -#endif - - _properties->apply_to_schema(s); - } - -#if 0 - private void addColumnMetadataFromAliases(CFMetaData cfm, List aliases, AbstractType comparator, ColumnDefinition.Kind kind) - { - if (comparator instanceof CompositeType) - { - CompositeType ct = (CompositeType)comparator; - for (int i = 0; i < aliases.size(); ++i) - if (aliases.get(i) != null) - cfm.addOrReplaceColumnDefinition(new ColumnDefinition(cfm, aliases.get(i), ct.types.get(i), i, kind)); - } - else - { - assert aliases.size() <= 1; - if (!aliases.isEmpty() && aliases.get(0) != null) - cfm.addOrReplaceColumnDefinition(new ColumnDefinition(cfm, aliases.get(0), comparator, null, kind)); - } - } -#endif class raw_statement; }; From 4365b8bb694f1fdfa9a9d89289bb9ac70dffb1f2 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Fri, 5 Jun 2015 11:14:04 +0300 Subject: [PATCH 3/4] cql3: Use schema_builder for create table statements Switch to using schema_builder in create_table_statement in preparation for also defining columns in the resulting schema_ptr. Signed-off-by: Pekka Enberg --- cql3/statements/cf_prop_defs.hh | 12 ++++++++++- cql3/statements/create_table_statement.cc | 25 +++++++---------------- cql3/statements/create_table_statement.hh | 2 +- 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/cql3/statements/cf_prop_defs.hh b/cql3/statements/cf_prop_defs.hh index 4f5c4d82f4..6e6a73cdad 100644 --- a/cql3/statements/cf_prop_defs.hh +++ b/cql3/statements/cf_prop_defs.hh @@ -25,8 +25,10 @@ #pragma once #include "cql3/statements/property_definitions.hh" - + #include "schema.hh" +#include "database.hh" +#include "schema_builder.hh" namespace cql3 { @@ -173,6 +175,14 @@ public: } #endif + // Keep this in sync with apply_to_schema(). + void apply_to_builder(schema_builder& builder) { + if (has_property(KW_COMMENT)) { + builder.set_comment(get_string(KW_COMMENT, "")); + } + } + + // Keep this in sync with apply_to_builder(). void apply_to_schema(schema* s) { if (has_property(KW_COMMENT)) { s->set_comment(get_string(KW_COMMENT, "")); diff --git a/cql3/statements/create_table_statement.cc b/cql3/statements/create_table_statement.cc index 74e2ee53f8..9383a35340 100644 --- a/cql3/statements/create_table_statement.cc +++ b/cql3/statements/create_table_statement.cc @@ -24,6 +24,8 @@ #include "cql3/statements/create_table_statement.hh" +#include "schema_builder.hh" + namespace cql3 { namespace statements { @@ -109,25 +111,12 @@ shared_ptr create_table_statement::change_event * @throws InvalidRequestException on failure to validate parsed parameters */ schema_ptr create_table_statement::get_cf_meta_data() { - auto s = make_lw_shared(schema({}, keyspace(), column_family(), - // partition key - {}, - // clustering key - {}, - // regular columns - {}, - // static columns - {}, - // regular column name type - utf8_type, - // comment - "" - )); - apply_properties_to(s.get()); - return s; + schema_builder builder{keyspace(), column_family()}; + apply_properties_to(builder); + return builder.build(); } -void create_table_statement::apply_properties_to(schema* s) { +void create_table_statement::apply_properties_to(schema_builder& builder) { #if 0 cfmd.defaultValidator(defaultValidator) .keyValidator(keyValidator) @@ -140,7 +129,7 @@ void create_table_statement::apply_properties_to(schema* s) { addColumnMetadataFromAliases(cfmd, Collections.singletonList(valueAlias), defaultValidator, ColumnDefinition.Kind.COMPACT_VALUE); #endif - _properties->apply_to_schema(s); + _properties->apply_to_builder(builder); } #if 0 diff --git a/cql3/statements/create_table_statement.hh b/cql3/statements/create_table_statement.hh index 30b4fc19a6..18d34c46b8 100644 --- a/cql3/statements/create_table_statement.hh +++ b/cql3/statements/create_table_statement.hh @@ -80,7 +80,7 @@ public: schema_ptr get_cf_meta_data(); - void apply_properties_to(schema* s); + void apply_properties_to(schema_builder& builder); class raw_statement; }; From 07e4286f9e656d2ba35b7019981965070075807a Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Fri, 5 Jun 2015 11:24:36 +0300 Subject: [PATCH 4/4] 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);