mirror of
https://github.com/scylladb/scylladb.git
synced 2026-04-19 16:15:07 +00:00
alternator: prevent adding GSI conflicting with a vector index
All the "indexes" we implement in Alternator - GSI, LSI and the new vector index - share the same IndexName namespace, which we'll use in Query to refer to the index. In the previous patch we already prevented adding a vector index with the same name as an existing GSI or LSI. In this patch we also prevent the reverse - adding a GSI with the name of an existing vector index. Additionally, one cannot add a GSI on a key that is already the key of a vector index: The types conflict: The key of a vector index must be a vector column, while the key of a GSI must have a standard key type (string, binary or number). We have tests for this later, this the big test patch.
This commit is contained in:
@@ -2246,17 +2246,20 @@ future<executor::request_return_type> executor::create_table(client_state& clien
|
||||
// columns of the base table or any of its prior GSIs or LSIs, the type
|
||||
// given in AttributeDefinitions must match the type of the existing key -
|
||||
// otherwise Alternator will not know which type to enforce in new writes.
|
||||
// Also, if the table already has vector indexes, their key attributes cannot
|
||||
// be redefined in AttributeDefinitions with a non-vector type.
|
||||
// This function checks for such conflicts. It assumes that the structure of
|
||||
// the given attribute_definitions was already validated (with
|
||||
// validate_attribute_definitions()).
|
||||
// This function should be called multiple times - once for the base schema
|
||||
// and once for each of its views (existing GSIs and LSIs on this table).
|
||||
static void check_attribute_definitions_conflicts(const rjson::value& attribute_definitions, const schema& schema) {
|
||||
for (auto& def : schema.primary_key_columns()) {
|
||||
std::string def_type = type_to_string(def.type);
|
||||
for (auto it = attribute_definitions.Begin(); it != attribute_definitions.End(); ++it) {
|
||||
const rjson::value& attribute_info = *it;
|
||||
if (rjson::to_string_view(attribute_info["AttributeName"]) == def.name_as_text()) {
|
||||
for (auto it = attribute_definitions.Begin(); it != attribute_definitions.End(); ++it) {
|
||||
const rjson::value& attribute_info = *it;
|
||||
std::string_view attribute_name = rjson::to_string_view(attribute_info["AttributeName"]);
|
||||
for (auto& def : schema.primary_key_columns()) {
|
||||
if (attribute_name == def.name_as_text()) {
|
||||
auto def_type = type_to_string(def.type);
|
||||
std::string_view type = rjson::to_string_view(attribute_info["AttributeType"]);
|
||||
if (type != def_type) {
|
||||
throw api_error::validation(fmt::format("AttributeDefinitions redefined {} to {} already a key attribute of type {} in this table", def.name_as_text(), type, def_type));
|
||||
@@ -2264,6 +2267,12 @@ future<executor::request_return_type> executor::create_table(client_state& clien
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Additionally, if we have a vector index, its key attribute is
|
||||
// required to have a vector type, and cannot be listed in
|
||||
// AttributeDefinitions with a non-vector key type.
|
||||
if (has_vector_index_on_attribute(schema, attribute_name)) {
|
||||
throw api_error::validation(fmt::format("AttributeDefinitions redefines {} but already a key of a vector index in this table", attribute_name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2522,6 +2531,10 @@ future<executor::request_return_type> executor::update_table(client_state& clien
|
||||
co_return api_error::validation(fmt::format(
|
||||
"LSI {} already exists in table {}, can't use same name for GSI", index_name, table_name));
|
||||
}
|
||||
if (tab->has_index(sstring(index_name))) {
|
||||
co_return api_error::validation(fmt::format(
|
||||
"Vector index {} already exists in table {}, cannot reuse the name for a GSI", index_name, table_name));
|
||||
}
|
||||
try {
|
||||
locator::assert_rf_rack_valid_keyspace(keyspace_name, p.local().local_db().get_token_metadata_ptr(),
|
||||
p.local().local_db().find_keyspace(keyspace_name).get_replication_strategy());
|
||||
|
||||
Reference in New Issue
Block a user