mirror of
https://github.com/typesense/typesense.git
synced 2025-05-19 21:22:25 +08:00
Improve field duplication check logic.
This commit is contained in:
parent
395763563c
commit
fee8a2e2fb
@ -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);
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user