mirror of
https://github.com/typesense/typesense.git
synced 2025-05-25 16:26:38 +08:00
Merge branch 'v0.24.1' into v0.25
This commit is contained in:
commit
8d9825617b
@ -738,6 +738,11 @@ Option<bool> field::flatten_field(nlohmann::json& doc, nlohmann::json& obj, cons
|
||||
// end of path: check if obj matches expected type
|
||||
std::string detected_type;
|
||||
if(!field::get_type(obj, detected_type)) {
|
||||
if(obj.is_null() && the_field.optional) {
|
||||
// null values are allowed only if field is optional
|
||||
return Option<bool>(false);
|
||||
}
|
||||
|
||||
return Option<bool>(400, "Field `" + the_field.name + "` has an incorrect type.");
|
||||
}
|
||||
|
||||
|
@ -5691,6 +5691,10 @@ Option<uint32_t> Index::coerce_string(const DIRTY_VALUES& dirty_values, const st
|
||||
else {
|
||||
if(dirty_values == DIRTY_VALUES::COERCE_OR_DROP) {
|
||||
if(!a_field.optional) {
|
||||
if(a_field.nested && item.is_array()) {
|
||||
return Option<>(400, "Field `" + field_name + "` has an incorrect type. "
|
||||
"Hint: field inside an array of objects must be an array type as well.");
|
||||
}
|
||||
return Option<>(400, "Field `" + field_name + "` must be " + suffix + " string.");
|
||||
}
|
||||
|
||||
@ -5702,6 +5706,10 @@ Option<uint32_t> Index::coerce_string(const DIRTY_VALUES& dirty_values, const st
|
||||
}
|
||||
} else {
|
||||
// COERCE_OR_REJECT / non-optional + DROP
|
||||
if(a_field.nested && item.is_array()) {
|
||||
return Option<>(400, "Field `" + field_name + "` has an incorrect type. "
|
||||
"Hint: field inside an array of objects must be an array type as well.");
|
||||
}
|
||||
return Option<>(400, "Field `" + field_name + "` must be " + suffix + " string.");
|
||||
}
|
||||
}
|
||||
|
@ -1390,7 +1390,8 @@ TEST_F(CollectionNestedFieldsTest, ExplicitSchemaOptionalFieldValidation) {
|
||||
"fields": [
|
||||
{"name": "details", "type": "object", "optional": true },
|
||||
{"name": "company.name", "type": "string", "optional": true },
|
||||
{"name": "locations", "type": "object[]", "optional": true }
|
||||
{"name": "locations", "type": "object[]", "optional": true },
|
||||
{"name": "blocks.text.description", "type": "string[]", "optional": true }
|
||||
]
|
||||
})"_json;
|
||||
|
||||
@ -1398,14 +1399,31 @@ TEST_F(CollectionNestedFieldsTest, ExplicitSchemaOptionalFieldValidation) {
|
||||
ASSERT_TRUE(op.ok());
|
||||
Collection* coll1 = op.get();
|
||||
|
||||
// no optional field is present and that should be allowed
|
||||
// when a nested field is null it should be allowed
|
||||
auto doc1 = R"({
|
||||
"foo": "bar"
|
||||
"company": {"name": null}
|
||||
})"_json;
|
||||
|
||||
auto add_op = coll1->add(doc1.dump(), CREATE);
|
||||
ASSERT_TRUE(add_op.ok());
|
||||
|
||||
// check the same with nested array type
|
||||
|
||||
doc1 = R"({
|
||||
"blocks": {"text": [{"description": null}]}
|
||||
})"_json;
|
||||
|
||||
add_op = coll1->add(doc1.dump(), CREATE);
|
||||
ASSERT_TRUE(add_op.ok());
|
||||
|
||||
// no optional field is present and that should be allowed
|
||||
doc1 = R"({
|
||||
"foo": "bar"
|
||||
})"_json;
|
||||
|
||||
add_op = coll1->add(doc1.dump(), CREATE);
|
||||
ASSERT_TRUE(add_op.ok());
|
||||
|
||||
// some parts of an optional field is present in a subsequent doc indexed
|
||||
auto doc2 = R"({
|
||||
"details": {"name": "foo"}
|
||||
@ -1421,12 +1439,37 @@ TEST_F(CollectionNestedFieldsTest, ExplicitSchemaOptionalFieldValidation) {
|
||||
|
||||
// check fields and their properties
|
||||
auto coll_fields = coll1->get_fields();
|
||||
ASSERT_EQ(5, coll_fields.size());
|
||||
ASSERT_EQ(6, coll_fields.size());
|
||||
for(auto& coll_field : coll_fields) {
|
||||
ASSERT_TRUE(coll_field.optional);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(CollectionNestedFieldsTest, ExplicitSchemaForNestedArrayTypeValidation) {
|
||||
nlohmann::json schema = R"({
|
||||
"name": "coll1",
|
||||
"enable_nested_fields": true,
|
||||
"fields": [
|
||||
{"name": "blocks.text", "type": "object[]"},
|
||||
{"name": "blocks.text.description", "type": "string"}
|
||||
]
|
||||
})"_json;
|
||||
|
||||
auto op = collectionManager.create_collection(schema);
|
||||
ASSERT_TRUE(op.ok());
|
||||
Collection* coll1 = op.get();
|
||||
|
||||
auto doc1 = R"({
|
||||
"blocks": {"text": [{"description": "Hello world."}]}
|
||||
})"_json;
|
||||
|
||||
auto add_op = coll1->add(doc1.dump(), CREATE);
|
||||
|
||||
ASSERT_FALSE(add_op.ok());
|
||||
ASSERT_EQ("Field `blocks.text.description` has an incorrect type. "
|
||||
"Hint: field inside an array of objects must be an array type as well.", add_op.error());
|
||||
}
|
||||
|
||||
TEST_F(CollectionNestedFieldsTest, SortByNestedField) {
|
||||
nlohmann::json schema = R"({
|
||||
"name": "coll1",
|
||||
|
Loading…
x
Reference in New Issue
Block a user