Improve field duplication check logic.

This commit is contained in:
Kishore Nallan 2021-12-21 19:17:43 +05:30
parent 395763563c
commit fee8a2e2fb
2 changed files with 51 additions and 10 deletions

View File

@ -222,10 +222,11 @@ struct field {
bool found_default_sorting_field = false;
// Check for duplicates in field names
std::set<std::string> field_names;
std::map<std::string, std::vector<const field*>> unique_fields;
for(const field & field: fields) {
field_names.insert(field.name);
unique_fields[field.name].push_back(&field);
if(field.name == "id") {
continue;
}
@ -290,10 +291,32 @@ struct field {
"` but is not found in the schema.");
}
if(field_names.size() != fields.size()) {
return Option<bool>(400, "There are duplicate field names in the schema.");
}
// check for duplicate field names in schema
for(auto& fname_fields: unique_fields) {
if(fname_fields.second.size() > 1) {
// if there are more than 1 field with the same field name, then
// a) only 1 field can be of static type
// b) only 1 field can be of dynamic type
size_t num_static = 0;
size_t num_dynamic = 0;
for(const field* f: fname_fields.second) {
if(f->name == ".*" || f->is_dynamic()) {
num_dynamic++;
} else {
num_static++;
}
}
if(num_static != 0 && num_static > 1) {
return Option<bool>(400, "There are duplicate field names in the schema.");
}
if(num_dynamic != 0 && num_dynamic > 1) {
return Option<bool>(400, "There are duplicate field names in the schema.");
}
}
}
return Option<bool>(true);
}

View File

@ -1996,9 +1996,27 @@ TEST_F(CollectionSpecificTest, SingleHyphenInQueryNotToBeTreatedAsExclusion) {
TEST_F(CollectionSpecificTest, DuplicateFieldsNotAllowed) {
std::vector<field> fields = {field("title", field_types::STRING, false),
field("title", field_types::INT32, true),};
Option<Collection*> response = collectionManager.create_collection("collection", 1, fields);
Option<Collection*> create_op = collectionManager.create_collection("collection", 1, fields);
ASSERT_EQ(response.error(), "There are duplicate field names in the schema.");
ASSERT_EQ(response.code(), 400);
ASSERT_FALSE(response.ok());
}
ASSERT_FALSE(create_op.ok());
ASSERT_EQ(create_op.error(), "There are duplicate field names in the schema.");
ASSERT_EQ(create_op.code(), 400);
// with dynamic field
fields = {field("title_.*", field_types::STRING, false, true),
field("title_.*", field_types::INT32, true, true),};
create_op = collectionManager.create_collection("collection", 1, fields);
ASSERT_FALSE(create_op.ok());
ASSERT_EQ(create_op.error(), "There are duplicate field names in the schema.");
ASSERT_EQ(create_op.code(), 400);
// but allow string* with resolved field
fields = {field("title", "string*", false, true),
field("title", field_types::STRING, true),};
create_op = collectionManager.create_collection("collection", 1, fields);
ASSERT_TRUE(create_op.ok());
}