summaryrefslogtreecommitdiff
path: root/src/mongo/db/matcher/schema
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/matcher/schema')
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_max_length.h4
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_min_length.h4
-rw-r--r--src/mongo/db/matcher/schema/expression_internal_schema_object_match_test.cpp3
-rw-r--r--src/mongo/db/matcher/schema/json_pointer_test.cpp10
-rw-r--r--src/mongo/db/matcher/schema/json_schema_parser.cpp151
5 files changed, 80 insertions, 92 deletions
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_max_length.h b/src/mongo/db/matcher/schema/expression_internal_schema_max_length.h
index 342f958679b..232335afb1b 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_max_length.h
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_max_length.h
@@ -43,9 +43,7 @@ public:
}
Validator getComparator() const final {
- return [strLen = strLen()](int lenWithoutNullTerm) {
- return lenWithoutNullTerm <= strLen;
- };
+ return [strLen = strLen()](int lenWithoutNullTerm) { return lenWithoutNullTerm <= strLen; };
}
std::unique_ptr<MatchExpression> shallowClone() const final {
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_min_length.h b/src/mongo/db/matcher/schema/expression_internal_schema_min_length.h
index 0c379a61b23..06388abd044 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_min_length.h
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_min_length.h
@@ -43,9 +43,7 @@ public:
}
Validator getComparator() const final {
- return [strLen = strLen()](int lenWithoutNullTerm) {
- return lenWithoutNullTerm >= strLen;
- };
+ return [strLen = strLen()](int lenWithoutNullTerm) { return lenWithoutNullTerm >= strLen; };
}
std::unique_ptr<MatchExpression> shallowClone() const final {
diff --git a/src/mongo/db/matcher/schema/expression_internal_schema_object_match_test.cpp b/src/mongo/db/matcher/schema/expression_internal_schema_object_match_test.cpp
index 13bc5c47f1c..8eb9332aed7 100644
--- a/src/mongo/db/matcher/schema/expression_internal_schema_object_match_test.cpp
+++ b/src/mongo/db/matcher/schema/expression_internal_schema_object_match_test.cpp
@@ -80,8 +80,7 @@ TEST(InternalSchemaObjectMatchExpression, AcceptsObjectsThatMatch) {
<< "string"))));
ASSERT_TRUE(objMatch.matchesBSON(BSON("a" << BSON("b"
<< "string"
- << "c"
- << 1))));
+ << "c" << 1))));
ASSERT_FALSE(
objMatch.matchesBSON(BSON("a" << BSON_ARRAY(BSON("b" << 1) << BSON("b"
<< "string")))));
diff --git a/src/mongo/db/matcher/schema/json_pointer_test.cpp b/src/mongo/db/matcher/schema/json_pointer_test.cpp
index aed92b17784..f91d8888719 100644
--- a/src/mongo/db/matcher/schema/json_pointer_test.cpp
+++ b/src/mongo/db/matcher/schema/json_pointer_test.cpp
@@ -49,9 +49,8 @@ void assertPointerEvaluatesTo(std::string pointerStr,
}
TEST(JSONPointerTest, ParseInterestingCharacterFields) {
- BSONObj obj = BSON(
- "" << 1 << "c%d" << 2 << "e^f" << 3 << "g|h" << 4 << "i\\\\j" << 5 << "k\"l" << 6 << " "
- << 7);
+ BSONObj obj = BSON("" << 1 << "c%d" << 2 << "e^f" << 3 << "g|h" << 4 << "i\\\\j" << 5 << "k\"l"
+ << 6 << " " << 7);
assertPointerEvaluatesTo("/", obj, "", 1);
assertPointerEvaluatesTo("/c%d", obj, "c%d", 2);
assertPointerEvaluatesTo("/e^f", obj, "e^f", 3);
@@ -129,9 +128,8 @@ TEST(JSONPointerTest, ArrayTraversalTest) {
<< "value2")
<< BSON("builder3"
<< "value3"));
- auto topLevel =
- BSON("transit" << BSON("arrBottom" << arrBottom) << "arrTop" << arrTop << "toBSONArray"
- << bsonArray);
+ auto topLevel = BSON("transit" << BSON("arrBottom" << arrBottom) << "arrTop" << arrTop
+ << "toBSONArray" << bsonArray);
assertPointerEvaluatesTo("/transit/arrBottom/0", topLevel, "0", 0);
assertPointerEvaluatesTo("/toBSONArray/0/builder0", topLevel, "builder0", "value0");
assertPointerEvaluatesTo("/toBSONArray/3/builder3", topLevel, "builder3", "value3");
diff --git a/src/mongo/db/matcher/schema/json_schema_parser.cpp b/src/mongo/db/matcher/schema/json_schema_parser.cpp
index dd51115e276..0608c2389b4 100644
--- a/src/mongo/db/matcher/schema/json_schema_parser.cpp
+++ b/src/mongo/db/matcher/schema/json_schema_parser.cpp
@@ -74,7 +74,12 @@ using findBSONTypeAliasFun = std::function<boost::optional<BSONType>(StringData)
// Explicitly unsupported JSON Schema keywords.
const std::set<StringData> unsupportedKeywords{
- "$ref"_sd, "$schema"_sd, "default"_sd, "definitions"_sd, "format"_sd, "id"_sd,
+ "$ref"_sd,
+ "$schema"_sd,
+ "default"_sd,
+ "definitions"_sd,
+ "format"_sd,
+ "id"_sd,
};
constexpr StringData kNamePlaceholder = "i"_sd;
@@ -176,9 +181,9 @@ StatusWithMatchExpression parseMaximum(StringData path,
bool isExclusiveMaximum) {
if (!maximum.isNumber()) {
return {Status(ErrorCodes::TypeMismatch,
- str::stream() << "$jsonSchema keyword '"
- << JSONSchemaParser::kSchemaMaximumKeyword
- << "' must be a number")};
+ str::stream()
+ << "$jsonSchema keyword '" << JSONSchemaParser::kSchemaMaximumKeyword
+ << "' must be a number")};
}
if (path.empty()) {
@@ -204,9 +209,9 @@ StatusWithMatchExpression parseMinimum(StringData path,
bool isExclusiveMinimum) {
if (!minimum.isNumber()) {
return {Status(ErrorCodes::TypeMismatch,
- str::stream() << "$jsonSchema keyword '"
- << JSONSchemaParser::kSchemaMinimumKeyword
- << "' must be a number")};
+ str::stream()
+ << "$jsonSchema keyword '" << JSONSchemaParser::kSchemaMinimumKeyword
+ << "' must be a number")};
}
if (path.empty()) {
@@ -252,9 +257,9 @@ StatusWithMatchExpression parsePattern(StringData path,
InternalSchemaTypeExpression* typeExpr) {
if (pattern.type() != BSONType::String) {
return {Status(ErrorCodes::TypeMismatch,
- str::stream() << "$jsonSchema keyword '"
- << JSONSchemaParser::kSchemaPatternKeyword
- << "' must be a string")};
+ str::stream()
+ << "$jsonSchema keyword '" << JSONSchemaParser::kSchemaPatternKeyword
+ << "' must be a string")};
}
if (path.empty()) {
@@ -273,16 +278,16 @@ StatusWithMatchExpression parseMultipleOf(StringData path,
InternalSchemaTypeExpression* typeExpr) {
if (!multipleOf.isNumber()) {
return {Status(ErrorCodes::TypeMismatch,
- str::stream() << "$jsonSchema keyword '"
- << JSONSchemaParser::kSchemaMultipleOfKeyword
- << "' must be a number")};
+ str::stream()
+ << "$jsonSchema keyword '" << JSONSchemaParser::kSchemaMultipleOfKeyword
+ << "' must be a number")};
}
if (multipleOf.numberDecimal().isNegative() || multipleOf.numberDecimal().isZero()) {
return {Status(ErrorCodes::FailedToParse,
- str::stream() << "$jsonSchema keyword '"
- << JSONSchemaParser::kSchemaMultipleOfKeyword
- << "' must have a positive value")};
+ str::stream()
+ << "$jsonSchema keyword '" << JSONSchemaParser::kSchemaMultipleOfKeyword
+ << "' must have a positive value")};
}
if (path.empty()) {
return {std::make_unique<AlwaysTrueMatchExpression>()};
@@ -407,7 +412,7 @@ StatusWith<StringDataSet> parseRequired(BSONElement requiredElt) {
<< propertyName.type()};
}
- const auto[it, didInsert] = properties.insert(propertyName.valueStringData());
+ const auto [it, didInsert] = properties.insert(propertyName.valueStringData());
if (!didInsert) {
return {ErrorCodes::FailedToParse,
str::stream() << "$jsonSchema keyword '"
@@ -460,9 +465,9 @@ StatusWithMatchExpression parseProperties(const boost::intrusive_ptr<ExpressionC
bool ignoreUnknownKeywords) {
if (propertiesElt.type() != BSONType::Object) {
return {Status(ErrorCodes::TypeMismatch,
- str::stream() << "$jsonSchema keyword '"
- << JSONSchemaParser::kSchemaPropertiesKeyword
- << "' must be an object")};
+ str::stream()
+ << "$jsonSchema keyword '" << JSONSchemaParser::kSchemaPropertiesKeyword
+ << "' must be an object")};
}
auto propertiesObj = propertiesElt.embeddedObject();
@@ -471,8 +476,7 @@ StatusWithMatchExpression parseProperties(const boost::intrusive_ptr<ExpressionC
if (property.type() != BSONType::Object) {
return {ErrorCodes::TypeMismatch,
str::stream() << "Nested schema for $jsonSchema property '"
- << property.fieldNameStringData()
- << "' must be an object"};
+ << property.fieldNameStringData() << "' must be an object"};
}
auto nestedSchemaMatch = _parse(expCtx,
@@ -534,11 +538,11 @@ StatusWith<std::vector<PatternSchema>> parsePatternProperties(
for (auto&& patternSchema : patternPropertiesElt.embeddedObject()) {
if (patternSchema.type() != BSONType::Object) {
return {Status(ErrorCodes::TypeMismatch,
- str::stream() << "$jsonSchema keyword '"
- << JSONSchemaParser::kSchemaPatternPropertiesKeyword
- << "' has property '"
- << patternSchema.fieldNameStringData()
- << "' which is not an object")};
+ str::stream()
+ << "$jsonSchema keyword '"
+ << JSONSchemaParser::kSchemaPatternPropertiesKeyword
+ << "' has property '" << patternSchema.fieldNameStringData()
+ << "' which is not an object")};
}
// Parse the nested schema using a placeholder as the path, since we intend on using the
@@ -841,11 +845,11 @@ StatusWith<boost::optional<long long>> parseItems(
for (auto subschema : itemsElt.embeddedObject()) {
if (subschema.type() != BSONType::Object) {
return {ErrorCodes::TypeMismatch,
- str::stream() << "$jsonSchema keyword '"
- << JSONSchemaParser::kSchemaItemsKeyword
- << "' requires that each element of the array is an "
- "object, but found a "
- << subschema.type()};
+ str::stream()
+ << "$jsonSchema keyword '" << JSONSchemaParser::kSchemaItemsKeyword
+ << "' requires that each element of the array is an "
+ "object, but found a "
+ << subschema.type()};
}
// We want to make an ExpressionWithPlaceholder for $_internalSchemaMatchArrayIndex,
@@ -896,8 +900,7 @@ StatusWith<boost::optional<long long>> parseItems(
} else {
return {ErrorCodes::TypeMismatch,
str::stream() << "$jsonSchema keyword '" << JSONSchemaParser::kSchemaItemsKeyword
- << "' must be an array or an object, not "
- << itemsElt.type()};
+ << "' must be an array or an object, not " << itemsElt.type()};
}
return startIndexForAdditionalItems;
@@ -1268,8 +1271,7 @@ Status translateScalarKeywords(StringMap<BSONElement>& keywordMap,
return {ErrorCodes::FailedToParse,
str::stream() << "$jsonSchema keyword '" << JSONSchemaParser::kSchemaMaximumKeyword
<< "' must be a present if "
- << JSONSchemaParser::kSchemaExclusiveMaximumKeyword
- << " is present"};
+ << JSONSchemaParser::kSchemaExclusiveMaximumKeyword << " is present"};
}
if (auto minimumElt = keywordMap[JSONSchemaParser::kSchemaMinimumKeyword]) {
@@ -1295,8 +1297,7 @@ Status translateScalarKeywords(StringMap<BSONElement>& keywordMap,
return {ErrorCodes::FailedToParse,
str::stream() << "$jsonSchema keyword '" << JSONSchemaParser::kSchemaMinimumKeyword
<< "' must be a present if "
- << JSONSchemaParser::kSchemaExclusiveMinimumKeyword
- << " is present"};
+ << JSONSchemaParser::kSchemaExclusiveMinimumKeyword << " is present"};
}
return Status::OK();
@@ -1316,10 +1317,8 @@ Status translateEncryptionKeywords(StringMap<BSONElement>& keywordMap,
if (encryptElt && encryptMetadataElt) {
return Status(ErrorCodes::FailedToParse,
str::stream() << "Cannot specify both $jsonSchema keywords '"
- << JSONSchemaParser::kSchemaEncryptKeyword
- << "' and '"
- << JSONSchemaParser::kSchemaEncryptMetadataKeyword
- << "'");
+ << JSONSchemaParser::kSchemaEncryptKeyword << "' and '"
+ << JSONSchemaParser::kSchemaEncryptMetadataKeyword << "'");
}
if (encryptMetadataElt) {
@@ -1389,9 +1388,9 @@ Status validateMetadataKeywords(StringMap<BSONElement>& keywordMap) {
if (auto titleElem = keywordMap[JSONSchemaParser::kSchemaTitleKeyword]) {
if (titleElem.type() != BSONType::String) {
return Status(ErrorCodes::TypeMismatch,
- str::stream() << "$jsonSchema keyword '"
- << JSONSchemaParser::kSchemaTitleKeyword
- << "' must be of type string");
+ str::stream()
+ << "$jsonSchema keyword '" << JSONSchemaParser::kSchemaTitleKeyword
+ << "' must be of type string");
}
}
return Status::OK();
@@ -1446,16 +1445,16 @@ StatusWithMatchExpression _parse(const boost::intrusive_ptr<ExpressionContext>&
<< "' is not currently supported");
} else if (!ignoreUnknownKeywords) {
return Status(ErrorCodes::FailedToParse,
- str::stream() << "Unknown $jsonSchema keyword: "
- << elt.fieldNameStringData());
+ str::stream()
+ << "Unknown $jsonSchema keyword: " << elt.fieldNameStringData());
}
continue;
}
if (it->second) {
return Status(ErrorCodes::FailedToParse,
- str::stream() << "Duplicate $jsonSchema keyword: "
- << elt.fieldNameStringData());
+ str::stream()
+ << "Duplicate $jsonSchema keyword: " << elt.fieldNameStringData());
}
keywordMap[elt.fieldNameStringData()] = elt;
@@ -1472,28 +1471,24 @@ StatusWithMatchExpression _parse(const boost::intrusive_ptr<ExpressionContext>&
if (typeElem && bsonTypeElem) {
return Status(ErrorCodes::FailedToParse,
str::stream() << "Cannot specify both $jsonSchema keywords '"
- << JSONSchemaParser::kSchemaTypeKeyword
- << "' and '"
- << JSONSchemaParser::kSchemaBsonTypeKeyword
- << "'");
+ << JSONSchemaParser::kSchemaTypeKeyword << "' and '"
+ << JSONSchemaParser::kSchemaBsonTypeKeyword << "'");
} else if (typeElem && encryptElem) {
return Status(ErrorCodes::FailedToParse,
- str::stream() << "$jsonSchema keyword '"
- << JSONSchemaParser::kSchemaEncryptKeyword
- << "' cannot be used in conjunction with '"
- << JSONSchemaParser::kSchemaTypeKeyword
- << "', '"
- << JSONSchemaParser::kSchemaEncryptKeyword
- << "' implies type 'bsonType::BinData'");
+ str::stream()
+ << "$jsonSchema keyword '" << JSONSchemaParser::kSchemaEncryptKeyword
+ << "' cannot be used in conjunction with '"
+ << JSONSchemaParser::kSchemaTypeKeyword << "', '"
+ << JSONSchemaParser::kSchemaEncryptKeyword
+ << "' implies type 'bsonType::BinData'");
} else if (bsonTypeElem && encryptElem) {
return Status(ErrorCodes::FailedToParse,
- str::stream() << "$jsonSchema keyword '"
- << JSONSchemaParser::kSchemaEncryptKeyword
- << "' cannot be used in conjunction with '"
- << JSONSchemaParser::kSchemaBsonTypeKeyword
- << "', '"
- << JSONSchemaParser::kSchemaEncryptKeyword
- << "' implies type 'bsonType::BinData'");
+ str::stream()
+ << "$jsonSchema keyword '" << JSONSchemaParser::kSchemaEncryptKeyword
+ << "' cannot be used in conjunction with '"
+ << JSONSchemaParser::kSchemaBsonTypeKeyword << "', '"
+ << JSONSchemaParser::kSchemaEncryptKeyword
+ << "' implies type 'bsonType::BinData'");
}
std::unique_ptr<InternalSchemaTypeExpression> typeExpr;
@@ -1584,25 +1579,25 @@ StatusWith<MatcherTypeSet> JSONSchemaParser::parseTypeSet(
for (auto&& typeArrayEntry : typeElt.embeddedObject()) {
if (typeArrayEntry.type() != BSONType::String) {
return {Status(ErrorCodes::TypeMismatch,
- str::stream() << "$jsonSchema keyword '"
- << typeElt.fieldNameStringData()
- << "' array elements must be strings")};
+ str::stream()
+ << "$jsonSchema keyword '" << typeElt.fieldNameStringData()
+ << "' array elements must be strings")};
}
if (typeArrayEntry.valueStringData() == JSONSchemaParser::kSchemaTypeInteger) {
return {ErrorCodes::FailedToParse,
- str::stream() << "$jsonSchema type '"
- << JSONSchemaParser::kSchemaTypeInteger
- << "' is not currently supported."};
+ str::stream()
+ << "$jsonSchema type '" << JSONSchemaParser::kSchemaTypeInteger
+ << "' is not currently supported."};
}
auto insertionResult = aliases.insert(typeArrayEntry.valueStringData());
if (!insertionResult.second) {
- return {Status(ErrorCodes::FailedToParse,
- str::stream() << "$jsonSchema keyword '"
- << typeElt.fieldNameStringData()
- << "' has duplicate value: "
- << typeArrayEntry.valueStringData())};
+ return {
+ Status(ErrorCodes::FailedToParse,
+ str::stream()
+ << "$jsonSchema keyword '" << typeElt.fieldNameStringData()
+ << "' has duplicate value: " << typeArrayEntry.valueStringData())};
}
}
}