Skip to content

Commit f719f1b

Browse files
mtandreiEvergreen Agent
authored andcommitted
SERVER-50008 Implement basic jsonSchema validation error generation
1 parent d633834 commit f719f1b

13 files changed

+1201
-424
lines changed

src/mongo/db/matcher/SConscript

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ env.Library(
2020
target='expressions',
2121
source=[
2222
'doc_validation_error.cpp',
23+
'doc_validation_util.cpp',
2324
'expression.cpp',
2425
'expression_algo.cpp',
2526
'expression_array.cpp',
@@ -97,6 +98,7 @@ env.Library(
9798
env.CppUnitTest(
9899
target='db_matcher_test',
99100
source=[
101+
'doc_validation_error_json_schema_test.cpp',
100102
'doc_validation_error_test.cpp',
101103
'expression_algo_test.cpp',
102104
'expression_always_boolean_test.cpp',

src/mongo/db/matcher/doc_validation_error.cpp

Lines changed: 175 additions & 74 deletions
Large diffs are not rendered by default.

src/mongo/db/matcher/doc_validation_error_json_schema_test.cpp

Lines changed: 444 additions & 0 deletions
Large diffs are not rendered by default.

src/mongo/db/matcher/doc_validation_error_test.cpp

Lines changed: 148 additions & 135 deletions
Large diffs are not rendered by default.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/**
2+
* Copyright (C) 2020-present MongoDB, Inc.
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the Server Side Public License, version 1,
6+
* as published by MongoDB, Inc.
7+
*
8+
* This program is distributed in the hope that it will be useful,
9+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
* Server Side Public License for more details.
12+
*
13+
* You should have received a copy of the Server Side Public License
14+
* along with this program. If not, see
15+
* <http://www.mongodb.com/licensing/server-side-public-license>.
16+
*
17+
* As a special exception, the copyright holders give permission to link the
18+
* code of portions of this program with the OpenSSL library under certain
19+
* conditions as described in each individual source file and distribute
20+
* linked combinations including the program with the OpenSSL library. You
21+
* must comply with the Server Side Public License in all respects for
22+
* all of the code used other than as permitted herein. If you modify file(s)
23+
* with this exception, you may extend this exception to your version of the
24+
* file(s), but you are not obligated to do so. If you do not wish to do so,
25+
* delete this exception statement from your version. If you delete this
26+
* exception statement from all source files in the program, then also delete
27+
* it in the license file.
28+
*/
29+
30+
#pragma once
31+
32+
#include "mongo/db/matcher/doc_validation_error.h"
33+
#include "mongo/db/matcher/expression_parser.h"
34+
#include "mongo/db/pipeline/expression_context_for_test.h"
35+
#include "mongo/unittest/unittest.h"
36+
37+
namespace mongo::doc_validation_error {
38+
/**
39+
* Utility function which parses a MatchExpression from 'query' and verifies that the error
40+
* generated by the parsed MatchExpression and 'document' matches 'expectedError'.
41+
*/
42+
void verifyGeneratedError(const BSONObj& query,
43+
const BSONObj& document,
44+
const BSONObj& expectedError);
45+
} // namespace mongo::doc_validation_error
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/**
2+
* Copyright (C) 2020-present MongoDB, Inc.
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the Server Side Public License, version 1,
6+
* as published by MongoDB, Inc.
7+
*
8+
* This program is distributed in the hope that it will be useful,
9+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
* Server Side Public License for more details.
12+
*
13+
* You should have received a copy of the Server Side Public License
14+
* along with this program. If not, see
15+
* <http://www.mongodb.com/licensing/server-side-public-license>.
16+
*
17+
* As a special exception, the copyright holders give permission to link the
18+
* code of portions of this program with the OpenSSL library under certain
19+
* conditions as described in each individual source file and distribute
20+
* linked combinations including the program with the OpenSSL library. You
21+
* must comply with the Server Side Public License in all respects for
22+
* all of the code used other than as permitted herein. If you modify file(s)
23+
* with this exception, you may extend this exception to your version of the
24+
* file(s), but you are not obligated to do so. If you do not wish to do so,
25+
* delete this exception statement from your version. If you delete this
26+
* exception statement from all source files in the program, then also delete
27+
* it in the license file.
28+
*/
29+
30+
#include "mongo/db/matcher/doc_validation_util.h"
31+
32+
namespace mongo::doc_validation_error {
33+
std::unique_ptr<MatchExpression::ErrorAnnotation> createAnnotation(
34+
const boost::intrusive_ptr<ExpressionContext>& expCtx,
35+
const std::string& operatorName,
36+
const BSONObj& annotation) {
37+
if (expCtx->isParsingCollectionValidator) {
38+
return std::make_unique<MatchExpression::ErrorAnnotation>(operatorName, annotation);
39+
} else {
40+
return nullptr;
41+
}
42+
}
43+
44+
std::unique_ptr<MatchExpression::ErrorAnnotation> createAnnotation(
45+
const boost::intrusive_ptr<ExpressionContext>& expCtx,
46+
MatchExpression::ErrorAnnotation::Mode mode) {
47+
if (expCtx->isParsingCollectionValidator) {
48+
return std::make_unique<MatchExpression::ErrorAnnotation>(mode);
49+
} else {
50+
return nullptr;
51+
}
52+
}
53+
54+
void annotateTreeToIgnoreForErrorDetails(const boost::intrusive_ptr<ExpressionContext>& expCtx,
55+
MatchExpression* expr) {
56+
expr->setErrorAnnotation(
57+
createAnnotation(expCtx, MatchExpression::ErrorAnnotation::Mode::kIgnore));
58+
for (const auto childExpr : *expr) {
59+
annotateTreeToIgnoreForErrorDetails(expCtx, childExpr);
60+
}
61+
}
62+
} // namespace mongo::doc_validation_error
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/**
2+
* Copyright (C) 2020-present MongoDB, Inc.
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the Server Side Public License, version 1,
6+
* as published by MongoDB, Inc.
7+
*
8+
* This program is distributed in the hope that it will be useful,
9+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
* Server Side Public License for more details.
12+
*
13+
* You should have received a copy of the Server Side Public License
14+
* along with this program. If not, see
15+
* <http://www.mongodb.com/licensing/server-side-public-license>.
16+
*
17+
* As a special exception, the copyright holders give permission to link the
18+
* code of portions of this program with the OpenSSL library under certain
19+
* conditions as described in each individual source file and distribute
20+
* linked combinations including the program with the OpenSSL library. You
21+
* must comply with the Server Side Public License in all respects for
22+
* all of the code used other than as permitted herein. If you modify file(s)
23+
* with this exception, you may extend this exception to your version of the
24+
* file(s), but you are not obligated to do so. If you do not wish to do so,
25+
* delete this exception statement from your version. If you delete this
26+
* exception statement from all source files in the program, then also delete
27+
* it in the license file.
28+
*/
29+
30+
#pragma once
31+
32+
#include "mongo/bson/bsonobj.h"
33+
#include "mongo/db/matcher/expression.h"
34+
#include "mongo/db/pipeline/expression_context.h"
35+
36+
namespace mongo::doc_validation_error {
37+
/**
38+
* Set of functions which create an ErrorAnnotation provided that a validator expression is being
39+
* parsed.
40+
*/
41+
std::unique_ptr<MatchExpression::ErrorAnnotation> createAnnotation(
42+
const boost::intrusive_ptr<ExpressionContext>& expCtx,
43+
const std::string& operatorName,
44+
const BSONObj& annotation);
45+
46+
std::unique_ptr<MatchExpression::ErrorAnnotation> createAnnotation(
47+
const boost::intrusive_ptr<ExpressionContext>& expCtx,
48+
MatchExpression::ErrorAnnotation::Mode mode);
49+
50+
/**
51+
* Utility which tags an entire tree with 'AnnotationMode::kIgnore'.
52+
*/
53+
void annotateTreeToIgnoreForErrorDetails(const boost::intrusive_ptr<ExpressionContext>& expCtx,
54+
MatchExpression* expr);
55+
} // namespace mongo::doc_validation_error

src/mongo/db/matcher/expression_always_boolean.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,14 +126,15 @@ class AlwaysTrueMatchExpression final : public AlwaysBooleanMatchExpression {
126126
public:
127127
static constexpr StringData kName = "$alwaysTrue"_sd;
128128

129-
AlwaysTrueMatchExpression() : AlwaysBooleanMatchExpression(MatchType::ALWAYS_TRUE, true) {}
129+
AlwaysTrueMatchExpression(clonable_ptr<ErrorAnnotation> annotation = nullptr)
130+
: AlwaysBooleanMatchExpression(MatchType::ALWAYS_TRUE, true, std::move(annotation)) {}
130131

131132
StringData name() const final {
132133
return kName;
133134
}
134135

135136
std::unique_ptr<MatchExpression> shallowClone() const final {
136-
return std::make_unique<AlwaysTrueMatchExpression>();
137+
return std::make_unique<AlwaysTrueMatchExpression>(_errorAnnotation);
137138
}
138139

139140
bool isTriviallyTrue() const final {

0 commit comments

Comments
 (0)