summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorTess Avitabile <tess.avitabile@mongodb.com>2016-04-13 16:51:54 -0400
committerTess Avitabile <tess.avitabile@mongodb.com>2016-04-26 17:31:35 -0400
commitd6a77a0135db56972b2626a08e20a240a770f66f (patch)
tree787d6af56c956cf0fab3d12d584668f58d50d105 /src/mongo
parentbfc1cf3a390099be0c031d2533aa5d090fc0acd6 (diff)
downloadmongo-d6a77a0135db56972b2626a08e20a240a770f66f.tar.gz
SERVER-23608 Make MatchExpressionParser take a CollatorInterface*
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/db/auth/authz_manager_external_state_mock.cpp3
-rw-r--r--src/mongo/db/catalog/apply_ops.cpp3
-rw-r--r--src/mongo/db/catalog/collection.cpp3
-rw-r--r--src/mongo/db/catalog/index_catalog.cpp3
-rw-r--r--src/mongo/db/catalog/index_catalog_entry.cpp3
-rw-r--r--src/mongo/db/clientlistplugin.cpp3
-rw-r--r--src/mongo/db/commands/current_op.cpp3
-rw-r--r--src/mongo/db/commands/list_collections.cpp4
-rw-r--r--src/mongo/db/exec/projection_exec.cpp3
-rw-r--r--src/mongo/db/exec/projection_exec_test.cpp3
-rw-r--r--src/mongo/db/exec/stagedebug_cmd.cpp3
-rw-r--r--src/mongo/db/matcher/SConscript1
-rw-r--r--src/mongo/db/matcher/expression_algo_test.cpp60
-rw-r--r--src/mongo/db/matcher/expression_parser.cpp41
-rw-r--r--src/mongo/db/matcher/expression_parser.h15
-rw-r--r--src/mongo/db/matcher/expression_parser_array_test.cpp154
-rw-r--r--src/mongo/db/matcher/expression_parser_geo_test.cpp108
-rw-r--r--src/mongo/db/matcher/expression_parser_leaf_test.cpp889
-rw-r--r--src/mongo/db/matcher/expression_parser_test.cpp16
-rw-r--r--src/mongo/db/matcher/expression_parser_tree_test.cpp30
-rw-r--r--src/mongo/db/matcher/expression_serialization_test.cpp333
-rw-r--r--src/mongo/db/matcher/matcher.cpp6
-rw-r--r--src/mongo/db/matcher/matcher.h9
-rw-r--r--src/mongo/db/ops/modifier_pull.cpp3
-rw-r--r--src/mongo/db/ops/path_support_test.cpp3
-rw-r--r--src/mongo/db/pipeline/document_source_match.cpp11
-rw-r--r--src/mongo/db/query/canonical_query.cpp6
-rw-r--r--src/mongo/db/query/canonical_query_test.cpp4
-rw-r--r--src/mongo/db/query/index_bounds_builder_test.cpp3
-rw-r--r--src/mongo/db/query/parsed_projection.cpp3
-rw-r--r--src/mongo/db/query/parsed_projection_test.cpp6
-rw-r--r--src/mongo/db/query/plan_cache_indexability_test.cpp3
-rw-r--r--src/mongo/db/query/plan_cache_test.cpp3
-rw-r--r--src/mongo/db/query/planner_ixselect_test.cpp3
-rw-r--r--src/mongo/db/query/query_planner_test_fixture.cpp3
-rw-r--r--src/mongo/db/query/query_planner_test_lib.cpp3
-rw-r--r--src/mongo/db/query/query_solution_test.cpp3
-rw-r--r--src/mongo/dbtests/matchertests.cpp76
-rw-r--r--src/mongo/dbtests/query_stage_collscan.cpp5
-rw-r--r--src/mongo/dbtests/query_stage_count.cpp3
-rw-r--r--src/mongo/dbtests/query_stage_fetch.cpp5
-rw-r--r--src/mongo/dbtests/query_stage_multiplan.cpp5
-rw-r--r--src/mongo/dbtests/query_stage_subplan.cpp15
-rw-r--r--src/mongo/dbtests/query_stage_tests.cpp5
44 files changed, 1350 insertions, 517 deletions
diff --git a/src/mongo/db/auth/authz_manager_external_state_mock.cpp b/src/mongo/db/auth/authz_manager_external_state_mock.cpp
index 5bb10a57f3c..47f65d888c4 100644
--- a/src/mongo/db/auth/authz_manager_external_state_mock.cpp
+++ b/src/mongo/db/auth/authz_manager_external_state_mock.cpp
@@ -274,8 +274,9 @@ Status AuthzManagerExternalStateMock::_queryVector(
const NamespaceString& collectionName,
const BSONObj& query,
std::vector<BSONObjCollection::iterator>* result) {
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression parseResult =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
if (!parseResult.isOK()) {
return parseResult.getStatus();
}
diff --git a/src/mongo/db/catalog/apply_ops.cpp b/src/mongo/db/catalog/apply_ops.cpp
index 39a6ee25740..5fd501ddab3 100644
--- a/src/mongo/db/catalog/apply_ops.cpp
+++ b/src/mongo/db/catalog/apply_ops.cpp
@@ -78,7 +78,8 @@ Status applyOps(OperationContext* txn,
// Apply-ops would never have a $where/$text matcher. Using the "DisallowExtensions"
// callback ensures that parsing will throw an error if $where or $text are found.
- Matcher m(f["res"].Obj(), ExtensionsCallbackDisallowExtensions());
+ // TODO SERVER-23690: Pass the appropriate CollatorInterface* instead of nullptr.
+ Matcher m(f["res"].Obj(), ExtensionsCallbackDisallowExtensions(), nullptr);
if (!m.matches(realres)) {
result->append("got", realres);
result->append("whatFailed", f);
diff --git a/src/mongo/db/catalog/collection.cpp b/src/mongo/db/catalog/collection.cpp
index da4583d9693..61ef5390201 100644
--- a/src/mongo/db/catalog/collection.cpp
+++ b/src/mongo/db/catalog/collection.cpp
@@ -300,8 +300,9 @@ StatusWithMatchExpression Collection::parseValidator(const BSONObj& validator) c
return status;
}
+ // TODO SERVER-23687: Pass the appropriate CollatorInterface* instead of nullptr.
auto statusWithMatcher =
- MatchExpressionParser::parse(validator, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(validator, ExtensionsCallbackDisallowExtensions(), nullptr);
if (!statusWithMatcher.isOK())
return statusWithMatcher.getStatus();
diff --git a/src/mongo/db/catalog/index_catalog.cpp b/src/mongo/db/catalog/index_catalog.cpp
index a64f43284ca..2a23509fd0a 100644
--- a/src/mongo/db/catalog/index_catalog.cpp
+++ b/src/mongo/db/catalog/index_catalog.cpp
@@ -545,8 +545,9 @@ Status IndexCatalog::_isSpecOk(OperationContext* txn, const BSONObj& spec) const
return Status(ErrorCodes::CannotCreateIndex,
"\"partialFilterExpression\" for an index must be a document");
}
+ // TODO SERVER-23618: pass the appropriate CollatorInterface* instead of nullptr.
StatusWithMatchExpression statusWithMatcher = MatchExpressionParser::parse(
- filterElement.Obj(), ExtensionsCallbackDisallowExtensions());
+ filterElement.Obj(), ExtensionsCallbackDisallowExtensions(), nullptr);
if (!statusWithMatcher.isOK()) {
return statusWithMatcher.getStatus();
}
diff --git a/src/mongo/db/catalog/index_catalog_entry.cpp b/src/mongo/db/catalog/index_catalog_entry.cpp
index dcc5f01f5b8..239cb7e4fc0 100644
--- a/src/mongo/db/catalog/index_catalog_entry.cpp
+++ b/src/mongo/db/catalog/index_catalog_entry.cpp
@@ -104,8 +104,9 @@ void IndexCatalogEntry::init(OperationContext* txn, IndexAccessMethod* accessMet
if (BSONElement filterElement = _descriptor->getInfoElement("partialFilterExpression")) {
invariant(filterElement.isABSONObj());
BSONObj filter = filterElement.Obj();
+ // TODO SERVER-23618: pass the appropriate CollatorInterface* instead of nullptr.
StatusWithMatchExpression statusWithMatcher =
- MatchExpressionParser::parse(filter, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(filter, ExtensionsCallbackDisallowExtensions(), nullptr);
// this should be checked in create, so can blow up here
invariantOK(statusWithMatcher.getStatus());
_filterExpression = std::move(statusWithMatcher.getValue());
diff --git a/src/mongo/db/clientlistplugin.cpp b/src/mongo/db/clientlistplugin.cpp
index ccb799571c5..ef241ed7185 100644
--- a/src/mongo/db/clientlistplugin.cpp
+++ b/src/mongo/db/clientlistplugin.cpp
@@ -168,8 +168,9 @@ public:
BSONObjBuilder& result) {
unique_ptr<MatchExpression> filter;
if (cmdObj["filter"].isABSONObj()) {
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression statusWithMatcher = MatchExpressionParser::parse(
- cmdObj["filter"].Obj(), ExtensionsCallbackDisallowExtensions());
+ cmdObj["filter"].Obj(), ExtensionsCallbackDisallowExtensions(), collator);
if (!statusWithMatcher.isOK()) {
return appendCommandStatus(result, statusWithMatcher.getStatus());
}
diff --git a/src/mongo/db/commands/current_op.cpp b/src/mongo/db/commands/current_op.cpp
index fed56b550ad..2f5798b410f 100644
--- a/src/mongo/db/commands/current_op.cpp
+++ b/src/mongo/db/commands/current_op.cpp
@@ -105,7 +105,8 @@ public:
// collection, we pass in a fake collection name (and this is okay, because $where parsing
// only relies on the database part of the namespace).
const NamespaceString fakeNS(db, "$cmd");
- const Matcher matcher(filter, ExtensionsCallbackReal(txn, &fakeNS));
+ CollatorInterface* collator = nullptr;
+ const Matcher matcher(filter, ExtensionsCallbackReal(txn, &fakeNS), collator);
BSONArrayBuilder inprogBuilder(result.subarrayStart("inprog"));
diff --git a/src/mongo/db/commands/list_collections.cpp b/src/mongo/db/commands/list_collections.cpp
index 0f9876420de..a20179c2bae 100644
--- a/src/mongo/db/commands/list_collections.cpp
+++ b/src/mongo/db/commands/list_collections.cpp
@@ -191,8 +191,10 @@ public:
return appendCommandStatus(
result, Status(ErrorCodes::BadValue, "\"filter\" must be an object"));
}
+ // The collator is null because collection objects are compared using binary comparison.
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression statusWithMatcher = MatchExpressionParser::parse(
- filterElt.Obj(), ExtensionsCallbackDisallowExtensions());
+ filterElt.Obj(), ExtensionsCallbackDisallowExtensions(), collator);
if (!statusWithMatcher.isOK()) {
return appendCommandStatus(result, statusWithMatcher.getStatus());
}
diff --git a/src/mongo/db/exec/projection_exec.cpp b/src/mongo/db/exec/projection_exec.cpp
index a399f33e9eb..f653e8494b3 100644
--- a/src/mongo/db/exec/projection_exec.cpp
+++ b/src/mongo/db/exec/projection_exec.cpp
@@ -125,8 +125,9 @@ ProjectionExec::ProjectionExec(const BSONObj& spec,
BSONObj elemMatchObj = e.wrap();
verify(elemMatchObj.isOwned());
_elemMatchObjs.push_back(elemMatchObj);
+ // TODO SERVER-23680: pass the appropriate CollatorInterface* instead of nullptr.
StatusWithMatchExpression statusWithMatcher =
- MatchExpressionParser::parse(elemMatchObj, extensionsCallback);
+ MatchExpressionParser::parse(elemMatchObj, extensionsCallback, nullptr);
verify(statusWithMatcher.isOK());
// And store it in _matchers.
_matchers[mongoutils::str::before(e.fieldName(), '.').c_str()] =
diff --git a/src/mongo/db/exec/projection_exec_test.cpp b/src/mongo/db/exec/projection_exec_test.cpp
index 9245cf8d18e..69fab9eafe3 100644
--- a/src/mongo/db/exec/projection_exec_test.cpp
+++ b/src/mongo/db/exec/projection_exec_test.cpp
@@ -49,8 +49,9 @@ using std::unique_ptr;
* Utility function to create MatchExpression
*/
unique_ptr<MatchExpression> parseMatchExpression(const BSONObj& obj) {
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression status =
- MatchExpressionParser::parse(obj, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(obj, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(status.isOK());
return std::move(status.getValue());
}
diff --git a/src/mongo/db/exec/stagedebug_cmd.cpp b/src/mongo/db/exec/stagedebug_cmd.cpp
index a56f7417063..d43a892bd8c 100644
--- a/src/mongo/db/exec/stagedebug_cmd.cpp
+++ b/src/mongo/db/exec/stagedebug_cmd.cpp
@@ -249,8 +249,9 @@ public:
}
BSONObj argObj = e.Obj();
if (filterTag == e.fieldName()) {
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression statusWithMatcher = MatchExpressionParser::parse(
- argObj, ExtensionsCallbackReal(txn, &collection->ns()));
+ argObj, ExtensionsCallbackReal(txn, &collection->ns()), collator);
if (!statusWithMatcher.isOK()) {
return NULL;
}
diff --git a/src/mongo/db/matcher/SConscript b/src/mongo/db/matcher/SConscript
index 5edaa348843..c22650d40ca 100644
--- a/src/mongo/db/matcher/SConscript
+++ b/src/mongo/db/matcher/SConscript
@@ -78,6 +78,7 @@ env.CppUnitTest(
'expression_parser_tree_test.cpp',
],
LIBDEPS=[
+ '$BUILD_DIR/mongo/db/query/collation/collator_interface_mock',
'expressions',
],
)
diff --git a/src/mongo/db/matcher/expression_algo_test.cpp b/src/mongo/db/matcher/expression_algo_test.cpp
index c89c95f5d63..807b35aee62 100644
--- a/src/mongo/db/matcher/expression_algo_test.cpp
+++ b/src/mongo/db/matcher/expression_algo_test.cpp
@@ -52,8 +52,9 @@ using std::unique_ptr;
class ParsedMatchExpression {
public:
ParsedMatchExpression(const std::string& str) : _obj(fromjson(str)) {
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(_obj, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(_obj, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_OK(result.getStatus());
_expr = std::move(result.getValue());
}
@@ -71,9 +72,10 @@ TEST(ExpressionAlgoIsSubsetOf, NullAndOmittedField) {
// Verify that ComparisonMatchExpression::init() prohibits creating a match expression with
// an Undefined type.
BSONObj undefined = fromjson("{a: undefined}");
+ CollatorInterface* collator = nullptr;
ASSERT_EQUALS(ErrorCodes::BadValue,
- MatchExpressionParser::parse(undefined, ExtensionsCallbackDisallowExtensions())
- .getStatus());
+ MatchExpressionParser::parse(
+ undefined, ExtensionsCallbackDisallowExtensions(), collator).getStatus());
ParsedMatchExpression empty("{}");
ParsedMatchExpression null("{a: null}");
@@ -653,8 +655,9 @@ TEST(ExpressionAlgoIsSubsetOf, Compare_Exists_NE) {
TEST(IsIndependent, AndIsIndependentOnlyIfChildrenAre) {
BSONObj matchPredicate = fromjson("{$and: [{a: 1}, {b: 1}]}");
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression status =
- MatchExpressionParser::parse(matchPredicate, ExtensionsCallbackNoop());
+ MatchExpressionParser::parse(matchPredicate, ExtensionsCallbackNoop(), collator);
ASSERT_OK(status.getStatus());
unique_ptr<MatchExpression> expr = std::move(status.getValue());
@@ -664,8 +667,9 @@ TEST(IsIndependent, AndIsIndependentOnlyIfChildrenAre) {
TEST(IsIndependent, ElemMatchIsNotIndependent) {
BSONObj matchPredicate = fromjson("{x: {$elemMatch: {y: 1}}}");
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression status =
- MatchExpressionParser::parse(matchPredicate, ExtensionsCallbackNoop());
+ MatchExpressionParser::parse(matchPredicate, ExtensionsCallbackNoop(), collator);
ASSERT_OK(status.getStatus());
unique_ptr<MatchExpression> expr = std::move(status.getValue());
@@ -676,8 +680,9 @@ TEST(IsIndependent, ElemMatchIsNotIndependent) {
TEST(IsIndependent, NorIsIndependentOnlyIfChildrenAre) {
BSONObj matchPredicate = fromjson("{$nor: [{a: 1}, {b: 1}]}");
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression status =
- MatchExpressionParser::parse(matchPredicate, ExtensionsCallbackNoop());
+ MatchExpressionParser::parse(matchPredicate, ExtensionsCallbackNoop(), collator);
ASSERT_OK(status.getStatus());
unique_ptr<MatchExpression> expr = std::move(status.getValue());
@@ -687,8 +692,9 @@ TEST(IsIndependent, NorIsIndependentOnlyIfChildrenAre) {
TEST(IsIndependent, NotIsIndependentOnlyIfChildrenAre) {
BSONObj matchPredicate = fromjson("{a: {$not: {$eq: 1}}}");
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression status =
- MatchExpressionParser::parse(matchPredicate, ExtensionsCallbackNoop());
+ MatchExpressionParser::parse(matchPredicate, ExtensionsCallbackNoop(), collator);
ASSERT_OK(status.getStatus());
unique_ptr<MatchExpression> expr = std::move(status.getValue());
@@ -698,8 +704,9 @@ TEST(IsIndependent, NotIsIndependentOnlyIfChildrenAre) {
TEST(IsIndependent, OrIsIndependentOnlyIfChildrenAre) {
BSONObj matchPredicate = fromjson("{$or: [{a: 1}, {b: 1}]}");
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression status =
- MatchExpressionParser::parse(matchPredicate, ExtensionsCallbackNoop());
+ MatchExpressionParser::parse(matchPredicate, ExtensionsCallbackNoop(), collator);
ASSERT_OK(status.getStatus());
unique_ptr<MatchExpression> expr = std::move(status.getValue());
@@ -709,8 +716,9 @@ TEST(IsIndependent, OrIsIndependentOnlyIfChildrenAre) {
TEST(IsIndependent, AndWithDottedFieldPathsIsNotIndependent) {
BSONObj matchPredicate = fromjson("{$and: [{'a': 1}, {'a.b': 1}]}");
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression status =
- MatchExpressionParser::parse(matchPredicate, ExtensionsCallbackNoop());
+ MatchExpressionParser::parse(matchPredicate, ExtensionsCallbackNoop(), collator);
ASSERT_OK(status.getStatus());
unique_ptr<MatchExpression> expr = std::move(status.getValue());
@@ -720,8 +728,9 @@ TEST(IsIndependent, AndWithDottedFieldPathsIsNotIndependent) {
TEST(IsIndependent, BallIsIndependentOfBalloon) {
BSONObj matchPredicate = fromjson("{'a.ball': 4}");
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression status =
- MatchExpressionParser::parse(matchPredicate, ExtensionsCallbackNoop());
+ MatchExpressionParser::parse(matchPredicate, ExtensionsCallbackNoop(), collator);
ASSERT_OK(status.getStatus());
unique_ptr<MatchExpression> expr = std::move(status.getValue());
@@ -732,8 +741,9 @@ TEST(IsIndependent, BallIsIndependentOfBalloon) {
TEST(SplitMatchExpression, AndWithSplittableChildrenIsSplittable) {
BSONObj matchPredicate = fromjson("{$and: [{a: 1}, {b: 1}]}");
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression status =
- MatchExpressionParser::parse(matchPredicate, ExtensionsCallbackNoop());
+ MatchExpressionParser::parse(matchPredicate, ExtensionsCallbackNoop(), collator);
ASSERT_OK(status.getStatus());
std::pair<unique_ptr<MatchExpression>, unique_ptr<MatchExpression>> splitExpr =
@@ -753,8 +763,9 @@ TEST(SplitMatchExpression, AndWithSplittableChildrenIsSplittable) {
TEST(SplitMatchExpression, NorWithIndependentChildrenIsSplittable) {
BSONObj matchPredicate = fromjson("{$nor: [{a: 1}, {b: 1}]}");
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression status =
- MatchExpressionParser::parse(matchPredicate, ExtensionsCallbackNoop());
+ MatchExpressionParser::parse(matchPredicate, ExtensionsCallbackNoop(), collator);
ASSERT_OK(status.getStatus());
std::pair<unique_ptr<MatchExpression>, unique_ptr<MatchExpression>> splitExpr =
@@ -774,8 +785,9 @@ TEST(SplitMatchExpression, NorWithIndependentChildrenIsSplittable) {
TEST(SplitMatchExpression, NotWithIndependentChildIsSplittable) {
BSONObj matchPredicate = fromjson("{x: {$not: {$gt: 4}}}");
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression status =
- MatchExpressionParser::parse(matchPredicate, ExtensionsCallbackNoop());
+ MatchExpressionParser::parse(matchPredicate, ExtensionsCallbackNoop(), collator);
ASSERT_OK(status.getStatus());
std::pair<unique_ptr<MatchExpression>, unique_ptr<MatchExpression>> splitExpr =
@@ -791,8 +803,9 @@ TEST(SplitMatchExpression, NotWithIndependentChildIsSplittable) {
TEST(SplitMatchExpression, OrWithOnlyIndependentChildrenIsNotSplittable) {
BSONObj matchPredicate = fromjson("{$or: [{a: 1}, {b: 1}]}");
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression status =
- MatchExpressionParser::parse(matchPredicate, ExtensionsCallbackNoop());
+ MatchExpressionParser::parse(matchPredicate, ExtensionsCallbackNoop(), collator);
ASSERT_OK(status.getStatus());
std::pair<unique_ptr<MatchExpression>, unique_ptr<MatchExpression>> splitExpr =
@@ -811,8 +824,9 @@ TEST(SplitMatchExpression, ComplexMatchExpressionSplitsCorrectly) {
"{$and: [{x: {$not: {$size: 2}}},"
"{$or: [{'a.b' : 3}, {'a.b.c': 4}]},"
"{$nor: [{x: {$gt: 4}}, {$and: [{x: {$not: {$eq: 1}}}, {y: 3}]}]}]}");
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression status =
- MatchExpressionParser::parse(matchPredicate, ExtensionsCallbackNoop());
+ MatchExpressionParser::parse(matchPredicate, ExtensionsCallbackNoop(), collator);
ASSERT_OK(status.getStatus());
std::pair<unique_ptr<MatchExpression>, unique_ptr<MatchExpression>> splitExpr =
@@ -836,7 +850,9 @@ TEST(SplitMatchExpression, ComplexMatchExpressionSplitsCorrectly) {
TEST(MapOverMatchExpression, DoesMapOverLogicalNodes) {
BSONObj matchPredicate = fromjson("{a: {$not: {$eq: 1}}}");
- auto swMatchExpression = MatchExpressionParser::parse(matchPredicate, ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ auto swMatchExpression =
+ MatchExpressionParser::parse(matchPredicate, ExtensionsCallbackNoop(), collator);
ASSERT_OK(swMatchExpression.getStatus());
bool hasLogicalNode = false;
@@ -852,7 +868,9 @@ TEST(MapOverMatchExpression, DoesMapOverLogicalNodes) {
TEST(MapOverMatchExpression, DoesMapOverLeafNodes) {
BSONObj matchPredicate = fromjson("{a: {$not: {$eq: 1}}}");
- auto swMatchExpression = MatchExpressionParser::parse(matchPredicate, ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ auto swMatchExpression =
+ MatchExpressionParser::parse(matchPredicate, ExtensionsCallbackNoop(), collator);
ASSERT_OK(swMatchExpression.getStatus());
bool hasLeafNode = false;
@@ -868,7 +886,9 @@ TEST(MapOverMatchExpression, DoesMapOverLeafNodes) {
TEST(MapOverMatchExpression, DoesPassPath) {
BSONObj matchPredicate = fromjson("{a: {$elemMatch: {b: 1}}}");
- auto swMatchExpression = MatchExpressionParser::parse(matchPredicate, ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ auto swMatchExpression =
+ MatchExpressionParser::parse(matchPredicate, ExtensionsCallbackNoop(), collator);
ASSERT_OK(swMatchExpression.getStatus());
std::vector<std::string> paths;
@@ -885,7 +905,9 @@ TEST(MapOverMatchExpression, DoesPassPath) {
TEST(MapOverMatchExpression, DoesMapOverNodesWithMultipleChildren) {
BSONObj matchPredicate = fromjson("{$and: [{a: {$gt: 1}}, {b: {$lte: 2}}]}");
- auto swMatchExpression = MatchExpressionParser::parse(matchPredicate, ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ auto swMatchExpression =
+ MatchExpressionParser::parse(matchPredicate, ExtensionsCallbackNoop(), collator);
ASSERT_OK(swMatchExpression.getStatus());
size_t nodeCount = 0;
diff --git a/src/mongo/db/matcher/expression_parser.cpp b/src/mongo/db/matcher/expression_parser.cpp
index f86ba0f55e4..a650ff2e88d 100644
--- a/src/mongo/db/matcher/expression_parser.cpp
+++ b/src/mongo/db/matcher/expression_parser.cpp
@@ -95,8 +95,7 @@ StatusWithMatchExpression MatchExpressionParser::_parseSubField(const BSONObj& c
// TODO: these should move to getGtLtOp, or its replacement
if (mongoutils::str::equals("$eq", e.fieldName()))
- // TODO SERVER-23608: Pass our CollatorInterface* to EqualityMatchExpression().
- return _parseComparison(name, new EqualityMatchExpression(nullptr), e);
+ return _parseComparison(name, new EqualityMatchExpression(_collator), e);
if (mongoutils::str::equals("$not", e.fieldName())) {
return _parseNot(name, e, level);
@@ -113,26 +112,21 @@ StatusWithMatchExpression MatchExpressionParser::_parseSubField(const BSONObj& c
return {Status(ErrorCodes::BadValue,
mongoutils::str::stream() << "unknown operator: " << e.fieldName())};
case BSONObj::LT:
- // TODO SERVER-23608: Pass our CollatorInterface* to LTMatchExpression().
- return _parseComparison(name, new LTMatchExpression(nullptr), e);
+ return _parseComparison(name, new LTMatchExpression(_collator), e);
case BSONObj::LTE:
- // TODO SERVER-23608: Pass our CollatorInterface* to LTEMatchExpression().
- return _parseComparison(name, new LTEMatchExpression(nullptr), e);
+ return _parseComparison(name, new LTEMatchExpression(_collator), e);
case BSONObj::GT:
- // TODO SERVER-23608: Pass our CollatorInterface* to GTMatchExpression().
- return _parseComparison(name, new GTMatchExpression(nullptr), e);
+ return _parseComparison(name, new GTMatchExpression(_collator), e);
case BSONObj::GTE:
- // TODO SERVER-23608: Pass our CollatorInterface* to GTEMatchExpression().
- return _parseComparison(name, new GTEMatchExpression(nullptr), e);
+ return _parseComparison(name, new GTEMatchExpression(_collator), e);
case BSONObj::NE: {
if (RegEx == e.type()) {
// Just because $ne can be rewritten as the negation of an
// equality does not mean that $ne of a regex is allowed. See SERVER-1705.
return {Status(ErrorCodes::BadValue, "Can't have regex as arg to $ne.")};
}
- // TODO SERVER-23608: Pass our CollatorInterface* to EqualityMatchExpression().
StatusWithMatchExpression s =
- _parseComparison(name, new EqualityMatchExpression(nullptr), e);
+ _parseComparison(name, new EqualityMatchExpression(_collator), e);
if (!s.isOK())
return s;
std::unique_ptr<NotMatchExpression> n = stdx::make_unique<NotMatchExpression>();
@@ -142,14 +136,13 @@ StatusWithMatchExpression MatchExpressionParser::_parseSubField(const BSONObj& c
return {std::move(n)};
}
case BSONObj::Equality:
- // TODO SERVER-23608: Pass our CollatorInterface* to EqualityMatchExpression().
- return _parseComparison(name, new EqualityMatchExpression(nullptr), e);
+ return _parseComparison(name, new EqualityMatchExpression(_collator), e);
case BSONObj::opIN: {
if (e.type() != Array)
return {Status(ErrorCodes::BadValue, "$in needs an array")};
- // TODO SERVER-23608: Pass our CollatorInterface* to InMatchExpression().
- std::unique_ptr<InMatchExpression> temp = stdx::make_unique<InMatchExpression>(nullptr);
+ std::unique_ptr<InMatchExpression> temp =
+ stdx::make_unique<InMatchExpression>(_collator);
Status s = temp->init(name);
if (!s.isOK())
return s;
@@ -162,8 +155,8 @@ StatusWithMatchExpression MatchExpressionParser::_parseSubField(const BSONObj& c
case BSONObj::NIN: {
if (e.type() != Array)
return {Status(ErrorCodes::BadValue, "$nin needs an array")};
- // TODO SERVER-23608: Pass our CollatorInterface* to InMatchExpression().
- std::unique_ptr<InMatchExpression> temp = stdx::make_unique<InMatchExpression>(nullptr);
+ std::unique_ptr<InMatchExpression> temp =
+ stdx::make_unique<InMatchExpression>(_collator);
Status s = temp->init(name);
if (!s.isOK())
return s;
@@ -354,10 +347,10 @@ StatusWithMatchExpression MatchExpressionParser::_parse(const BSONObj& obj, int
} else if (mongoutils::str::equals("ref", rest) ||
mongoutils::str::equals("id", rest) || mongoutils::str::equals("db", rest)) {
// DBRef fields.
- // TODO SERVER-23608: Pass our CollatorInterface* to EqualityMatchExpression() in
- // the "id" case.
+ // 'id' is collation-aware. 'ref' and 'db' are compared using binary comparison.
+ CollatorInterface* collator = (str::equals("id", rest) ? _collator : nullptr);
std::unique_ptr<ComparisonMatchExpression> eq =
- stdx::make_unique<EqualityMatchExpression>(nullptr);
+ stdx::make_unique<EqualityMatchExpression>(collator);
Status s = eq->init(e.fieldName(), e);
if (!s.isOK())
return s;
@@ -387,9 +380,8 @@ StatusWithMatchExpression MatchExpressionParser::_parse(const BSONObj& obj, int
continue;
}
- // TODO SERVER-23608: Pass our CollatorInterface* to EqualityMatchExpression().
std::unique_ptr<ComparisonMatchExpression> eq =
- stdx::make_unique<EqualityMatchExpression>(nullptr);
+ stdx::make_unique<EqualityMatchExpression>(_collator);
Status s = eq->init(e.fieldName(), e);
if (!s.isOK())
return s;
@@ -807,9 +799,8 @@ StatusWithMatchExpression MatchExpressionParser::_parseAll(const char* name,
} else if (e.type() == Object && e.Obj().firstElement().getGtLtOp(-1) != -1) {
return {Status(ErrorCodes::BadValue, "no $ expressions in $all")};
} else {
- // TODO SERVER-23608: Pass our CollatorInterface* to EqualityMatchExpression().
std::unique_ptr<EqualityMatchExpression> x =
- stdx::make_unique<EqualityMatchExpression>(nullptr);
+ stdx::make_unique<EqualityMatchExpression>(_collator);
Status s = x->init(name, e);
if (!s.isOK())
return s;
diff --git a/src/mongo/db/matcher/expression_parser.h b/src/mongo/db/matcher/expression_parser.h
index 9fc5d18ccc2..0bde5027338 100644
--- a/src/mongo/db/matcher/expression_parser.h
+++ b/src/mongo/db/matcher/expression_parser.h
@@ -40,6 +40,7 @@
namespace mongo {
+class CollatorInterface;
class OperationContext;
class MatchExpressionParser {
@@ -47,16 +48,18 @@ public:
/**
* caller has to maintain ownership obj
* the tree has views (BSONElement) into obj
+ * 'collator' must outlive the returned MatchExpression and any clones made of it.
*/
static StatusWithMatchExpression parse(const BSONObj& obj,
- const ExtensionsCallback& extensionsCallback) {
+ const ExtensionsCallback& extensionsCallback,
+ CollatorInterface* collator) {
// The 0 initializes the match expression tree depth.
- return MatchExpressionParser(&extensionsCallback)._parse(obj, 0);
+ return MatchExpressionParser(&extensionsCallback, collator)._parse(obj, 0);
}
private:
- explicit MatchExpressionParser(const ExtensionsCallback* extensionsCallback)
- : _extensionsCallback(extensionsCallback) {}
+ MatchExpressionParser(const ExtensionsCallback* extensionsCallback, CollatorInterface* collator)
+ : _extensionsCallback(extensionsCallback), _collator(collator) {}
/**
* 5 = false
@@ -149,6 +152,10 @@ private:
// Performs parsing for the match extensions. We do not own this pointer - it has to live
// as long as the parser is active.
const ExtensionsCallback* _extensionsCallback;
+
+ // Collator that constructed collation-aware MatchExpressions will use.
+ // We do not own this pointer - it has to live as long as the parser is active.
+ CollatorInterface* _collator;
};
typedef stdx::function<StatusWithMatchExpression(
diff --git a/src/mongo/db/matcher/expression_parser_array_test.cpp b/src/mongo/db/matcher/expression_parser_array_test.cpp
index 48972f3ef1e..c215ea33c9b 100644
--- a/src/mongo/db/matcher/expression_parser_array_test.cpp
+++ b/src/mongo/db/matcher/expression_parser_array_test.cpp
@@ -39,6 +39,7 @@
#include "mongo/db/matcher/expression.h"
#include "mongo/db/matcher/expression_array.h"
#include "mongo/db/matcher/extensions_callback_disallow_extensions.h"
+#include "mongo/db/query/collation/collator_interface_mock.h"
namespace mongo {
@@ -46,8 +47,9 @@ using std::string;
TEST(MatchExpressionParserArrayTest, Size1) {
BSONObj query = BSON("x" << BSON("$size" << 2));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(!result.getValue()->matchesBSON(BSON("x" << 1)));
@@ -58,8 +60,9 @@ TEST(MatchExpressionParserArrayTest, Size1) {
TEST(MatchExpressionParserArrayTest, SizeAsLong) {
BSONObj query = BSON("x" << BSON("$size" << 2LL));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(!result.getValue()->matchesBSON(BSON("x" << 1)));
@@ -70,30 +73,34 @@ TEST(MatchExpressionParserArrayTest, SizeAsLong) {
TEST(MatchExpressionParserArrayTest, SizeAsNegativeLong) {
BSONObj query = BSON("x" << BSON("$size" << -2LL));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
TEST(MatchExpressionParserArrayTest, SizeTooLarge) {
BSONObj query = BSON("x" << BSON("$size" << std::numeric_limits<long long>::max()));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
TEST(MatchExpressionParserArrayTest, SizeAsString) {
BSONObj query = BSON("x" << BSON("$size"
<< "a"));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
TEST(MatchExpressionParserArrayTest, SizeWithIntegralDouble) {
BSONObj query = BSON("x" << BSON("$size" << 2.0));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(!result.getValue()->matchesBSON(BSON("x" << 1)));
@@ -104,29 +111,33 @@ TEST(MatchExpressionParserArrayTest, SizeWithIntegralDouble) {
TEST(MatchExpressionParserArrayTest, SizeWithNegativeIntegralDouble) {
BSONObj query = BSON("x" << BSON("$size" << -2.0));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
TEST(MatchExpressionParserArrayTest, SizeWithDouble) {
BSONObj query = BSON("x" << BSON("$size" << 2.5));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
TEST(MatchExpressionParserArrayTest, SizeWithNegative) {
BSONObj query = BSON("x" << BSON("$size" << -2));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
TEST(MatchExpressionParserArrayTest, SizeBad) {
BSONObj query = BSON("x" << BSON("$size" << BSONNULL));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
@@ -134,8 +145,9 @@ TEST(MatchExpressionParserArrayTest, SizeBad) {
TEST(MatchExpressionParserArrayTest, ElemMatchArr1) {
BSONObj query = BSON("x" << BSON("$elemMatch" << BSON("x" << 1 << "y" << 2)));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(!result.getValue()->matchesBSON(BSON("x" << 1)));
@@ -147,8 +159,9 @@ TEST(MatchExpressionParserArrayTest, ElemMatchArr1) {
TEST(MatchExpressionParserArrayTest, ElemMatchAnd) {
BSONObj query =
BSON("x" << BSON("$elemMatch" << BSON("$and" << BSON_ARRAY(BSON("x" << 1 << "y" << 2)))));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(!result.getValue()->matchesBSON(BSON("x" << 1)));
@@ -159,8 +172,9 @@ TEST(MatchExpressionParserArrayTest, ElemMatchAnd) {
TEST(MatchExpressionParserArrayTest, ElemMatchNor) {
BSONObj query = BSON("x" << BSON("$elemMatch" << BSON("$nor" << BSON_ARRAY(BSON("x" << 1)))));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(!result.getValue()->matchesBSON(BSON("x" << 1)));
@@ -172,8 +186,9 @@ TEST(MatchExpressionParserArrayTest, ElemMatchNor) {
TEST(MatchExpressionParserArrayTest, ElemMatchOr) {
BSONObj query =
BSON("x" << BSON("$elemMatch" << BSON("$or" << BSON_ARRAY(BSON("x" << 1 << "y" << 2)))));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(!result.getValue()->matchesBSON(BSON("x" << 1)));
@@ -184,8 +199,9 @@ TEST(MatchExpressionParserArrayTest, ElemMatchOr) {
TEST(MatchExpressionParserArrayTest, ElemMatchVal1) {
BSONObj query = BSON("x" << BSON("$elemMatch" << BSON("$gt" << 5)));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(!result.getValue()->matchesBSON(BSON("x" << 1)));
@@ -207,8 +223,9 @@ TEST(MatchExpressionParserArrayTest, ElemMatchDBRef1) {
<< "db");
BSONObj query = BSON("x" << BSON("$elemMatch" << BSON("$eq" << match)));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(!result.getValue()->matchesBSON(BSON("x" << match)));
@@ -229,8 +246,9 @@ TEST(MatchExpressionParserArrayTest, ElemMatchDBRef2) {
<< "db");
BSONObj query = BSON("x" << BSON("$elemMatch" << match));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(!result.getValue()->matchesBSON(BSON("x" << match)));
@@ -250,8 +268,9 @@ TEST(MatchExpressionParserArrayTest, ElemMatchDBRef3) {
<< "$id" << oidx << "foo" << 12345);
BSONObj query = BSON("x" << BSON("$elemMatch" << match));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(!result.getValue()->matchesBSON(BSON("x" << match)));
@@ -283,8 +302,9 @@ TEST(MatchExpressionParserArrayTest, ElemMatchDBRef4) {
<< "db");
BSONObj query = BSON("x" << BSON("$elemMatch" << matchOutOfOrder));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(!result.getValue()->matchesBSON(BSON("x" << match)));
@@ -307,8 +327,9 @@ TEST(MatchExpressionParserArrayTest, ElemMatchDBRef5) {
<< "$id" << oidx << "foo" << 12345);
BSONObj query = BSON("x" << BSON("$elemMatch" << matchOutOfOrder));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(!result.getValue()->matchesBSON(BSON("x" << match)));
@@ -336,8 +357,9 @@ TEST(MatchExpressionParserArrayTest, ElemMatchDBRef6) {
<< "$id" << oid << "foo" << 12345);
BSONObj query = BSON("x" << BSON("$elemMatch" << matchMissingID));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(!result.getValue()->matchesBSON(BSON("x" << match)));
@@ -364,8 +386,9 @@ TEST(MatchExpressionParserArrayTest, ElemMatchDBRef7) {
<< "$id" << oidx << "foo" << 12345);
BSONObj query = BSON("x" << BSON("$elemMatch" << matchMissingRef));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(!result.getValue()->matchesBSON(BSON("x" << match)));
@@ -397,8 +420,9 @@ TEST(MatchExpressionParserArrayTest, ElemMatchDBRef8) {
<< "foo" << 12345);
BSONObj query = BSON("x" << BSON("$elemMatch" << matchDBOnly));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(!result.getValue()->matchesBSON(BSON("x" << match)));
@@ -416,8 +440,9 @@ TEST(MatchExpressionParserArrayTest, ElemMatchDBRef8) {
TEST(MatchExpressionParserArrayTest, All1) {
BSONObj query = BSON("x" << BSON("$all" << BSON_ARRAY(1 << 2)));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
// Verify that the $all got parsed to AND.
@@ -433,8 +458,9 @@ TEST(MatchExpressionParserArrayTest, All1) {
TEST(MatchExpressionParserArrayTest, AllNull) {
BSONObj query = BSON("x" << BSON("$all" << BSON_ARRAY(BSONNULL)));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
// Verify that the $all got parsed to AND.
@@ -448,8 +474,9 @@ TEST(MatchExpressionParserArrayTest, AllNull) {
TEST(MatchExpressionParserArrayTest, AllBadArg) {
BSONObj query = BSON("x" << BSON("$all" << 1));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
@@ -462,8 +489,9 @@ TEST(MatchExpressionParserArrayTest, AllBadRegexArg) {
BSONObj query = BSON("x" << operand.obj());
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
@@ -476,8 +504,9 @@ TEST(MatchExpressionParserArrayTest, AllRegex1) {
all.appendArray("$all", allArray.obj());
BSONObj query = BSON("a" << all.obj());
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
// Verify that the $all got parsed to AND.
@@ -503,8 +532,9 @@ TEST(MatchExpressionParserArrayTest, AllRegex2) {
all.appendArray("$all", allArray.obj());
BSONObj query = BSON("a" << all.obj());
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
// Verify that the $all got parsed to AND.
@@ -521,8 +551,9 @@ TEST(MatchExpressionParserArrayTest, AllRegex2) {
TEST(MatchExpressionParserArrayTest, AllNonArray) {
BSONObj query = BSON("x" << BSON("$all" << BSON_ARRAY(5)));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
// Verify that the $all got parsed to AND.
@@ -538,8 +569,9 @@ TEST(MatchExpressionParserArrayTest, AllNonArray) {
TEST(MatchExpressionParserArrayTest, AllElemMatch1) {
BSONObj internal = BSON("x" << 1 << "y" << 2);
BSONObj query = BSON("x" << BSON("$all" << BSON_ARRAY(BSON("$elemMatch" << internal))));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
// Verify that the $all got parsed to an AND with a single ELEM_MATCH_OBJECT child.
@@ -559,8 +591,9 @@ TEST(MatchExpressionParserArrayTest, AllElemMatch1) {
TEST(MatchExpressionParserArrayTest, AllElemMatch2) {
BSONObj internal = BSON("z" << 1);
BSONObj query = BSON("x.y" << BSON("$all" << BSON_ARRAY(BSON("$elemMatch" << internal))));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
// Verify that the $all got parsed to an AND with a single ELEM_MATCH_OBJECT child.
@@ -595,8 +628,9 @@ TEST(MatchExpressionParserArrayTest, AllElemMatch2) {
// are correct.
TEST(MatchExpressionParserArrayTest, AllElemMatch3) {
BSONObj query = fromjson("{x: {$all: [{$elemMatch: {y: 1, z: 1}}]}}");
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
std::unique_ptr<MatchExpression> expr = std::move(result.getValue());
@@ -631,12 +665,13 @@ TEST(MatchExpressionParserArrayTest, AllElemMatchBad) {
BSONObj internal = BSON("x" << 1 << "y" << 2);
BSONObj query = BSON("x" << BSON("$all" << BSON_ARRAY(BSON("$elemMatch" << internal) << 5)));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
query = BSON("x" << BSON("$all" << BSON_ARRAY(5 << BSON("$elemMatch" << internal))));
- result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
@@ -644,34 +679,36 @@ TEST(MatchExpressionParserArrayTest, AllElemMatchBad) {
TEST(MatchExpressionParserArrayTest, AllElemMatchBadMixed) {
// $elemMatch first, equality second.
BSONObj bad1 = fromjson("{x: {$all: [{$elemMatch: {y: 1}}, 3]}}");
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result1 =
- MatchExpressionParser::parse(bad1, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(bad1, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result1.isOK());
// equality first, $elemMatch second
BSONObj bad2 = fromjson("{x: {$all: [3, {$elemMatch: {y: 1}}]}}");
StatusWithMatchExpression result2 =
- MatchExpressionParser::parse(bad2, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(bad2, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result1.isOK());
// $elemMatch first, object second
BSONObj bad3 = fromjson("{x: {$all: [{$elemMatch: {y: 1}}, {z: 1}]}}");
StatusWithMatchExpression result3 =
- MatchExpressionParser::parse(bad3, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(bad3, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result3.isOK());
// object first, $elemMatch second
BSONObj bad4 = fromjson("{x: {$all: [{z: 1}, {$elemMatch: {y: 1}}]}}");
StatusWithMatchExpression result4 =
- MatchExpressionParser::parse(bad4, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(bad4, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result4.isOK());
}
// $all with empty string.
TEST(MatchExpressionParserArrayTest, AllEmptyString) {
BSONObj query = BSON("x" << BSON("$all" << BSON_ARRAY("")));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(!result.getValue()->matchesBSON(BSON("x"
@@ -695,8 +732,9 @@ TEST(MatchExpressionParserArrayTest, AllISODate) {
const Date_t& notMatch = notMatchResult.getValue();
BSONObj query = BSON("x" << BSON("$all" << BSON_ARRAY(match)));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(!result.getValue()->matchesBSON(BSON("x" << notMatch)));
@@ -711,8 +749,9 @@ TEST(MatchExpressionParserArrayTest, AllISODate) {
// $all on array element with empty string.
TEST(MatchExpressionParserArrayTest, AllDottedEmptyString) {
BSONObj query = BSON("x.1" << BSON("$all" << BSON_ARRAY("")));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(!result.getValue()->matchesBSON(BSON("x"
@@ -738,8 +777,9 @@ TEST(MatchExpressionParserArrayTest, AllDottedISODate) {
const Date_t& notMatch = notMatchResult.getValue();
BSONObj query = BSON("x.1" << BSON("$all" << BSON_ARRAY(match)));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(!result.getValue()->matchesBSON(BSON("x" << notMatch)));
@@ -752,4 +792,32 @@ TEST(MatchExpressionParserArrayTest, AllDottedISODate) {
ASSERT(result.getValue()->matchesBSON(BSON("x" << BSON_ARRAY(BSONNULL << match))));
ASSERT(result.getValue()->matchesBSON(BSON("x" << BSON_ARRAY(BSONObj() << match))));
}
+
+TEST(MatchExpressionParserArrayTest, AllStringNullCollation) {
+ BSONObj query = BSON("x" << BSON("$all" << BSON_ARRAY("string")));
+ CollatorInterface* collator = nullptr;
+ StatusWithMatchExpression result =
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
+ ASSERT_TRUE(result.isOK());
+ ASSERT_EQUALS(MatchExpression::AND, result.getValue()->matchType());
+ ASSERT_EQUALS(1U, result.getValue()->numChildren());
+ MatchExpression* child = result.getValue()->getChild(0);
+ ASSERT_EQUALS(MatchExpression::EQ, child->matchType());
+ EqualityMatchExpression* eqMatch = static_cast<EqualityMatchExpression*>(child);
+ ASSERT_TRUE(eqMatch->getCollator() == collator);
+}
+
+TEST(MatchExpressionParserArrayTest, AllStringCollation) {
+ BSONObj query = BSON("x" << BSON("$all" << BSON_ARRAY("string")));
+ CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
+ StatusWithMatchExpression result =
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), &collator);
+ ASSERT_TRUE(result.isOK());
+ ASSERT_EQUALS(MatchExpression::AND, result.getValue()->matchType());
+ ASSERT_EQUALS(1U, result.getValue()->numChildren());
+ MatchExpression* child = result.getValue()->getChild(0);
+ ASSERT_EQUALS(MatchExpression::EQ, child->matchType());
+ EqualityMatchExpression* eqMatch = static_cast<EqualityMatchExpression*>(child);
+ ASSERT_TRUE(eqMatch->getCollator() == &collator);
+}
}
diff --git a/src/mongo/db/matcher/expression_parser_geo_test.cpp b/src/mongo/db/matcher/expression_parser_geo_test.cpp
index cb2e98942d4..5724cff0d51 100644
--- a/src/mongo/db/matcher/expression_parser_geo_test.cpp
+++ b/src/mongo/db/matcher/expression_parser_geo_test.cpp
@@ -43,8 +43,9 @@ namespace mongo {
TEST(MatchExpressionParserGeo, WithinBox) {
BSONObj query = fromjson("{a:{$within:{$box:[{x: 4, y:4},[6,6]]}}}");
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(!result.getValue()->matchesBSON(fromjson("{a: [3,4]}")));
@@ -59,8 +60,9 @@ TEST(MatchExpressionParserGeoNear, ParseNear) {
"{loc:{$near:{$maxDistance:100, "
"$geometry:{type:\"Point\", coordinates:[0,0]}}}}");
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
MatchExpression* exp = result.getValue().get();
@@ -76,8 +78,10 @@ TEST(MatchExpressionParserGeoNear, ParseNearExtraField) {
"{loc:{$near:{$maxDistance:100, "
"$geometry:{type:\"Point\", coordinates:[0,0]}}, foo: 1}}");
- ASSERT_THROWS(MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()),
- UserException);
+ CollatorInterface* collator = nullptr;
+ ASSERT_THROWS(
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator),
+ UserException);
}
// For $near, $nearSphere, and $geoNear syntax of:
@@ -89,8 +93,9 @@ TEST(MatchExpressionParserGeoNear, ParseNearExtraField) {
TEST(MatchExpressionParserGeoNear, ParseValidNear) {
BSONObj query = fromjson("{loc: {$near: [0,0], $maxDistance: 100, $minDistance: 50}}");
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
MatchExpression* exp = result.getValue().get();
@@ -104,53 +109,66 @@ TEST(MatchExpressionParserGeoNear, ParseValidNear) {
TEST(MatchExpressionParserGeoNear, ParseInvalidNear) {
{
BSONObj query = fromjson("{loc: {$maxDistance: 100, $near: [0,0]}}");
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
{
BSONObj query = fromjson("{loc: {$minDistance: 100, $near: [0,0]}}");
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
{
BSONObj query = fromjson("{loc: {$near: [0,0], $maxDistance: {}}}");
- ASSERT_THROWS(MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()),
- UserException);
+ CollatorInterface* collator = nullptr;
+ ASSERT_THROWS(
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator),
+ UserException);
}
{
BSONObj query = fromjson("{loc: {$near: [0,0], $minDistance: {}}}");
- ASSERT_THROWS(MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()),
- UserException);
+ CollatorInterface* collator = nullptr;
+ ASSERT_THROWS(
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator),
+ UserException);
}
{
BSONObj query = fromjson("{loc: {$near: [0,0], $eq: 40}}");
- ASSERT_THROWS(MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()),
- UserException);
+ CollatorInterface* collator = nullptr;
+ ASSERT_THROWS(
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator),
+ UserException);
}
{
BSONObj query = fromjson("{loc: {$eq: 40, $near: [0,0]}}");
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
{
BSONObj query = fromjson(
"{loc: {$near: [0,0], $geoWithin: {$geometry: {type: \"Polygon\", coordinates: []}}}}");
- ASSERT_THROWS(MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()),
- UserException);
+ CollatorInterface* collator = nullptr;
+ ASSERT_THROWS(
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator),
+ UserException);
}
{
BSONObj query = fromjson("{loc: {$near: {$foo: 1}}}");
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
{
BSONObj query = fromjson("{loc: {$minDistance: 10}}");
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
}
@@ -158,8 +176,9 @@ TEST(MatchExpressionParserGeoNear, ParseInvalidNear) {
TEST(MatchExpressionParserGeoNear, ParseValidGeoNear) {
BSONObj query = fromjson("{loc: {$geoNear: [0,0], $maxDistance: 100, $minDistance: 50}}");
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
MatchExpression* exp = result.getValue().get();
@@ -173,38 +192,47 @@ TEST(MatchExpressionParserGeoNear, ParseValidGeoNear) {
TEST(MatchExpressionParserGeoNear, ParseInvalidGeoNear) {
{
BSONObj query = fromjson("{loc: {$maxDistance: 100, $geoNear: [0,0]}}");
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
{
BSONObj query = fromjson("{loc: {$minDistance: 100, $geoNear: [0,0]}}");
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
{
BSONObj query = fromjson("{loc: {$geoNear: [0,0], $eq: 1}}");
- ASSERT_THROWS(MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()),
- UserException);
+ CollatorInterface* collator = nullptr;
+ ASSERT_THROWS(
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator),
+ UserException);
}
{
BSONObj query = fromjson("{loc: {$geoNear: [0,0], $maxDistance: {}}}");
- ASSERT_THROWS(MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()),
- UserException);
+ CollatorInterface* collator = nullptr;
+ ASSERT_THROWS(
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator),
+ UserException);
}
{
BSONObj query = fromjson("{loc: {$geoNear: [0,0], $minDistance: {}}}");
- ASSERT_THROWS(MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()),
- UserException);
+ CollatorInterface* collator = nullptr;
+ ASSERT_THROWS(
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator),
+ UserException);
}
}
TEST(MatchExpressionParserGeoNear, ParseValidNearSphere) {
BSONObj query = fromjson("{loc: {$nearSphere: [0,0], $maxDistance: 100, $minDistance: 50}}");
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
MatchExpression* exp = result.getValue().get();
@@ -218,30 +246,38 @@ TEST(MatchExpressionParserGeoNear, ParseValidNearSphere) {
TEST(MatchExpressionParserGeoNear, ParseInvalidNearSphere) {
{
BSONObj query = fromjson("{loc: {$maxDistance: 100, $nearSphere: [0,0]}}");
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
{
BSONObj query = fromjson("{loc: {$minDistance: 100, $nearSphere: [0,0]}}");
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
{
BSONObj query = fromjson("{loc: {$nearSphere: [0,0], $maxDistance: {}}}");
- ASSERT_THROWS(MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()),
- UserException);
+ CollatorInterface* collator = nullptr;
+ ASSERT_THROWS(
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator),
+ UserException);
}
{
BSONObj query = fromjson("{loc: {$nearSphere: [0,0], $minDistance: {}}}");
- ASSERT_THROWS(MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()),
- UserException);
+ CollatorInterface* collator = nullptr;
+ ASSERT_THROWS(
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator),
+ UserException);
}
{
BSONObj query = fromjson("{loc: {$nearSphere: [0,0], $eq: 1}}");
- ASSERT_THROWS(MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions()),
- UserException);
+ CollatorInterface* collator = nullptr;
+ ASSERT_THROWS(
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator),
+ UserException);
}
}
diff --git a/src/mongo/db/matcher/expression_parser_leaf_test.cpp b/src/mongo/db/matcher/expression_parser_leaf_test.cpp
index 23eb7e79ac1..b3a3639defd 100644
--- a/src/mongo/db/matcher/expression_parser_leaf_test.cpp
+++ b/src/mongo/db/matcher/expression_parser_leaf_test.cpp
@@ -39,6 +39,7 @@
#include "mongo/db/matcher/expression.h"
#include "mongo/db/matcher/expression_leaf.h"
#include "mongo/db/matcher/extensions_callback_disallow_extensions.h"
+#include "mongo/db/query/collation/collator_interface_mock.h"
#include "mongo/platform/decimal128.h"
#include "mongo/util/log.h"
@@ -47,10 +48,36 @@ namespace mongo {
using std::endl;
using std::string;
+TEST(MatchExpressionParserLeafTest, NullCollation) {
+ BSONObj query = BSON("x"
+ << "string");
+ CollatorInterface* collator = nullptr;
+ StatusWithMatchExpression result =
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
+ ASSERT_TRUE(result.isOK());
+ ASSERT_EQUALS(MatchExpression::EQ, result.getValue()->matchType());
+ EqualityMatchExpression* match = static_cast<EqualityMatchExpression*>(result.getValue().get());
+ ASSERT_TRUE(match->getCollator() == collator);
+}
+
+
+TEST(MatchExpressionParserLeafTest, Collation) {
+ BSONObj query = BSON("x"
+ << "string");
+ CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
+ StatusWithMatchExpression result =
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), &collator);
+ ASSERT_TRUE(result.isOK());
+ ASSERT_EQUALS(MatchExpression::EQ, result.getValue()->matchType());
+ EqualityMatchExpression* match = static_cast<EqualityMatchExpression*>(result.getValue().get());
+ ASSERT_TRUE(match->getCollator() == &collator);
+}
+
TEST(MatchExpressionParserLeafTest, SimpleEQ2) {
BSONObj query = BSON("x" << BSON("$eq" << 2));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(!result.getValue()->matchesBSON(BSON("x" << 1)));
@@ -60,25 +87,78 @@ TEST(MatchExpressionParserLeafTest, SimpleEQ2) {
TEST(MatchExpressionParserLeafTest, SimpleEQUndefined) {
BSONObj query = BSON("x" << BSON("$eq" << BSONUndefined));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
+TEST(MatchExpressionParserLeafTest, EQNullCollation) {
+ BSONObj query = BSON("x" << BSON("$eq"
+ << "string"));
+ CollatorInterface* collator = nullptr;
+ StatusWithMatchExpression result =
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
+ ASSERT_TRUE(result.isOK());
+ ASSERT_EQUALS(MatchExpression::EQ, result.getValue()->matchType());
+ EqualityMatchExpression* match = static_cast<EqualityMatchExpression*>(result.getValue().get());
+ ASSERT_TRUE(match->getCollator() == collator);
+}
+
+
+TEST(MatchExpressionParserLeafTest, EQCollation) {
+ BSONObj query = BSON("x" << BSON("$eq"
+ << "string"));
+ CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
+ StatusWithMatchExpression result =
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), &collator);
+ ASSERT_TRUE(result.isOK());
+ ASSERT_EQUALS(MatchExpression::EQ, result.getValue()->matchType());
+ EqualityMatchExpression* match = static_cast<EqualityMatchExpression*>(result.getValue().get());
+ ASSERT_TRUE(match->getCollator() == &collator);
+}
+
TEST(MatchExpressionParserLeafTest, SimpleGT1) {
BSONObj query = BSON("x" << BSON("$gt" << 2));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(!result.getValue()->matchesBSON(BSON("x" << 2)));
ASSERT(result.getValue()->matchesBSON(BSON("x" << 3)));
}
+TEST(MatchExpressionParserLeafTest, GTNullCollation) {
+ BSONObj query = BSON("x" << BSON("$gt"
+ << "abc"));
+ CollatorInterface* collator = nullptr;
+ StatusWithMatchExpression result =
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
+ ASSERT_TRUE(result.isOK());
+ ASSERT_EQUALS(MatchExpression::GT, result.getValue()->matchType());
+ GTMatchExpression* match = static_cast<GTMatchExpression*>(result.getValue().get());
+ ASSERT_TRUE(match->getCollator() == collator);
+}
+
+
+TEST(MatchExpressionParserLeafTest, GTCollation) {
+ BSONObj query = BSON("x" << BSON("$gt"
+ << "abc"));
+ CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
+ StatusWithMatchExpression result =
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), &collator);
+ ASSERT_TRUE(result.isOK());
+ ASSERT_EQUALS(MatchExpression::GT, result.getValue()->matchType());
+ GTMatchExpression* match = static_cast<GTMatchExpression*>(result.getValue().get());
+ ASSERT_TRUE(match->getCollator() == &collator);
+}
+
TEST(MatchExpressionParserLeafTest, SimpleLT1) {
BSONObj query = BSON("x" << BSON("$lt" << 2));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(result.getValue()->matchesBSON(BSON("x" << 1)));
@@ -86,10 +166,36 @@ TEST(MatchExpressionParserLeafTest, SimpleLT1) {
ASSERT(!result.getValue()->matchesBSON(BSON("x" << 3)));
}
+TEST(MatchExpressionParserLeafTest, LTNullCollation) {
+ BSONObj query = BSON("x" << BSON("$lt"
+ << "abc"));
+ CollatorInterface* collator = nullptr;
+ StatusWithMatchExpression result =
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
+ ASSERT_TRUE(result.isOK());
+ ASSERT_EQUALS(MatchExpression::LT, result.getValue()->matchType());
+ LTMatchExpression* match = static_cast<LTMatchExpression*>(result.getValue().get());
+ ASSERT_TRUE(match->getCollator() == collator);
+}
+
+
+TEST(MatchExpressionParserLeafTest, LTCollation) {
+ BSONObj query = BSON("x" << BSON("$lt"
+ << "abc"));
+ CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
+ StatusWithMatchExpression result =
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), &collator);
+ ASSERT_TRUE(result.isOK());
+ ASSERT_EQUALS(MatchExpression::LT, result.getValue()->matchType());
+ LTMatchExpression* match = static_cast<LTMatchExpression*>(result.getValue().get());
+ ASSERT_TRUE(match->getCollator() == &collator);
+}
+
TEST(MatchExpressionParserLeafTest, SimpleGTE1) {
BSONObj query = BSON("x" << BSON("$gte" << 2));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(!result.getValue()->matchesBSON(BSON("x" << 1)));
@@ -97,10 +203,36 @@ TEST(MatchExpressionParserLeafTest, SimpleGTE1) {
ASSERT(result.getValue()->matchesBSON(BSON("x" << 3)));
}
+TEST(MatchExpressionParserLeafTest, GTENullCollation) {
+ BSONObj query = BSON("x" << BSON("$gte"
+ << "abc"));
+ CollatorInterface* collator = nullptr;
+ StatusWithMatchExpression result =
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
+ ASSERT_TRUE(result.isOK());
+ ASSERT_EQUALS(MatchExpression::GTE, result.getValue()->matchType());
+ GTEMatchExpression* match = static_cast<GTEMatchExpression*>(result.getValue().get());
+ ASSERT_TRUE(match->getCollator() == collator);
+}
+
+
+TEST(MatchExpressionParserLeafTest, GTECollation) {
+ BSONObj query = BSON("x" << BSON("$gte"
+ << "abc"));
+ CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
+ StatusWithMatchExpression result =
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), &collator);
+ ASSERT_TRUE(result.isOK());
+ ASSERT_EQUALS(MatchExpression::GTE, result.getValue()->matchType());
+ GTEMatchExpression* match = static_cast<GTEMatchExpression*>(result.getValue().get());
+ ASSERT_TRUE(match->getCollator() == &collator);
+}
+
TEST(MatchExpressionParserLeafTest, SimpleLTE1) {
BSONObj query = BSON("x" << BSON("$lte" << 2));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(result.getValue()->matchesBSON(BSON("x" << 1)));
@@ -108,10 +240,36 @@ TEST(MatchExpressionParserLeafTest, SimpleLTE1) {
ASSERT(!result.getValue()->matchesBSON(BSON("x" << 3)));
}
+TEST(MatchExpressionParserLeafTest, LTENullCollation) {
+ BSONObj query = BSON("x" << BSON("$lte"
+ << "abc"));
+ CollatorInterface* collator = nullptr;
+ StatusWithMatchExpression result =
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
+ ASSERT_TRUE(result.isOK());
+ ASSERT_EQUALS(MatchExpression::LTE, result.getValue()->matchType());
+ LTEMatchExpression* match = static_cast<LTEMatchExpression*>(result.getValue().get());
+ ASSERT_TRUE(match->getCollator() == collator);
+}
+
+
+TEST(MatchExpressionParserLeafTest, LTECollation) {
+ BSONObj query = BSON("x" << BSON("$lte"
+ << "abc"));
+ CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
+ StatusWithMatchExpression result =
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), &collator);
+ ASSERT_TRUE(result.isOK());
+ ASSERT_EQUALS(MatchExpression::LTE, result.getValue()->matchType());
+ LTEMatchExpression* match = static_cast<LTEMatchExpression*>(result.getValue().get());
+ ASSERT_TRUE(match->getCollator() == &collator);
+}
+
TEST(MatchExpressionParserLeafTest, SimpleNE1) {
BSONObj query = BSON("x" << BSON("$ne" << 2));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(result.getValue()->matchesBSON(BSON("x" << 1)));
@@ -119,37 +277,68 @@ TEST(MatchExpressionParserLeafTest, SimpleNE1) {
ASSERT(result.getValue()->matchesBSON(BSON("x" << 3)));
}
+TEST(MatchExpressionParserLeafTest, NENullCollation) {
+ BSONObj query = BSON("x" << BSON("$ne"
+ << "string"));
+ CollatorInterface* collator = nullptr;
+ StatusWithMatchExpression result =
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
+ ASSERT_TRUE(result.isOK());
+ ASSERT_EQUALS(MatchExpression::NOT, result.getValue()->matchType());
+ MatchExpression* child = result.getValue()->getChild(0);
+ ASSERT_EQUALS(MatchExpression::EQ, child->matchType());
+ EqualityMatchExpression* eqMatch = static_cast<EqualityMatchExpression*>(child);
+ ASSERT_TRUE(eqMatch->getCollator() == collator);
+}
+
+
+TEST(MatchExpressionParserLeafTest, NECollation) {
+ BSONObj query = BSON("x" << BSON("$ne"
+ << "string"));
+ CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
+ StatusWithMatchExpression result =
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), &collator);
+ ASSERT_TRUE(result.isOK());
+ ASSERT_EQUALS(MatchExpression::NOT, result.getValue()->matchType());
+ MatchExpression* child = result.getValue()->getChild(0);
+ ASSERT_EQUALS(MatchExpression::EQ, child->matchType());
+ EqualityMatchExpression* eqMatch = static_cast<EqualityMatchExpression*>(child);
+ ASSERT_TRUE(eqMatch->getCollator() == &collator);
+}
+
TEST(MatchExpressionParserLeafTest, SimpleModBad1) {
BSONObj query = BSON("x" << BSON("$mod" << BSON_ARRAY(3 << 2)));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
query = BSON("x" << BSON("$mod" << BSON_ARRAY(3)));
- result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(!result.isOK());
query = BSON("x" << BSON("$mod" << BSON_ARRAY(3 << 2 << 4)));
- result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(!result.isOK());
query = BSON("x" << BSON("$mod" << BSON_ARRAY("q" << 2)));
- result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(!result.isOK());
query = BSON("x" << BSON("$mod" << 3));
- result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(!result.isOK());
query = BSON("x" << BSON("$mod" << BSON("a" << 1 << "b" << 2)));
- result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(!result.isOK());
}
TEST(MatchExpressionParserLeafTest, SimpleMod1) {
BSONObj query = BSON("x" << BSON("$mod" << BSON_ARRAY(3 << 2)));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(result.getValue()->matchesBSON(BSON("x" << 5)));
@@ -159,8 +348,9 @@ TEST(MatchExpressionParserLeafTest, SimpleMod1) {
TEST(MatchExpressionParserLeafTest, SimpleModNotNumber) {
BSONObj query = BSON("x" << BSON("$mod" << BSON_ARRAY(2 << "r")));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(result.getValue()->matchesBSON(BSON("x" << 2)));
@@ -170,11 +360,59 @@ TEST(MatchExpressionParserLeafTest, SimpleModNotNumber) {
<< "a")));
}
+TEST(MatchExpressionParserLeafTest, IdCollation) {
+ BSONObj query = BSON("$id"
+ << "string");
+ CollatorInterface* collator = nullptr;
+ StatusWithMatchExpression result =
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
+ ASSERT_TRUE(result.isOK());
+ ASSERT_EQUALS(MatchExpression::EQ, result.getValue()->matchType());
+ EqualityMatchExpression* match = static_cast<EqualityMatchExpression*>(result.getValue().get());
+ ASSERT_TRUE(match->getCollator() == collator);
+}
+
+TEST(MatchExpressionParserLeafTest, IdNullCollation) {
+ BSONObj query = BSON("$id"
+ << "string");
+ CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
+ StatusWithMatchExpression result =
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), &collator);
+ ASSERT_TRUE(result.isOK());
+ ASSERT_EQUALS(MatchExpression::EQ, result.getValue()->matchType());
+ EqualityMatchExpression* match = static_cast<EqualityMatchExpression*>(result.getValue().get());
+ ASSERT_TRUE(match->getCollator() == &collator);
+}
+
+TEST(MatchExpressionParserLeafTest, RefCollation) {
+ BSONObj query = BSON("$ref"
+ << "coll");
+ CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
+ StatusWithMatchExpression result =
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), &collator);
+ ASSERT_TRUE(result.isOK());
+ ASSERT_EQUALS(MatchExpression::EQ, result.getValue()->matchType());
+ EqualityMatchExpression* match = static_cast<EqualityMatchExpression*>(result.getValue().get());
+ ASSERT_TRUE(match->getCollator() == nullptr);
+}
+
+TEST(MatchExpressionParserLeafTest, DbCollation) {
+ BSONObj query = BSON("$db"
+ << "db");
+ CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
+ StatusWithMatchExpression result =
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), &collator);
+ ASSERT_TRUE(result.isOK());
+ ASSERT_EQUALS(MatchExpression::EQ, result.getValue()->matchType());
+ EqualityMatchExpression* match = static_cast<EqualityMatchExpression*>(result.getValue().get());
+ ASSERT_TRUE(match->getCollator() == nullptr);
+}
TEST(MatchExpressionParserLeafTest, SimpleIN1) {
BSONObj query = BSON("x" << BSON("$in" << BSON_ARRAY(2 << 3)));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(!result.getValue()->matchesBSON(BSON("x" << 1)));
@@ -182,14 +420,37 @@ TEST(MatchExpressionParserLeafTest, SimpleIN1) {
ASSERT(result.getValue()->matchesBSON(BSON("x" << 3)));
}
+TEST(MatchExpressionParserLeafTest, INNullCollation) {
+ BSONObj query = BSON("x" << BSON("$in" << BSON_ARRAY("string")));
+ CollatorInterface* collator = nullptr;
+ StatusWithMatchExpression result =
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
+ ASSERT_TRUE(result.isOK());
+ ASSERT_EQUALS(MatchExpression::MATCH_IN, result.getValue()->matchType());
+ InMatchExpression* match = static_cast<InMatchExpression*>(result.getValue().get());
+ ASSERT_TRUE(match->getCollator() == collator);
+}
+
+TEST(MatchExpressionParserLeafTest, INCollation) {
+ BSONObj query = BSON("x" << BSON("$in" << BSON_ARRAY("string")));
+ CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
+ StatusWithMatchExpression result =
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), &collator);
+ ASSERT_TRUE(result.isOK());
+ ASSERT_EQUALS(MatchExpression::MATCH_IN, result.getValue()->matchType());
+ InMatchExpression* match = static_cast<InMatchExpression*>(result.getValue().get());
+ ASSERT_TRUE(match->getCollator() == &collator);
+}
+
TEST(MatchExpressionParserLeafTest, INSingleDBRef) {
OID oid = OID::gen();
BSONObj query = BSON("x" << BSON("$in" << BSON_ARRAY(BSON("$ref"
<< "coll"
<< "$id" << oid << "$db"
<< "db"))));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
OID oidx = OID::gen();
@@ -251,8 +512,9 @@ TEST(MatchExpressionParserLeafTest, INMultipleDBRef) {
<< "coll"
<< "$id" << oid << "$db"
<< "db"))));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
OID oidx = OID::gen();
@@ -351,8 +613,9 @@ TEST(MatchExpressionParserLeafTest, INDBRefWithOptionalField1) {
BSONObj query = BSON("x" << BSON("$in" << BSON_ARRAY(BSON("$ref"
<< "coll"
<< "$id" << oid << "foo" << 12345))));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
OID oidx = OID::gen();
@@ -377,57 +640,62 @@ TEST(MatchExpressionParserLeafTest, INInvalidDBRefs) {
// missing $id
BSONObj query = BSON("x" << BSON("$in" << BSON_ARRAY(BSON("$ref"
<< "coll"))));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
- result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
+ result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
// second field is not $id
query = BSON("x" << BSON("$in" << BSON_ARRAY(BSON("$ref"
<< "coll"
<< "$foo" << 1))));
- result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
OID oid = OID::gen();
// missing $ref field
query = BSON("x" << BSON("$in" << BSON_ARRAY(BSON("$id" << oid << "foo" << 3))));
- result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
// missing $id and $ref field
query = BSON("x" << BSON("$in" << BSON_ARRAY(BSON("$db"
<< "test"
<< "foo" << 3))));
- result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
TEST(MatchExpressionParserLeafTest, INExpressionDocument) {
BSONObj query = BSON("x" << BSON("$in" << BSON_ARRAY(BSON("$foo" << 1))));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
TEST(MatchExpressionParserLeafTest, INNotArray) {
BSONObj query = BSON("x" << BSON("$in" << 5));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
TEST(MatchExpressionParserLeafTest, INUndefined) {
BSONObj query = BSON("x" << BSON("$in" << BSON_ARRAY(BSONUndefined)));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
TEST(MatchExpressionParserLeafTest, INNotElemMatch) {
BSONObj query = BSON("x" << BSON("$in" << BSON_ARRAY(BSON("$elemMatch" << 1))));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
@@ -438,16 +706,18 @@ TEST(MatchExpressionParserLeafTest, INRegexTooLong) {
BSONObjBuilder operand;
operand.appendArray("$in", inArray.obj());
BSONObj query = BSON("x" << operand.obj());
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
TEST(MatchExpressionParserLeafTest, INRegexTooLong2) {
string tooLargePattern(50 * 1000, 'z');
BSONObj query = BSON("x" << BSON("$in" << BSON_ARRAY(BSON("$regex" << tooLargePattern))));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
@@ -460,8 +730,9 @@ TEST(MatchExpressionParserLeafTest, INRegexStuff) {
operand.appendArray("$in", inArray.obj());
BSONObj query = BSON("a" << operand.obj());
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
BSONObj matchFirst = BSON("a"
@@ -486,8 +757,9 @@ TEST(MatchExpressionParserLeafTest, INRegexStuff) {
TEST(MatchExpressionParserLeafTest, SimpleNIN1) {
BSONObj query = BSON("x" << BSON("$nin" << BSON_ARRAY(2 << 3)));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(result.getValue()->matchesBSON(BSON("x" << 1)));
@@ -497,18 +769,45 @@ TEST(MatchExpressionParserLeafTest, SimpleNIN1) {
TEST(MatchExpressionParserLeafTest, NINNotArray) {
BSONObj query = BSON("x" << BSON("$nin" << 5));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
+TEST(MatchExpressionParserLeafTest, NINNullCollation) {
+ BSONObj query = BSON("x" << BSON("$nin" << BSON_ARRAY("string")));
+ CollatorInterface* collator = nullptr;
+ StatusWithMatchExpression result =
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
+ ASSERT_TRUE(result.isOK());
+ ASSERT_EQUALS(MatchExpression::NOT, result.getValue()->matchType());
+ MatchExpression* child = result.getValue()->getChild(0);
+ ASSERT_EQUALS(MatchExpression::MATCH_IN, child->matchType());
+ InMatchExpression* inMatch = static_cast<InMatchExpression*>(child);
+ ASSERT_TRUE(inMatch->getCollator() == collator);
+}
+
+TEST(MatchExpressionParserLeafTest, NINCollation) {
+ BSONObj query = BSON("x" << BSON("$nin" << BSON_ARRAY("string")));
+ CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
+ StatusWithMatchExpression result =
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), &collator);
+ ASSERT_TRUE(result.isOK());
+ ASSERT_EQUALS(MatchExpression::NOT, result.getValue()->matchType());
+ MatchExpression* child = result.getValue()->getChild(0);
+ ASSERT_EQUALS(MatchExpression::MATCH_IN, child->matchType());
+ InMatchExpression* inMatch = static_cast<InMatchExpression*>(child);
+ ASSERT_TRUE(inMatch->getCollator() == &collator);
+}
TEST(MatchExpressionParserLeafTest, Regex1) {
BSONObjBuilder b;
b.appendRegex("x", "abc", "i");
BSONObj query = b.obj();
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(result.getValue()->matchesBSON(BSON("x"
@@ -524,8 +823,9 @@ TEST(MatchExpressionParserLeafTest, Regex2) {
<< "abc"
<< "$options"
<< "i"));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(result.getValue()->matchesBSON(BSON("x"
@@ -541,8 +841,9 @@ TEST(MatchExpressionParserLeafTest, Regex3) {
<< "i"
<< "$regex"
<< "abc"));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
log() << "result: " << result.getStatus() << endl;
ASSERT_TRUE(result.isOK());
@@ -560,35 +861,37 @@ TEST(MatchExpressionParserLeafTest, RegexBad) {
<< "abc"
<< "$optionas"
<< "i"));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
// $regex does not with numbers
query = BSON("x" << BSON("$regex" << 123));
- result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
query = BSON("x" << BSON("$regex" << BSON_ARRAY("abc")));
- result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
query = BSON("x" << BSON("$optionas"
<< "i"));
- result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
query = BSON("x" << BSON("$options"
<< "i"));
- result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
TEST(MatchExpressionParserLeafTest, RegexEmbeddedNULByte) {
BSONObj query = BSON("x" << BSON("$regex"
<< "^a\\x00b"));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
StringData value("a\0b", StringData::LiteralTag());
@@ -601,8 +904,9 @@ TEST(MatchExpressionParserLeafTest, ExistsYes1) {
BSONObjBuilder b;
b.appendBool("$exists", true);
BSONObj query = BSON("x" << b.obj());
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(result.getValue()->matchesBSON(BSON("x"
@@ -615,8 +919,9 @@ TEST(MatchExpressionParserLeafTest, ExistsNO1) {
BSONObjBuilder b;
b.appendBool("$exists", false);
BSONObj query = BSON("x" << b.obj());
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(!result.getValue()->matchesBSON(BSON("x"
@@ -627,8 +932,9 @@ TEST(MatchExpressionParserLeafTest, ExistsNO1) {
TEST(MatchExpressionParserLeafTest, Type1) {
BSONObj query = BSON("x" << BSON("$type" << String));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(result.getValue()->matchesBSON(BSON("x"
@@ -638,8 +944,9 @@ TEST(MatchExpressionParserLeafTest, Type1) {
TEST(MatchExpressionParserLeafTest, Type2) {
BSONObj query = BSON("x" << BSON("$type" << (double)NumberDouble));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(result.getValue()->matchesBSON(BSON("x" << 5.3)));
@@ -648,8 +955,9 @@ TEST(MatchExpressionParserLeafTest, Type2) {
TEST(MatchExpressionParserLeafTest, TypeDoubleOperator) {
BSONObj query = BSON("x" << BSON("$type" << 1.5));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(!result.getValue()->matchesBSON(BSON("x" << 5.3)));
@@ -659,8 +967,9 @@ TEST(MatchExpressionParserLeafTest, TypeDoubleOperator) {
TEST(MatchExpressionParserLeafTest, TypeDecimalOperator) {
if (Decimal128::enabled) {
BSONObj query = BSON("x" << BSON("$type" << mongo::NumberDecimal));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT_FALSE(result.getValue()->matchesBSON(BSON("x" << 5.3)));
@@ -670,8 +979,9 @@ TEST(MatchExpressionParserLeafTest, TypeDecimalOperator) {
TEST(MatchExpressionParserLeafTest, TypeNull) {
BSONObj query = BSON("x" << BSON("$type" << jstNULL));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(!result.getValue()->matchesBSON(BSONObj()));
@@ -685,35 +995,44 @@ TEST(MatchExpressionParserLeafTest, TypeBadType) {
BSONObjBuilder b;
b.append("$type", (JSTypeMax + 1));
BSONObj query = BSON("x" << b.obj());
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_NOT_OK(result.getStatus());
}
TEST(MatchExpressionParserLeafTest, TypeBad) {
BSONObj query = BSON("x" << BSON("$type" << BSON("x" << 1)));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
TEST(MatchExpressionParserLeafTest, TypeBadString) {
+ CollatorInterface* collator = nullptr;
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$type: null}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$type: true}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$type: {}}}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(
MatchExpressionParser::parse(fromjson("{a: {$type: ObjectId('000000000000000000000000')}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$type: []}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
}
TEST(MatchExpressionParserLeafTest, TypeStringnameDouble) {
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression typeNumberDouble = MatchExpressionParser::parse(
- fromjson("{a: {$type: 'double'}}"), ExtensionsCallbackDisallowExtensions());
+ fromjson("{a: {$type: 'double'}}"), ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_OK(typeNumberDouble.getStatus());
TypeMatchExpression* tmeNumberDouble =
static_cast<TypeMatchExpression*>(typeNumberDouble.getValue().get());
@@ -724,8 +1043,9 @@ TEST(MatchExpressionParserLeafTest, TypeStringnameDouble) {
TEST(MatchExpressionParserLeafTest, TypeStringNameNumberDecimal) {
if (Decimal128::enabled) {
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression typeNumberDecimal = MatchExpressionParser::parse(
- fromjson("{a: {$type: 'decimal'}}"), ExtensionsCallbackDisallowExtensions());
+ fromjson("{a: {$type: 'decimal'}}"), ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_OK(typeNumberDecimal.getStatus());
TypeMatchExpression* tmeNumberDecimal =
static_cast<TypeMatchExpression*>(typeNumberDecimal.getValue().get());
@@ -736,8 +1056,9 @@ TEST(MatchExpressionParserLeafTest, TypeStringNameNumberDecimal) {
}
TEST(MatchExpressionParserLeafTest, TypeStringnameNumberInt) {
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression typeNumberInt = MatchExpressionParser::parse(
- fromjson("{a: {$type: 'int'}}"), ExtensionsCallbackDisallowExtensions());
+ fromjson("{a: {$type: 'int'}}"), ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_OK(typeNumberInt.getStatus());
TypeMatchExpression* tmeNumberInt =
static_cast<TypeMatchExpression*>(typeNumberInt.getValue().get());
@@ -747,8 +1068,9 @@ TEST(MatchExpressionParserLeafTest, TypeStringnameNumberInt) {
}
TEST(MatchExpressionParserLeafTest, TypeStringnameNumberLong) {
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression typeNumberLong = MatchExpressionParser::parse(
- fromjson("{a: {$type: 'long'}}"), ExtensionsCallbackDisallowExtensions());
+ fromjson("{a: {$type: 'long'}}"), ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_OK(typeNumberLong.getStatus());
TypeMatchExpression* tmeNumberLong =
static_cast<TypeMatchExpression*>(typeNumberLong.getValue().get());
@@ -758,8 +1080,9 @@ TEST(MatchExpressionParserLeafTest, TypeStringnameNumberLong) {
}
TEST(MatchExpressionParserLeafTest, TypeStringnameString) {
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression typeString = MatchExpressionParser::parse(
- fromjson("{a: {$type: 'string'}}"), ExtensionsCallbackDisallowExtensions());
+ fromjson("{a: {$type: 'string'}}"), ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_OK(typeString.getStatus());
TypeMatchExpression* tmeString = static_cast<TypeMatchExpression*>(typeString.getValue().get());
ASSERT(tmeString->getType() == String);
@@ -768,8 +1091,9 @@ TEST(MatchExpressionParserLeafTest, TypeStringnameString) {
}
TEST(MatchExpressionParserLeafTest, TypeStringnamejstOID) {
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression typejstOID = MatchExpressionParser::parse(
- fromjson("{a: {$type: 'objectId'}}"), ExtensionsCallbackDisallowExtensions());
+ fromjson("{a: {$type: 'objectId'}}"), ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_OK(typejstOID.getStatus());
TypeMatchExpression* tmejstOID = static_cast<TypeMatchExpression*>(typejstOID.getValue().get());
ASSERT(tmejstOID->getType() == jstOID);
@@ -778,8 +1102,9 @@ TEST(MatchExpressionParserLeafTest, TypeStringnamejstOID) {
}
TEST(MatchExpressionParserLeafTest, TypeStringnamejstNULL) {
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression typejstNULL = MatchExpressionParser::parse(
- fromjson("{a: {$type: 'null'}}"), ExtensionsCallbackDisallowExtensions());
+ fromjson("{a: {$type: 'null'}}"), ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_OK(typejstNULL.getStatus());
TypeMatchExpression* tmejstNULL =
static_cast<TypeMatchExpression*>(typejstNULL.getValue().get());
@@ -789,8 +1114,9 @@ TEST(MatchExpressionParserLeafTest, TypeStringnamejstNULL) {
}
TEST(MatchExpressionParserLeafTest, TypeStringnameBool) {
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression typeBool = MatchExpressionParser::parse(
- fromjson("{a: {$type: 'bool'}}"), ExtensionsCallbackDisallowExtensions());
+ fromjson("{a: {$type: 'bool'}}"), ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_OK(typeBool.getStatus());
TypeMatchExpression* tmeBool = static_cast<TypeMatchExpression*>(typeBool.getValue().get());
ASSERT(tmeBool->getType() == Bool);
@@ -799,8 +1125,9 @@ TEST(MatchExpressionParserLeafTest, TypeStringnameBool) {
}
TEST(MatchExpressionParserLeafTest, TypeStringnameObject) {
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression typeObject = MatchExpressionParser::parse(
- fromjson("{a: {$type: 'object'}}"), ExtensionsCallbackDisallowExtensions());
+ fromjson("{a: {$type: 'object'}}"), ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_OK(typeObject.getStatus());
TypeMatchExpression* tmeObject = static_cast<TypeMatchExpression*>(typeObject.getValue().get());
ASSERT(tmeObject->getType() == Object);
@@ -809,8 +1136,9 @@ TEST(MatchExpressionParserLeafTest, TypeStringnameObject) {
}
TEST(MatchExpressionParserLeafTest, TypeStringnameArray) {
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression typeArray = MatchExpressionParser::parse(
- fromjson("{a: {$type: 'array'}}"), ExtensionsCallbackDisallowExtensions());
+ fromjson("{a: {$type: 'array'}}"), ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_OK(typeArray.getStatus());
TypeMatchExpression* tmeArray = static_cast<TypeMatchExpression*>(typeArray.getValue().get());
ASSERT(tmeArray->getType() == Array);
@@ -819,8 +1147,9 @@ TEST(MatchExpressionParserLeafTest, TypeStringnameArray) {
}
TEST(MatchExpressionParserLeafTest, TypeStringnameNumber) {
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression typeNumber = MatchExpressionParser::parse(
- fromjson("{a: {$type: 'number'}}"), ExtensionsCallbackDisallowExtensions());
+ fromjson("{a: {$type: 'number'}}"), ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_OK(typeNumber.getStatus());
TypeMatchExpression* tmeNumber = static_cast<TypeMatchExpression*>(typeNumber.getValue().get());
ASSERT_TRUE(tmeNumber->matchesBSON(fromjson("{a: 5.4}")));
@@ -830,20 +1159,23 @@ TEST(MatchExpressionParserLeafTest, TypeStringnameNumber) {
}
TEST(MatchExpressionParserLeafTest, InvalidTypeCodeLessThanMinKeyFailsToParse) {
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression typeNumber = MatchExpressionParser::parse(
- fromjson("{a: {$type: -20}}"), ExtensionsCallbackDisallowExtensions());
+ fromjson("{a: {$type: -20}}"), ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_NOT_OK(typeNumber.getStatus());
}
TEST(MatchExpressionParserLeafTest, InvalidTypeCodeGreaterThanMaxKeyFailsToParse) {
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression typeNumber = MatchExpressionParser::parse(
- fromjson("{a: {$type: 400}}"), ExtensionsCallbackDisallowExtensions());
+ fromjson("{a: {$type: 400}}"), ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_NOT_OK(typeNumber.getStatus());
}
TEST(MatchExpressionParserLeafTest, InvalidTypeCodeUnusedBetweenMinAndMaxFailsToParse) {
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression typeNumber = MatchExpressionParser::parse(
- fromjson("{a: {$type: 62}}"), ExtensionsCallbackDisallowExtensions());
+ fromjson("{a: {$type: 62}}"), ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_NOT_OK(typeNumber.getStatus());
}
@@ -855,8 +1187,9 @@ TEST(MatchExpressionParserLeafTest, ValidTypeCodesParseSuccessfully) {
for (auto type : validTypes) {
BSONObj predicate = BSON("a" << BSON("$type" << type));
- auto expression =
- MatchExpressionParser::parse(predicate, ExtensionsCallbackDisallowExtensions());
+ CollatorInterface* collator = nullptr;
+ auto expression = MatchExpressionParser::parse(
+ predicate, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_OK(expression.getStatus());
auto typeExpression = static_cast<TypeMatchExpression*>(expression.getValue().get());
ASSERT_EQ(type, typeExpression->getType());
@@ -866,45 +1199,62 @@ TEST(MatchExpressionParserLeafTest, ValidTypeCodesParseSuccessfully) {
TEST(MatchExpressionParserTest, BitTestMatchExpressionValidMask) {
const double k2Power53 = scalbn(1, 32);
+ CollatorInterface* collator = nullptr;
ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllSet" << 54)),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(MatchExpressionParser::parse(
BSON("a" << BSON("$bitsAllSet" << std::numeric_limits<long long>::max())),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllSet" << k2Power53)),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllSet" << k2Power53 - 1)),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllClear" << 54)),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(MatchExpressionParser::parse(
BSON("a" << BSON("$bitsAllClear" << std::numeric_limits<long long>::max())),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllClear" << k2Power53)),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllClear" << k2Power53 - 1)),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnySet" << 54)),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(MatchExpressionParser::parse(
BSON("a" << BSON("$bitsAnySet" << std::numeric_limits<long long>::max())),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnySet" << k2Power53)),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnySet" << k2Power53 - 1)),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnyClear" << 54)),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(MatchExpressionParser::parse(
BSON("a" << BSON("$bitsAnyClear" << std::numeric_limits<long long>::max())),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnyClear" << k2Power53)),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnyClear" << k2Power53 - 1)),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
}
TEST(MatchExpressionParserTest, BitTestMatchExpressionValidArray) {
@@ -914,335 +1264,460 @@ TEST(MatchExpressionParserTest, BitTestMatchExpressionValidArray) {
ASSERT_EQ(BSONType::NumberLong, bsonArrayLongLong[2].type());
ASSERT_EQ(BSONType::NumberLong, bsonArrayLongLong[3].type());
+ CollatorInterface* collator = nullptr;
ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllSet" << BSON_ARRAY(0))),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(MatchExpressionParser::parse(
BSON("a" << BSON("$bitsAllSet" << BSON_ARRAY(0 << 1 << 2 << 3))),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllSet" << bsonArrayLongLong)),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(MatchExpressionParser::parse(
BSON("a" << BSON("$bitsAllSet" << BSON_ARRAY(std::numeric_limits<int>::max()))),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllClear" << BSON_ARRAY(0))),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(MatchExpressionParser::parse(
BSON("a" << BSON("$bitsAllClear" << BSON_ARRAY(0 << 1 << 2 << 3))),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllClear" << bsonArrayLongLong)),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(MatchExpressionParser::parse(
BSON("a" << BSON("$bitsAllClear" << BSON_ARRAY(std::numeric_limits<int>::max()))),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnySet" << BSON_ARRAY(0))),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(MatchExpressionParser::parse(
BSON("a" << BSON("$bitsAnySet" << BSON_ARRAY(0 << 1 << 2 << 3))),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnySet" << bsonArrayLongLong)),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(MatchExpressionParser::parse(
BSON("a" << BSON("$bitsAnySet" << BSON_ARRAY(std::numeric_limits<int>::max()))),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnyClear" << BSON_ARRAY(0))),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(MatchExpressionParser::parse(
BSON("a" << BSON("$bitsAnyClear" << BSON_ARRAY(0 << 1 << 2 << 3))),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnyClear" << bsonArrayLongLong)),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(MatchExpressionParser::parse(
BSON("a" << BSON("$bitsAnyClear" << BSON_ARRAY(std::numeric_limits<int>::max()))),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
}
TEST(MatchExpressionParserTest, BitTestMatchExpressionValidBinData) {
+ CollatorInterface* collator = nullptr;
ASSERT_OK(
MatchExpressionParser::parse(
fromjson("{a: {$bitsAllSet: {$binary: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAA', $type: '00'}}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(
MatchExpressionParser::parse(
fromjson(
"{a: {$bitsAllClear: {$binary: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAA', $type: '00'}}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(
MatchExpressionParser::parse(
fromjson("{a: {$bitsAnySet: {$binary: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAA', $type: '00'}}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_OK(
MatchExpressionParser::parse(
fromjson(
"{a: {$bitsAnyClear: {$binary: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAA', $type: '00'}}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
}
TEST(MatchExpressionParserTest, BitTestMatchExpressionInvalidMaskType) {
+ CollatorInterface* collator = nullptr;
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: null}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: true}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: {}}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: ''}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: null}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: true}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: {}}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: ''}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(
fromjson("{a: {$bitsAllClear: ObjectId('000000000000000000000000')}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: null}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: true}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: {}}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: ''}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(
fromjson("{a: {$bitsAnySet: ObjectId('000000000000000000000000')}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: null}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: true}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: {}}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: ''}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(
fromjson("{a: {$bitsAnyClear: ObjectId('000000000000000000000000')}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
}
TEST(MatchExpressionParserTest, BitTestMatchExpressionInvalidMaskValue) {
const double kLongLongMaxAsDouble = scalbn(1, std::numeric_limits<long long>::digits);
+ CollatorInterface* collator = nullptr;
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: NaN}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: -54}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(
BSON("a" << BSON("$bitsAllSet" << std::numeric_limits<double>::max())),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(
MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllSet" << kLongLongMaxAsDouble)),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: 2.5}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: NaN}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: -54}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(
BSON("a" << BSON("$bitsAllClear" << std::numeric_limits<double>::max())),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(
MatchExpressionParser::parse(BSON("a" << BSON("$bitsAllClear" << kLongLongMaxAsDouble)),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: 2.5}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: NaN}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: -54}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(
BSON("a" << BSON("$bitsAnySet" << std::numeric_limits<double>::max())),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(
MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnySet" << kLongLongMaxAsDouble)),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: 2.5}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: NaN}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: -54}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(
BSON("a" << BSON("$bitsAnyClear" << std::numeric_limits<double>::max())),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(
MatchExpressionParser::parse(BSON("a" << BSON("$bitsAnyClear" << kLongLongMaxAsDouble)),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: 2.5}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
}
TEST(MatchExpressionParserTest, BitTestMatchExpressionInvalidArray) {
+ CollatorInterface* collator = nullptr;
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [null]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [true]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: ['']}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [{}]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [[]]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [-1]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [2.5]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(
MatchExpressionParser::parse(
fromjson(
"{a: {$bitsAllSet: [{$binary: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAA', $type: '00'}]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [null]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [true]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: ['']}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [{}]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [[]]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [-1]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [2.5]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(
MatchExpressionParser::parse(
fromjson(
"{a: {$bitsAllClear: [{$binary: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAA', $type: '00'}]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [null]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [true]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: ['']}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [{}]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [[]]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [-1]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [2.5]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(
MatchExpressionParser::parse(
fromjson(
"{a: {$bitsAnySet: [{$binary: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAA', $type: '00'}]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [null]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [true]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: ['']}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [{}]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [[]]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [-1]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [2.5]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(
MatchExpressionParser::parse(
fromjson(
"{a: {$bitsAnyClear: [{$binary: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAA', $type: '00'}]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
}
TEST(MatchExpressionParserTest, BitTestMatchExpressionInvalidArrayValue) {
+ CollatorInterface* collator = nullptr;
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [-54]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [NaN]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [2.5]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [1e100]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllSet: [-1e100]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(
MatchExpressionParser::parse(
BSON("a" << BSON("$bitsAllSet" << BSON_ARRAY(std::numeric_limits<long long>::max()))),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(
MatchExpressionParser::parse(
BSON("a" << BSON("$bitsAllSet" << BSON_ARRAY(std::numeric_limits<long long>::min()))),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [-54]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [NaN]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [2.5]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [1e100]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAllClear: [-1e100]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(
MatchExpressionParser::parse(
BSON("a" << BSON("$bitsAllClear" << BSON_ARRAY(std::numeric_limits<long long>::max()))),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(
MatchExpressionParser::parse(
BSON("a" << BSON("$bitsAllClear" << BSON_ARRAY(std::numeric_limits<long long>::min()))),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [-54]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [NaN]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [2.5]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [1e100]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnySet: [-1e100]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(
MatchExpressionParser::parse(
BSON("a" << BSON("$bitsAnySet" << BSON_ARRAY(std::numeric_limits<long long>::max()))),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(
MatchExpressionParser::parse(
BSON("a" << BSON("$bitsAnySet" << BSON_ARRAY(std::numeric_limits<long long>::min()))),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [-54]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [NaN]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [2.5]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [1e100]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(MatchExpressionParser::parse(fromjson("{a: {$bitsAnyClear: [-1e100]}}"),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(
MatchExpressionParser::parse(
BSON("a" << BSON("$bitsAnyClear" << BSON_ARRAY(std::numeric_limits<long long>::max()))),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
ASSERT_NOT_OK(
MatchExpressionParser::parse(
BSON("a" << BSON("$bitsAnyClear" << BSON_ARRAY(std::numeric_limits<long long>::min()))),
- ExtensionsCallbackDisallowExtensions()).getStatus());
+ ExtensionsCallbackDisallowExtensions(),
+ collator).getStatus());
}
}
diff --git a/src/mongo/db/matcher/expression_parser_test.cpp b/src/mongo/db/matcher/expression_parser_test.cpp
index 0c800d2863b..35b55c0b9f6 100644
--- a/src/mongo/db/matcher/expression_parser_test.cpp
+++ b/src/mongo/db/matcher/expression_parser_test.cpp
@@ -42,8 +42,9 @@ namespace mongo {
TEST(MatchExpressionParserTest, SimpleEQ1) {
BSONObj query = BSON("x" << 2);
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(result.getValue()->matchesBSON(BSON("x" << 2)));
@@ -52,8 +53,9 @@ TEST(MatchExpressionParserTest, SimpleEQ1) {
TEST(MatchExpressionParserTest, Multiple1) {
BSONObj query = BSON("x" << 5 << "y" << BSON("$gt" << 5 << "$lt" << 8));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(result.getValue()->matchesBSON(BSON("x" << 5 << "y" << 7)));
@@ -65,23 +67,25 @@ TEST(MatchExpressionParserTest, Multiple1) {
TEST(AtomicMatchExpressionTest, AtomicOperator1) {
BSONObj query = BSON("x" << 5 << "$atomic" << BSON("$gt" << 5 << "$lt" << 8));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
query = BSON("x" << 5 << "$isolated" << 1);
- result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
query = BSON("x" << 5 << "y" << BSON("$isolated" << 1));
- result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ result = MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
TEST(MatchExpressionParserTest, MinDistanceWithoutNearFailsToParse) {
BSONObj query = fromjson("{loc: {$minDistance: 10}}");
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
diff --git a/src/mongo/db/matcher/expression_parser_tree_test.cpp b/src/mongo/db/matcher/expression_parser_tree_test.cpp
index a5a3413eec2..01e52c33841 100644
--- a/src/mongo/db/matcher/expression_parser_tree_test.cpp
+++ b/src/mongo/db/matcher/expression_parser_tree_test.cpp
@@ -42,8 +42,9 @@ namespace mongo {
TEST(MatchExpressionParserTreeTest, OR1) {
BSONObj query = BSON("$or" << BSON_ARRAY(BSON("x" << 1) << BSON("y" << 2)));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(result.getValue()->matchesBSON(BSON("x" << 1)));
@@ -55,8 +56,9 @@ TEST(MatchExpressionParserTreeTest, OR1) {
TEST(MatchExpressionParserTreeTest, OREmbedded) {
BSONObj query1 = BSON("$or" << BSON_ARRAY(BSON("x" << 1) << BSON("y" << 2)));
BSONObj query2 = BSON("$or" << BSON_ARRAY(query1));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query2, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query2, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(result.getValue()->matchesBSON(BSON("x" << 1)));
@@ -68,8 +70,9 @@ TEST(MatchExpressionParserTreeTest, OREmbedded) {
TEST(MatchExpressionParserTreeTest, AND1) {
BSONObj query = BSON("$and" << BSON_ARRAY(BSON("x" << 1) << BSON("y" << 2)));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(!result.getValue()->matchesBSON(BSON("x" << 1)));
@@ -82,8 +85,9 @@ TEST(MatchExpressionParserTreeTest, AND1) {
TEST(MatchExpressionParserTreeTest, NOREmbedded) {
BSONObj query = BSON("$nor" << BSON_ARRAY(BSON("x" << 1) << BSON("y" << 2)));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(!result.getValue()->matchesBSON(BSON("x" << 1)));
@@ -94,8 +98,9 @@ TEST(MatchExpressionParserTreeTest, NOREmbedded) {
TEST(MatchExpressionParserTreeTest, NOT1) {
BSONObj query = BSON("x" << BSON("$not" << BSON("$gt" << 5)));
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(result.getValue()->matchesBSON(BSON("x" << 2)));
@@ -116,8 +121,9 @@ TEST(MatchExpressionParserTreeTest, MaximumTreeDepthNotExceed) {
}
BSONObj query = fromjson(ss.str());
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT(result.isOK());
}
@@ -135,8 +141,9 @@ TEST(MatchExpressionParserTreeTest, MaximumTreeDepthExceed) {
}
BSONObj query = fromjson(ss.str());
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
@@ -155,8 +162,9 @@ TEST(MatchExpressionParserTreeTest, MaximumTreeDepthExceededNestedNots) {
}
BSONObj query = fromjson(ss.str());
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
@@ -174,8 +182,9 @@ TEST(MatchExpressionParserTreeTest, MaximumTreeDepthExceededNestedElemMatch) {
}
BSONObj query = fromjson(ss.str());
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_FALSE(result.isOK());
}
@@ -183,8 +192,9 @@ TEST(MatchExpressionParserLeafTest, NotRegex1) {
BSONObjBuilder b;
b.appendRegex("$not", "abc", "i");
BSONObj query = BSON("x" << b.obj());
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression result =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(result.isOK());
ASSERT(!result.getValue()->matchesBSON(BSON("x"
diff --git a/src/mongo/db/matcher/expression_serialization_test.cpp b/src/mongo/db/matcher/expression_serialization_test.cpp
index 39a472adef6..43f6f6ebf25 100644
--- a/src/mongo/db/matcher/expression_serialization_test.cpp
+++ b/src/mongo/db/matcher/expression_serialization_test.cpp
@@ -51,8 +51,10 @@ BSONObj serialize(MatchExpression* match) {
}
TEST(SerializeBasic, AndExpressionWithOneChildSerializesCorrectly) {
- Matcher original(fromjson("{$and: [{x: 0}]}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{$and: [{x: 0}]}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{$and: [{x: {$eq: 0}}]}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -64,8 +66,10 @@ TEST(SerializeBasic, AndExpressionWithOneChildSerializesCorrectly) {
}
TEST(SerializeBasic, AndExpressionWithTwoChildrenSerializesCorrectly) {
- Matcher original(fromjson("{$and: [{x: 1}, {x: 2}]}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{$and: [{x: 1}, {x: 2}]}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{$and: [{x: {$eq: 1}}, {x: {$eq: 2}}]}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -77,8 +81,10 @@ TEST(SerializeBasic, AndExpressionWithTwoChildrenSerializesCorrectly) {
}
TEST(SerializeBasic, AndExpressionWithTwoIdenticalChildrenSerializesCorrectly) {
- Matcher original(fromjson("{$and: [{x: 1}, {x: 1}]}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{$and: [{x: 1}, {x: 1}]}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{$and: [{x: {$eq: 1}}, {x: {$eq: 1}}]}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -90,8 +96,10 @@ TEST(SerializeBasic, AndExpressionWithTwoIdenticalChildrenSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionOr) {
- Matcher original(fromjson("{$or: [{x: 'A'}, {x: 'B'}]}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{$or: [{x: 'A'}, {x: 'B'}]}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{$or: [{x: {$eq: 'A'}}, {x: {$eq: 'B'}}]}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -103,9 +111,12 @@ TEST(SerializeBasic, ExpressionOr) {
}
TEST(SerializeBasic, ExpressionElemMatchObjectSerializesCorrectly) {
+ CollatorInterface* collator = nullptr;
Matcher original(fromjson("{x: {$elemMatch: {a: {$gt: 0}, b: {$gt: 0}}}}"),
- ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ ExtensionsCallbackNoop(),
+ collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(),
fromjson("{x: {$elemMatch: {$and: [{a: {$gt: 0}}, {b: {$gt: 0}}]}}}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -118,9 +129,12 @@ TEST(SerializeBasic, ExpressionElemMatchObjectSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionElemMatchObjectWithEmptyStringSerializesCorrectly) {
+ CollatorInterface* collator = nullptr;
Matcher original(fromjson("{'': {$elemMatch: {a: {$gt: 0}, b: {$gt: 0}}}}"),
- ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ ExtensionsCallbackNoop(),
+ collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(),
fromjson("{'': {$elemMatch: {$and: [{a: {$gt: 0}}, {b: {$gt: 0}}]}}}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -133,8 +147,11 @@ TEST(SerializeBasic, ExpressionElemMatchObjectWithEmptyStringSerializesCorrectly
}
TEST(SerializeBasic, ExpressionElemMatchValueSerializesCorrectly) {
- Matcher original(fromjson("{x: {$elemMatch: {$lt: 1, $gt: -1}}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(
+ fromjson("{x: {$elemMatch: {$lt: 1, $gt: -1}}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{x: {$elemMatch: {$lt: 1, $gt: -1}}}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -149,8 +166,11 @@ TEST(SerializeBasic, ExpressionElemMatchValueSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionElemMatchValueWithEmptyStringSerializesCorrectly) {
- Matcher original(fromjson("{x: {$elemMatch: {$lt: 1, $gt: -1}}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(
+ fromjson("{x: {$elemMatch: {$lt: 1, $gt: -1}}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{x: {$elemMatch: {$lt: 1, $gt: -1}}}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -165,8 +185,10 @@ TEST(SerializeBasic, ExpressionElemMatchValueWithEmptyStringSerializesCorrectly)
}
TEST(SerializeBasic, ExpressionSizeSerializesCorrectly) {
- Matcher original(fromjson("{x: {$size: 2}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{x: {$size: 2}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{x: {$size: 2}}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -178,8 +200,10 @@ TEST(SerializeBasic, ExpressionSizeSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionAllSerializesCorrectly) {
- Matcher original(fromjson("{x: {$all: [1, 2]}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{x: {$all: [1, 2]}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{$and: [{x: {$eq: 1}}, {x: {$eq: 2}}]}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -191,8 +215,10 @@ TEST(SerializeBasic, ExpressionAllSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionAllWithEmptyArraySerializesCorrectly) {
- Matcher original(fromjson("{x: {$all: []}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{x: {$all: []}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{x: {$all: []}}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -201,8 +227,11 @@ TEST(SerializeBasic, ExpressionAllWithEmptyArraySerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionAllWithRegex) {
- Matcher original(fromjson("{x: {$all: [/a.b.c/, /.d.e./]}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(
+ fromjson("{x: {$all: [/a.b.c/, /.d.e./]}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{$and: [{x: /a.b.c/}, {x: /.d.e./}]}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -214,8 +243,10 @@ TEST(SerializeBasic, ExpressionAllWithRegex) {
}
TEST(SerializeBasic, ExpressionEqSerializesCorrectly) {
- Matcher original(fromjson("{x: {$eq: {a: 1}}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{x: {$eq: {a: 1}}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{x: {$eq: {a: 1}}}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -230,8 +261,10 @@ TEST(SerializeBasic, ExpressionEqSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionNeSerializesCorrectly) {
- Matcher original(fromjson("{x: {$ne: {a: 1}}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{x: {$ne: {a: 1}}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{$nor: [{x: {$eq: {a: 1}}}]}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -243,8 +276,10 @@ TEST(SerializeBasic, ExpressionNeSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionLtSerializesCorrectly) {
- Matcher original(fromjson("{x: {$lt: 3}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{x: {$lt: 3}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{x: {$lt: 3}}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -256,8 +291,10 @@ TEST(SerializeBasic, ExpressionLtSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionGtSerializesCorrectly) {
- Matcher original(fromjson("{x: {$gt: 3}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{x: {$gt: 3}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{x: {$gt: 3}}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -269,8 +306,10 @@ TEST(SerializeBasic, ExpressionGtSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionGteSerializesCorrectly) {
- Matcher original(fromjson("{x: {$gte: 3}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{x: {$gte: 3}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{x: {$gte: 3}}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -282,8 +321,10 @@ TEST(SerializeBasic, ExpressionGteSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionLteSerializesCorrectly) {
- Matcher original(fromjson("{x: {$lte: 3}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{x: {$lte: 3}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{x: {$lte: 3}}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -295,8 +336,10 @@ TEST(SerializeBasic, ExpressionLteSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionRegexWithObjSerializesCorrectly) {
- Matcher original(fromjson("{x: {$regex: 'a.b'}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{x: {$regex: 'a.b'}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{x: {$regex: 'a.b'}}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -308,8 +351,10 @@ TEST(SerializeBasic, ExpressionRegexWithObjSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionRegexWithValueSerializesCorrectly) {
- Matcher original(fromjson("{x: /a.b/i}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{x: /a.b/i}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{x: {$regex: 'a.b', $options: 'i'}}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -321,8 +366,10 @@ TEST(SerializeBasic, ExpressionRegexWithValueSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionRegexWithValueAndOptionsSerializesCorrectly) {
- Matcher original(fromjson("{x: /a.b/}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{x: /a.b/}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{x: {$regex: 'a.b'}}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -334,8 +381,10 @@ TEST(SerializeBasic, ExpressionRegexWithValueAndOptionsSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionRegexWithEqObjSerializesCorrectly) {
- Matcher original(fromjson("{x: {$eq: {$regex: 'a.b'}}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{x: {$eq: {$regex: 'a.b'}}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{x: {$eq: {$regex: 'a.b'}}}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -350,8 +399,10 @@ TEST(SerializeBasic, ExpressionRegexWithEqObjSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionModSerializesCorrectly) {
- Matcher original(fromjson("{x: {$mod: [2, 1]}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{x: {$mod: [2, 1]}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{x: {$mod: [2, 1]}}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -363,8 +414,10 @@ TEST(SerializeBasic, ExpressionModSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionExistsTrueSerializesCorrectly) {
- Matcher original(fromjson("{x: {$exists: true}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{x: {$exists: true}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{x: {$exists: true}}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -376,8 +429,10 @@ TEST(SerializeBasic, ExpressionExistsTrueSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionExistsFalseSerializesCorrectly) {
- Matcher original(fromjson("{x: {$exists: false}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{x: {$exists: false}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{$nor: [{x: {$exists: true}}]}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -389,8 +444,10 @@ TEST(SerializeBasic, ExpressionExistsFalseSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionInSerializesCorrectly) {
- Matcher original(fromjson("{x: {$in: [1, 2, 3]}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{x: {$in: [1, 2, 3]}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{x: {$in: [1, 2, 3]}}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -405,8 +462,10 @@ TEST(SerializeBasic, ExpressionInSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionInWithEmptyArraySerializesCorrectly) {
- Matcher original(fromjson("{x: {$in: []}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{x: {$in: []}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{x: {$in: []}}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -415,8 +474,10 @@ TEST(SerializeBasic, ExpressionInWithEmptyArraySerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionInWithRegexSerializesCorrectly) {
- Matcher original(fromjson("{x: {$in: [/\\d+/, /\\w+/]}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{x: {$in: [/\\d+/, /\\w+/]}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{x: {$in: [/\\d+/, /\\w+/]}}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -431,8 +492,10 @@ TEST(SerializeBasic, ExpressionInWithRegexSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionNinSerializesCorrectly) {
- Matcher original(fromjson("{x: {$nin: [1, 2, 3]}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{x: {$nin: [1, 2, 3]}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{$nor: [{x: {$in: [1, 2, 3]}}]}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -447,8 +510,10 @@ TEST(SerializeBasic, ExpressionNinSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionBitsAllSetSerializesCorrectly) {
- Matcher original(fromjson("{x: {$bitsAllSet: [1, 3]}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{x: {$bitsAllSet: [1, 3]}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{x: {$bitsAllSet: [1, 3]}}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -460,8 +525,10 @@ TEST(SerializeBasic, ExpressionBitsAllSetSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionBitsAllClearSerializesCorrectly) {
- Matcher original(fromjson("{x: {$bitsAllClear: [1, 3]}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{x: {$bitsAllClear: [1, 3]}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{x: {$bitsAllClear: [1, 3]}}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -473,8 +540,10 @@ TEST(SerializeBasic, ExpressionBitsAllClearSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionBitsAnySetSerializesCorrectly) {
- Matcher original(fromjson("{x: {$bitsAnySet: [1, 3]}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{x: {$bitsAnySet: [1, 3]}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{x: {$bitsAnySet: [1, 3]}}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -486,8 +555,10 @@ TEST(SerializeBasic, ExpressionBitsAnySetSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionBitsAnyClearSerializesCorrectly) {
- Matcher original(fromjson("{x: {$bitsAnyClear: [1, 3]}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{x: {$bitsAnyClear: [1, 3]}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{x: {$bitsAnyClear: [1, 3]}}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -502,8 +573,10 @@ TEST(SerializeBasic, ExpressionBitsAnyClearSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionNotSerializesCorrectly) {
- Matcher original(fromjson("{x: {$not: {$eq: 3}}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{x: {$not: {$eq: 3}}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{$nor: [{$and: [{x: {$eq: 3}}]}]}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -515,8 +588,10 @@ TEST(SerializeBasic, ExpressionNotSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionNotWithMultipleChildrenSerializesCorrectly) {
- Matcher original(fromjson("{x: {$not: {$lt: 1, $gt: 3}}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{x: {$not: {$lt: 1, $gt: 3}}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(),
fromjson("{$nor: [{$and: [{x: {$lt: 1}}, {x: {$gt: 3}}]}]}}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -529,8 +604,11 @@ TEST(SerializeBasic, ExpressionNotWithMultipleChildrenSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionNotWithBitTestSerializesCorrectly) {
- Matcher original(fromjson("{x: {$not: {$bitsAnySet: [1, 3]}}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(
+ fromjson("{x: {$not: {$bitsAnySet: [1, 3]}}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{$nor: [{$and: [{x: {$bitsAnySet: [1, 3]}}]}]}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -542,8 +620,10 @@ TEST(SerializeBasic, ExpressionNotWithBitTestSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionNotWithRegexObjSerializesCorrectly) {
- Matcher original(fromjson("{x: {$not: {$regex: 'a.b'}}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{x: {$not: {$regex: 'a.b'}}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{$nor: [{x: /a.b/}]}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -555,8 +635,10 @@ TEST(SerializeBasic, ExpressionNotWithRegexObjSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionNotWithRegexValueSerializesCorrectly) {
- Matcher original(fromjson("{x: {$not: /a.b/}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{x: {$not: /a.b/}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{$nor: [{x: /a.b/}]}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -568,8 +650,10 @@ TEST(SerializeBasic, ExpressionNotWithRegexValueSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionNotWithRegexValueAndOptionsSerializesCorrectly) {
- Matcher original(fromjson("{x: {$not: /a.b/i}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{x: {$not: /a.b/i}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{$nor: [{x: /a.b/i}]}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -581,12 +665,15 @@ TEST(SerializeBasic, ExpressionNotWithRegexValueAndOptionsSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionNotWithGeoSerializesCorrectly) {
+ CollatorInterface* collator = nullptr;
Matcher original(fromjson(
"{x: {$not: {$geoIntersects: {$geometry: {type: 'Polygon', "
"coordinates: [[[0,0], [5,0], "
"[5, 5], [0, 5], [0, 0]]]}}}}}"),
- ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ ExtensionsCallbackNoop(),
+ collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(),
fromjson(
"{$nor: [{$and: [{x: {$geoIntersects: {$geometry: {type: 'Polygon', coordinates: "
@@ -609,8 +696,11 @@ TEST(SerializeBasic, ExpressionNotWithGeoSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionNorSerializesCorrectly) {
- Matcher original(fromjson("{$nor: [{x: 3}, {x: {$lt: 1}}]}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(
+ fromjson("{$nor: [{x: 3}, {x: {$lt: 1}}]}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{$nor: [{x: {$eq: 3}}, {x: {$lt: 1}}]}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -625,8 +715,10 @@ TEST(SerializeBasic, ExpressionNorSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionTypeSerializesCorrectly) {
- Matcher original(fromjson("{x: {$type: 2}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{x: {$type: 2}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{x: {$type: 2}}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -638,8 +730,10 @@ TEST(SerializeBasic, ExpressionTypeSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionTypeWithNumberSerializesCorrectly) {
- Matcher original(fromjson("{x: {$type: 'number'}}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{x: {$type: 'number'}}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{x: {$type: 'number'}}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -651,8 +745,10 @@ TEST(SerializeBasic, ExpressionTypeWithNumberSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionEmptySerializesCorrectly) {
- Matcher original(fromjson("{}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -661,25 +757,32 @@ TEST(SerializeBasic, ExpressionEmptySerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionWhereSerializesCorrectly) {
- Matcher original(fromjson("{$where: 'this.a == this.b'}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{$where: 'this.a == this.b'}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(),
BSONObjBuilder().appendCodeWScope("$where", "this.a == this.b", BSONObj()).obj());
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
}
TEST(SerializeBasic, ExpressionWhereWithScopeSerializesCorrectly) {
+ CollatorInterface* collator = nullptr;
Matcher original(BSON("$where" << BSONCodeWScope("this.a == this.b", BSON("x" << 3))),
- ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ ExtensionsCallbackNoop(),
+ collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(),
BSON("$where" << BSONCodeWScope("this.a == this.b", BSON("x" << 3))));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
}
TEST(SerializeBasic, ExpressionCommentSerializesCorrectly) {
- Matcher original(fromjson("{$comment: 'Hello'}"), ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ Matcher original(fromjson("{$comment: 'Hello'}"), ExtensionsCallbackNoop(), collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(), fromjson("{}"));
ASSERT_EQ(*reserialized.getQuery(), serialize(reserialized.getMatchExpression()));
@@ -691,12 +794,15 @@ TEST(SerializeBasic, ExpressionCommentSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionGeoWithinSerializesCorrectly) {
+ CollatorInterface* collator = nullptr;
Matcher original(
fromjson(
"{x: {$geoWithin: {$geometry: "
"{type: 'Polygon', coordinates: [[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]]]}}}}"),
- ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ ExtensionsCallbackNoop(),
+ collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(),
fromjson(
"{x: {$geoWithin: {$geometry: {type: 'Polygon', coordinates: [[[0,0], [10,0], "
@@ -711,12 +817,15 @@ TEST(SerializeBasic, ExpressionGeoWithinSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionGeoIntersectsSerializesCorrectly) {
+ CollatorInterface* collator = nullptr;
Matcher original(
fromjson(
"{x: {$geoIntersects: {$geometry: {type: 'Polygon', coordinates: [[[0,0], [5,0], [5, "
"5], [0, 5], [0, 0]]]}}}}"),
- ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ ExtensionsCallbackNoop(),
+ collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(),
fromjson(
"{x: {$geoIntersects: {$geometry: {type: 'Polygon', coordinates: [[[0,0], [5,0], "
@@ -738,12 +847,15 @@ TEST(SerializeBasic, ExpressionGeoIntersectsSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionNearSerializesCorrectly) {
+ CollatorInterface* collator = nullptr;
Matcher original(
fromjson(
"{x: {$near: {$geometry: {type: 'Point', coordinates: [0, 0]}, $maxDistance: 10, "
"$minDistance: 1}}}"),
- ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ ExtensionsCallbackNoop(),
+ collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(),
fromjson(
"{x: {$near: {$geometry: {type: 'Point', coordinates: [0, 0]}, $maxDistance: 10, "
@@ -752,12 +864,15 @@ TEST(SerializeBasic, ExpressionNearSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionNearSphereSerializesCorrectly) {
+ CollatorInterface* collator = nullptr;
Matcher original(
fromjson(
"{x: {$nearSphere: {$geometry: {type: 'Point', coordinates: [0, 0]}, $maxDistance: 10, "
"$minDistance: 1}}}"),
- ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ ExtensionsCallbackNoop(),
+ collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(),
fromjson(
"{x: {$nearSphere: {$geometry: {type: 'Point', coordinates: [0, 0]}, "
@@ -766,9 +881,12 @@ TEST(SerializeBasic, ExpressionNearSphereSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionTextSerializesCorrectly) {
+ CollatorInterface* collator = nullptr;
Matcher original(fromjson("{$text: {$search: 'a', $language: 'en', $caseSensitive: true}}"),
- ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ ExtensionsCallbackNoop(),
+ collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(),
fromjson(
"{$text: {$search: 'a', $language: 'en', $caseSensitive: true, "
@@ -777,9 +895,12 @@ TEST(SerializeBasic, ExpressionTextSerializesCorrectly) {
}
TEST(SerializeBasic, ExpressionTextWithDefaultLanguageSerializesCorrectly) {
+ CollatorInterface* collator = nullptr;
Matcher original(fromjson("{$text: {$search: 'a', $caseSensitive: false}}"),
- ExtensionsCallbackNoop());
- Matcher reserialized(serialize(original.getMatchExpression()), ExtensionsCallbackNoop());
+ ExtensionsCallbackNoop(),
+ collator);
+ Matcher reserialized(
+ serialize(original.getMatchExpression()), ExtensionsCallbackNoop(), collator);
ASSERT_EQ(*reserialized.getQuery(),
fromjson(
"{$text: {$search: 'a', $language: '', $caseSensitive: false, "
diff --git a/src/mongo/db/matcher/matcher.cpp b/src/mongo/db/matcher/matcher.cpp
index c0ed2bf6985..0668848c4ad 100644
--- a/src/mongo/db/matcher/matcher.cpp
+++ b/src/mongo/db/matcher/matcher.cpp
@@ -41,10 +41,12 @@
namespace mongo {
-Matcher::Matcher(const BSONObj& pattern, const ExtensionsCallback& extensionsCallback)
+Matcher::Matcher(const BSONObj& pattern,
+ const ExtensionsCallback& extensionsCallback,
+ CollatorInterface* collator)
: _pattern(pattern) {
StatusWithMatchExpression statusWithMatcher =
- MatchExpressionParser::parse(pattern, extensionsCallback);
+ MatchExpressionParser::parse(pattern, extensionsCallback, collator);
uassert(16810,
mongoutils::str::stream() << "bad query: " << statusWithMatcher.getStatus().toString(),
statusWithMatcher.isOK());
diff --git a/src/mongo/db/matcher/matcher.h b/src/mongo/db/matcher/matcher.h
index 99b54b37a8a..3d64908036e 100644
--- a/src/mongo/db/matcher/matcher.h
+++ b/src/mongo/db/matcher/matcher.h
@@ -41,6 +41,8 @@
namespace mongo {
+class CollatorInterface;
+
/**
* Matcher is a simple wrapper around a BSONObj and the MatchExpression created from it.
*/
@@ -48,7 +50,12 @@ class Matcher {
MONGO_DISALLOW_COPYING(Matcher);
public:
- explicit Matcher(const BSONObj& pattern, const ExtensionsCallback& extensionsCallback);
+ /**
+ * 'collator' must outlive the returned Matcher and any MatchExpression cloned from it.
+ */
+ explicit Matcher(const BSONObj& pattern,
+ const ExtensionsCallback& extensionsCallback,
+ CollatorInterface* collator);
bool matches(const BSONObj& doc, MatchDetails* details = NULL) const;
diff --git a/src/mongo/db/ops/modifier_pull.cpp b/src/mongo/db/ops/modifier_pull.cpp
index 2986af6d86f..f73f853be1d 100644
--- a/src/mongo/db/ops/modifier_pull.cpp
+++ b/src/mongo/db/ops/modifier_pull.cpp
@@ -118,8 +118,9 @@ Status ModifierPull::init(const BSONElement& modExpr, const Options& opts, bool*
// Build the matcher around the object we built above. Currently, we do not allow $pull
// operations to contain $text/$where clauses, so preserving this behaviour.
+ // TODO SERVER-23689: Pass the appropriate CollatorInterface* instead of nullptr.
StatusWithMatchExpression parseResult =
- MatchExpressionParser::parse(_exprObj, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(_exprObj, ExtensionsCallbackDisallowExtensions(), nullptr);
if (!parseResult.isOK()) {
return parseResult.getStatus();
}
diff --git a/src/mongo/db/ops/path_support_test.cpp b/src/mongo/db/ops/path_support_test.cpp
index 310a6eb2f72..a5d5e060de9 100644
--- a/src/mongo/db/ops/path_support_test.cpp
+++ b/src/mongo/db/ops/path_support_test.cpp
@@ -521,7 +521,8 @@ TEST_F(ArrayDoc, NonNumericPathInArray) {
//
static MatchExpression* makeExpr(const BSONObj& exprBSON) {
- return MatchExpressionParser::parse(exprBSON, ExtensionsCallbackDisallowExtensions())
+ CollatorInterface* collator = nullptr;
+ return MatchExpressionParser::parse(exprBSON, ExtensionsCallbackDisallowExtensions(), collator)
.getValue()
.release();
}
diff --git a/src/mongo/db/pipeline/document_source_match.cpp b/src/mongo/db/pipeline/document_source_match.cpp
index 87866267ea2..21f7dab580c 100644
--- a/src/mongo/db/pipeline/document_source_match.cpp
+++ b/src/mongo/db/pipeline/document_source_match.cpp
@@ -357,8 +357,9 @@ bool DocumentSourceMatch::isTextQuery(const BSONObj& query) {
void DocumentSourceMatch::joinMatchWith(intrusive_ptr<DocumentSourceMatch> other) {
_predicate = BSON("$and" << BSON_ARRAY(_predicate << other->getQuery()));
- StatusWithMatchExpression status =
- uassertStatusOK(MatchExpressionParser::parse(_predicate, ExtensionsCallbackNoop()));
+ // TODO SERVER-23349: Pass the appropriate CollatorInterface* instead of nullptr.
+ StatusWithMatchExpression status = uassertStatusOK(
+ MatchExpressionParser::parse(_predicate, ExtensionsCallbackNoop(), nullptr));
_expression = std::move(status.getValue());
}
@@ -492,8 +493,10 @@ void DocumentSourceMatch::addDependencies(DepsTracker* deps) const {
DocumentSourceMatch::DocumentSourceMatch(const BSONObj& query,
const intrusive_ptr<ExpressionContext>& pExpCtx)
: DocumentSource(pExpCtx), _predicate(query.getOwned()), _isTextQuery(isTextQuery(query)) {
- StatusWithMatchExpression status =
- uassertStatusOK(MatchExpressionParser::parse(_predicate, ExtensionsCallbackNoop()));
+ // TODO SERVER-23349: Pass the appropriate CollatorInterface* instead of nullptr.
+ StatusWithMatchExpression status = uassertStatusOK(
+ MatchExpressionParser::parse(_predicate, ExtensionsCallbackNoop(), nullptr));
+
_expression = std::move(status.getValue());
getDependencies(&_dependencies);
}
diff --git a/src/mongo/db/query/canonical_query.cpp b/src/mongo/db/query/canonical_query.cpp
index 5e3f5a2b1a1..5cc41126c79 100644
--- a/src/mongo/db/query/canonical_query.cpp
+++ b/src/mongo/db/query/canonical_query.cpp
@@ -213,8 +213,9 @@ StatusWith<std::unique_ptr<CanonicalQuery>> CanonicalQuery::canonicalize(
std::unique_ptr<LiteParsedQuery> autoLpq(lpq);
// Make MatchExpression.
+ // TODO SERVER-23610: pass our CollatorInterface* instead of nullptr.
StatusWithMatchExpression statusWithMatcher =
- MatchExpressionParser::parse(autoLpq->getFilter(), extensionsCallback);
+ MatchExpressionParser::parse(autoLpq->getFilter(), extensionsCallback, nullptr);
if (!statusWithMatcher.isOK()) {
return statusWithMatcher.getStatus();
}
@@ -292,8 +293,9 @@ StatusWith<std::unique_ptr<CanonicalQuery>> CanonicalQuery::canonicalize(
auto& lpq = lpqStatus.getValue();
// Build a parse tree from the BSONObj in the parsed query.
+ // TODO SERVER-23610: pass our CollatorInterface* instead of nullptr.
StatusWithMatchExpression statusWithMatcher =
- MatchExpressionParser::parse(lpq->getFilter(), extensionsCallback);
+ MatchExpressionParser::parse(lpq->getFilter(), extensionsCallback, nullptr);
if (!statusWithMatcher.isOK()) {
return statusWithMatcher.getStatus();
}
diff --git a/src/mongo/db/query/canonical_query_test.cpp b/src/mongo/db/query/canonical_query_test.cpp
index 50574135059..dcfbefcaf77 100644
--- a/src/mongo/db/query/canonical_query_test.cpp
+++ b/src/mongo/db/query/canonical_query_test.cpp
@@ -51,7 +51,9 @@ static const NamespaceString nss("testdb.testcoll");
* and return the MatchExpression*.
*/
MatchExpression* parseMatchExpression(const BSONObj& obj) {
- StatusWithMatchExpression status = MatchExpressionParser::parse(obj, ExtensionsCallbackNoop());
+ CollatorInterface* collator = nullptr;
+ StatusWithMatchExpression status =
+ MatchExpressionParser::parse(obj, ExtensionsCallbackNoop(), collator);
if (!status.isOK()) {
mongoutils::str::stream ss;
ss << "failed to parse query: " << obj.toString()
diff --git a/src/mongo/db/query/index_bounds_builder_test.cpp b/src/mongo/db/query/index_bounds_builder_test.cpp
index d29500d16cd..3380562599b 100644
--- a/src/mongo/db/query/index_bounds_builder_test.cpp
+++ b/src/mongo/db/query/index_bounds_builder_test.cpp
@@ -59,8 +59,9 @@ double NaN = numeric_limits<double>::quiet_NaN();
* Utility function to create MatchExpression
*/
MatchExpression* parseMatchExpression(const BSONObj& obj) {
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression status =
- MatchExpressionParser::parse(obj, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(obj, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(status.isOK());
MatchExpression* expr(status.getValue().release());
return expr;
diff --git a/src/mongo/db/query/parsed_projection.cpp b/src/mongo/db/query/parsed_projection.cpp
index d8d490c2ab7..621b3ce5bc9 100644
--- a/src/mongo/db/query/parsed_projection.cpp
+++ b/src/mongo/db/query/parsed_projection.cpp
@@ -123,8 +123,9 @@ Status ParsedProjection::make(const BSONObj& spec,
invariant(elemMatchObj.isOwned());
// TODO: Is there a faster way of validating the elemMatchObj?
+ // TODO SERVER-23680: pass the appropriate CollatorInterface* instead of nullptr.
StatusWithMatchExpression statusWithMatcher =
- MatchExpressionParser::parse(elemMatchObj, extensionsCallback);
+ MatchExpressionParser::parse(elemMatchObj, extensionsCallback, nullptr);
if (!statusWithMatcher.isOK()) {
return statusWithMatcher.getStatus();
}
diff --git a/src/mongo/db/query/parsed_projection_test.cpp b/src/mongo/db/query/parsed_projection_test.cpp
index 64c379dacb2..5b246d8f4d4 100644
--- a/src/mongo/db/query/parsed_projection_test.cpp
+++ b/src/mongo/db/query/parsed_projection_test.cpp
@@ -47,8 +47,9 @@ using namespace mongo;
//
unique_ptr<ParsedProjection> createParsedProjection(const BSONObj& query, const BSONObj& projObj) {
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression statusWithMatcher =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT(statusWithMatcher.isOK());
std::unique_ptr<MatchExpression> queryMatchExpr = std::move(statusWithMatcher.getValue());
ParsedProjection* out = NULL;
@@ -75,8 +76,9 @@ unique_ptr<ParsedProjection> createParsedProjection(const char* queryStr, const
void assertInvalidProjection(const char* queryStr, const char* projStr) {
BSONObj query = fromjson(queryStr);
BSONObj projObj = fromjson(projStr);
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression statusWithMatcher =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT(statusWithMatcher.isOK());
std::unique_ptr<MatchExpression> queryMatchExpr = std::move(statusWithMatcher.getValue());
ParsedProjection* out = NULL;
diff --git a/src/mongo/db/query/plan_cache_indexability_test.cpp b/src/mongo/db/query/plan_cache_indexability_test.cpp
index bef185e8503..9d64ea157c2 100644
--- a/src/mongo/db/query/plan_cache_indexability_test.cpp
+++ b/src/mongo/db/query/plan_cache_indexability_test.cpp
@@ -36,8 +36,9 @@ namespace mongo {
namespace {
std::unique_ptr<MatchExpression> parseMatchExpression(const BSONObj& obj) {
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression status =
- MatchExpressionParser::parse(obj, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(obj, ExtensionsCallbackDisallowExtensions(), collator);
if (!status.isOK()) {
FAIL(str::stream() << "failed to parse query: " << obj.toString()
<< ". Reason: " << status.getStatus().toString());
diff --git a/src/mongo/db/query/plan_cache_test.cpp b/src/mongo/db/query/plan_cache_test.cpp
index 48aa9b2bb89..51ae170d3ae 100644
--- a/src/mongo/db/query/plan_cache_test.cpp
+++ b/src/mongo/db/query/plan_cache_test.cpp
@@ -151,8 +151,9 @@ unique_ptr<CanonicalQuery> canonicalize(const char* queryStr,
* Utility function to create MatchExpression
*/
unique_ptr<MatchExpression> parseMatchExpression(const BSONObj& obj) {
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression status =
- MatchExpressionParser::parse(obj, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(obj, ExtensionsCallbackDisallowExtensions(), collator);
if (!status.isOK()) {
str::stream ss;
ss << "failed to parse query: " << obj.toString()
diff --git a/src/mongo/db/query/planner_ixselect_test.cpp b/src/mongo/db/query/planner_ixselect_test.cpp
index 934079fcf24..47c64a049ae 100644
--- a/src/mongo/db/query/planner_ixselect_test.cpp
+++ b/src/mongo/db/query/planner_ixselect_test.cpp
@@ -53,8 +53,9 @@ using std::vector;
* Utility function to create MatchExpression
*/
unique_ptr<MatchExpression> parseMatchExpression(const BSONObj& obj) {
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression status =
- MatchExpressionParser::parse(obj, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(obj, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_TRUE(status.isOK());
return std::move(status.getValue());
}
diff --git a/src/mongo/db/query/query_planner_test_fixture.cpp b/src/mongo/db/query/query_planner_test_fixture.cpp
index e690d5ff48b..288c010c8dd 100644
--- a/src/mongo/db/query/query_planner_test_fixture.cpp
+++ b/src/mongo/db/query/query_planner_test_fixture.cpp
@@ -374,8 +374,9 @@ void QueryPlannerTest::assertHasOneSolutionOf(const std::vector<std::string>& so
}
std::unique_ptr<MatchExpression> QueryPlannerTest::parseMatchExpression(const BSONObj& obj) {
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression status =
- MatchExpressionParser::parse(obj, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(obj, ExtensionsCallbackDisallowExtensions(), collator);
if (!status.isOK()) {
FAIL(str::stream() << "failed to parse query: " << obj.toString()
<< ". Reason: " << status.getStatus().toString());
diff --git a/src/mongo/db/query/query_planner_test_lib.cpp b/src/mongo/db/query/query_planner_test_lib.cpp
index fe9daeffaae..ba0bc5d569a 100644
--- a/src/mongo/db/query/query_planner_test_lib.cpp
+++ b/src/mongo/db/query/query_planner_test_lib.cpp
@@ -52,8 +52,9 @@ bool filterMatches(const BSONObj& testFilter, const QuerySolutionNode* trueFilte
if (NULL == trueFilterNode->filter) {
return false;
}
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression statusWithMatcher =
- MatchExpressionParser::parse(testFilter, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(testFilter, ExtensionsCallbackDisallowExtensions(), collator);
if (!statusWithMatcher.isOK()) {
return false;
}
diff --git a/src/mongo/db/query/query_solution_test.cpp b/src/mongo/db/query/query_solution_test.cpp
index ed7b4cdf615..913a76609f0 100644
--- a/src/mongo/db/query/query_solution_test.cpp
+++ b/src/mongo/db/query/query_solution_test.cpp
@@ -251,8 +251,9 @@ TEST(QuerySolutionTest, IntervalListSomePoints) {
std::unique_ptr<ParsedProjection> createParsedProjection(const BSONObj& query,
const BSONObj& projObj) {
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression queryMatchExpr =
- MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions());
+ MatchExpressionParser::parse(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT(queryMatchExpr.isOK());
ParsedProjection* out = nullptr;
Status status = ParsedProjection::make(
diff --git a/src/mongo/dbtests/matchertests.cpp b/src/mongo/dbtests/matchertests.cpp
index ef4c6498384..ce24738b325 100644
--- a/src/mongo/dbtests/matchertests.cpp
+++ b/src/mongo/dbtests/matchertests.cpp
@@ -39,6 +39,8 @@
#include "mongo/db/matcher/extensions_callback_disallow_extensions.h"
#include "mongo/db/matcher/extensions_callback_real.h"
#include "mongo/db/matcher/matcher.h"
+#include "mongo/db/operation_context_impl.h"
+#include "mongo/db/query/collation/collator_interface_mock.h"
#include "mongo/dbtests/dbtests.h"
#include "mongo/util/timer.h"
@@ -60,7 +62,8 @@ class Basic {
public:
void run() {
BSONObj query = fromjson("{\"a\":\"b\"}");
- M m(query, ExtensionsCallbackDisallowExtensions());
+ CollatorInterface* collator = nullptr;
+ M m(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT(m.matches(fromjson("{\"a\":\"b\"}")));
}
};
@@ -70,7 +73,8 @@ class DoubleEqual {
public:
void run() {
BSONObj query = fromjson("{\"a\":5}");
- M m(query, ExtensionsCallbackDisallowExtensions());
+ CollatorInterface* collator = nullptr;
+ M m(query, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT(m.matches(fromjson("{\"a\":5}")));
}
};
@@ -81,7 +85,8 @@ public:
void run() {
BSONObjBuilder query;
query.append("a", 5);
- M m(query.done(), ExtensionsCallbackDisallowExtensions());
+ CollatorInterface* collator = nullptr;
+ M m(query.done(), ExtensionsCallbackDisallowExtensions(), collator);
ASSERT(m.matches(fromjson("{\"a\":5}")));
}
};
@@ -91,7 +96,8 @@ class MixedNumericGt {
public:
void run() {
BSONObj query = fromjson("{\"a\":{\"$gt\":4}}");
- M m(query, ExtensionsCallbackDisallowExtensions());
+ CollatorInterface* collator = nullptr;
+ M m(query, ExtensionsCallbackDisallowExtensions(), collator);
BSONObjBuilder b;
b.append("a", 5);
ASSERT(m.matches(b.done()));
@@ -106,7 +112,8 @@ public:
ASSERT_EQUALS(4, query["a"].embeddedObject()["$in"].embeddedObject()["0"].number());
ASSERT_EQUALS(NumberInt, query["a"].embeddedObject()["$in"].embeddedObject()["0"].type());
- M m(query, ExtensionsCallbackDisallowExtensions());
+ CollatorInterface* collator = nullptr;
+ M m(query, ExtensionsCallbackDisallowExtensions(), collator);
{
BSONObjBuilder b;
@@ -133,7 +140,8 @@ template <typename M>
class MixedNumericEmbedded {
public:
void run() {
- M m(BSON("a" << BSON("x" << 1)), ExtensionsCallbackDisallowExtensions());
+ CollatorInterface* collator = nullptr;
+ M m(BSON("a" << BSON("x" << 1)), ExtensionsCallbackDisallowExtensions(), collator);
ASSERT(m.matches(BSON("a" << BSON("x" << 1))));
ASSERT(m.matches(BSON("a" << BSON("x" << 1.0))));
}
@@ -143,7 +151,8 @@ template <typename M>
class Size {
public:
void run() {
- M m(fromjson("{a:{$size:4}}"), ExtensionsCallbackDisallowExtensions());
+ CollatorInterface* collator = nullptr;
+ M m(fromjson("{a:{$size:4}}"), ExtensionsCallbackDisallowExtensions(), collator);
ASSERT(m.matches(fromjson("{a:[1,2,3,4]}")));
ASSERT(!m.matches(fromjson("{a:[1,2,3]}")));
ASSERT(!m.matches(fromjson("{a:[1,2,3,'a','b']}")));
@@ -155,8 +164,10 @@ template <typename M>
class WithinBox {
public:
void run() {
+ CollatorInterface* collator = nullptr;
M m(fromjson("{loc:{$within:{$box:[{x: 4, y:4},[6,6]]}}}"),
- ExtensionsCallbackDisallowExtensions());
+ ExtensionsCallbackDisallowExtensions(),
+ collator);
ASSERT(!m.matches(fromjson("{loc: [3,4]}")));
ASSERT(m.matches(fromjson("{loc: [4,4]}")));
ASSERT(m.matches(fromjson("{loc: [5,5]}")));
@@ -169,8 +180,10 @@ template <typename M>
class WithinPolygon {
public:
void run() {
+ CollatorInterface* collator = nullptr;
M m(fromjson("{loc:{$within:{$polygon:[{x:0,y:0},[0,5],[5,5],[5,0]]}}}"),
- ExtensionsCallbackDisallowExtensions());
+ ExtensionsCallbackDisallowExtensions(),
+ collator);
ASSERT(m.matches(fromjson("{loc: [3,4]}")));
ASSERT(m.matches(fromjson("{loc: [4,4]}")));
ASSERT(m.matches(fromjson("{loc: {x:5,y:5}}")));
@@ -183,8 +196,10 @@ template <typename M>
class WithinCenter {
public:
void run() {
+ CollatorInterface* collator = nullptr;
M m(fromjson("{loc:{$within:{$center:[{x:30,y:30},10]}}}"),
- ExtensionsCallbackDisallowExtensions());
+ ExtensionsCallbackDisallowExtensions(),
+ collator);
ASSERT(!m.matches(fromjson("{loc: [3,4]}")));
ASSERT(m.matches(fromjson("{loc: {x:30,y:30}}")));
ASSERT(m.matches(fromjson("{loc: [20,30]}")));
@@ -200,7 +215,8 @@ template <typename M>
class ElemMatchKey {
public:
void run() {
- M matcher(BSON("a.b" << 1), ExtensionsCallbackDisallowExtensions());
+ CollatorInterface* collator = nullptr;
+ M matcher(BSON("a.b" << 1), ExtensionsCallbackDisallowExtensions(), collator);
MatchDetails details;
details.requestElemMatchKey();
ASSERT(!details.hasElemMatchKey());
@@ -220,9 +236,11 @@ public:
const NamespaceString nss("unittests.matchertests");
AutoGetCollectionForRead ctx(&txn, nss);
+ CollatorInterface* collator = nullptr;
M m(BSON("$where"
<< "function(){ return this.a == 1; }"),
- ExtensionsCallbackReal(&txn, &nss));
+ ExtensionsCallbackReal(&txn, &nss),
+ collator);
ASSERT(m.matches(BSON("a" << 1)));
ASSERT(!m.matches(BSON("a" << 2)));
}
@@ -232,7 +250,8 @@ template <typename M>
class TimingBase {
public:
long dotime(const BSONObj& patt, const BSONObj& obj) {
- M m(patt, ExtensionsCallbackDisallowExtensions());
+ CollatorInterface* collator = nullptr;
+ M m(patt, ExtensionsCallbackDisallowExtensions(), collator);
Timer t;
for (int i = 0; i < 900000; i++) {
if (!m.matches(obj)) {
@@ -257,6 +276,35 @@ public:
}
};
+/** Test that 'collator' is passed to MatchExpressionParser::parse(). */
+template <typename M>
+class NullCollator {
+public:
+ void run() {
+ CollatorInterface* collator = nullptr;
+ M matcher(BSON("a"
+ << "string"),
+ ExtensionsCallbackDisallowExtensions(),
+ collator);
+ ASSERT(!matcher.matches(BSON("a"
+ << "string2")));
+ }
+};
+
+/** Test that 'collator' is passed to MatchExpressionParser::parse(). */
+template <typename M>
+class Collator {
+public:
+ void run() {
+ CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
+ M matcher(BSON("a"
+ << "string"),
+ ExtensionsCallbackDisallowExtensions(),
+ &collator);
+ ASSERT(matcher.matches(BSON("a"
+ << "string2")));
+ }
+};
class All : public Suite {
public:
@@ -278,6 +326,8 @@ public:
ADD_BOTH(WithinBox);
ADD_BOTH(WithinCenter);
ADD_BOTH(WithinPolygon);
+ ADD_BOTH(NullCollator);
+ ADD_BOTH(Collator);
}
};
diff --git a/src/mongo/dbtests/query_stage_collscan.cpp b/src/mongo/dbtests/query_stage_collscan.cpp
index c233155af77..cac7a702028 100644
--- a/src/mongo/dbtests/query_stage_collscan.cpp
+++ b/src/mongo/dbtests/query_stage_collscan.cpp
@@ -90,8 +90,9 @@ public:
params.tailable = false;
// Make the filter.
- StatusWithMatchExpression statusWithMatcher =
- MatchExpressionParser::parse(filterObj, ExtensionsCallbackDisallowExtensions());
+ CollatorInterface* collator = nullptr;
+ StatusWithMatchExpression statusWithMatcher = MatchExpressionParser::parse(
+ filterObj, ExtensionsCallbackDisallowExtensions(), collator);
verify(statusWithMatcher.isOK());
unique_ptr<MatchExpression> filterExpr = std::move(statusWithMatcher.getValue());
diff --git a/src/mongo/dbtests/query_stage_count.cpp b/src/mongo/dbtests/query_stage_count.cpp
index f325004216f..82a645bdcde 100644
--- a/src/mongo/dbtests/query_stage_count.cpp
+++ b/src/mongo/dbtests/query_stage_count.cpp
@@ -145,8 +145,9 @@ public:
unique_ptr<WorkingSet> ws(new WorkingSet);
+ CollatorInterface* collator = nullptr;
StatusWithMatchExpression statusWithMatcher = MatchExpressionParser::parse(
- request.getQuery(), ExtensionsCallbackDisallowExtensions());
+ request.getQuery(), ExtensionsCallbackDisallowExtensions(), collator);
ASSERT(statusWithMatcher.isOK());
unique_ptr<MatchExpression> expression = std::move(statusWithMatcher.getValue());
diff --git a/src/mongo/dbtests/query_stage_fetch.cpp b/src/mongo/dbtests/query_stage_fetch.cpp
index 451b4b3069a..60158a3fd92 100644
--- a/src/mongo/dbtests/query_stage_fetch.cpp
+++ b/src/mongo/dbtests/query_stage_fetch.cpp
@@ -195,8 +195,9 @@ public:
// Make the filter.
BSONObj filterObj = BSON("foo" << 6);
- StatusWithMatchExpression statusWithMatcher =
- MatchExpressionParser::parse(filterObj, ExtensionsCallbackDisallowExtensions());
+ CollatorInterface* collator = nullptr;
+ StatusWithMatchExpression statusWithMatcher = MatchExpressionParser::parse(
+ filterObj, ExtensionsCallbackDisallowExtensions(), collator);
verify(statusWithMatcher.isOK());
unique_ptr<MatchExpression> filterExpr = std::move(statusWithMatcher.getValue());
diff --git a/src/mongo/dbtests/query_stage_multiplan.cpp b/src/mongo/dbtests/query_stage_multiplan.cpp
index 4056c439545..250eb5c380f 100644
--- a/src/mongo/dbtests/query_stage_multiplan.cpp
+++ b/src/mongo/dbtests/query_stage_multiplan.cpp
@@ -149,8 +149,9 @@ public:
// Make the filter.
BSONObj filterObj = BSON("foo" << 7);
- StatusWithMatchExpression statusWithMatcher =
- MatchExpressionParser::parse(filterObj, ExtensionsCallbackDisallowExtensions());
+ CollatorInterface* collator = nullptr;
+ StatusWithMatchExpression statusWithMatcher = MatchExpressionParser::parse(
+ filterObj, ExtensionsCallbackDisallowExtensions(), collator);
verify(statusWithMatcher.isOK());
unique_ptr<MatchExpression> filter = std::move(statusWithMatcher.getValue());
// Make the stage.
diff --git a/src/mongo/dbtests/query_stage_subplan.cpp b/src/mongo/dbtests/query_stage_subplan.cpp
index a5253a5ee94..09f27a679e4 100644
--- a/src/mongo/dbtests/query_stage_subplan.cpp
+++ b/src/mongo/dbtests/query_stage_subplan.cpp
@@ -447,8 +447,9 @@ public:
// Rewrite (AND (OR a b) e) => (OR (AND a e) (AND b e))
{
BSONObj queryObj = fromjson("{$or:[{a:1}, {b:1}], e:1}");
- StatusWithMatchExpression expr =
- MatchExpressionParser::parse(queryObj, ExtensionsCallbackDisallowExtensions());
+ CollatorInterface* collator = nullptr;
+ StatusWithMatchExpression expr = MatchExpressionParser::parse(
+ queryObj, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_OK(expr.getStatus());
std::unique_ptr<MatchExpression> rewrittenExpr =
SubplanStage::rewriteToRootedOr(std::move(expr.getValue()));
@@ -464,8 +465,9 @@ public:
// Rewrite (AND (OR a b) e f) => (OR (AND a e f) (AND b e f))
{
BSONObj queryObj = fromjson("{$or:[{a:1}, {b:1}], e:1, f:1}");
- StatusWithMatchExpression expr =
- MatchExpressionParser::parse(queryObj, ExtensionsCallbackDisallowExtensions());
+ CollatorInterface* collator = nullptr;
+ StatusWithMatchExpression expr = MatchExpressionParser::parse(
+ queryObj, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_OK(expr.getStatus());
std::unique_ptr<MatchExpression> rewrittenExpr =
SubplanStage::rewriteToRootedOr(std::move(expr.getValue()));
@@ -481,8 +483,9 @@ public:
// Rewrite (AND (OR (AND a b) (AND c d) e f) => (OR (AND a b e f) (AND c d e f))
{
BSONObj queryObj = fromjson("{$or:[{a:1,b:1}, {c:1,d:1}], e:1,f:1}");
- StatusWithMatchExpression expr =
- MatchExpressionParser::parse(queryObj, ExtensionsCallbackDisallowExtensions());
+ CollatorInterface* collator = nullptr;
+ StatusWithMatchExpression expr = MatchExpressionParser::parse(
+ queryObj, ExtensionsCallbackDisallowExtensions(), collator);
ASSERT_OK(expr.getStatus());
std::unique_ptr<MatchExpression> rewrittenExpr =
SubplanStage::rewriteToRootedOr(std::move(expr.getValue()));
diff --git a/src/mongo/dbtests/query_stage_tests.cpp b/src/mongo/dbtests/query_stage_tests.cpp
index 5e3bdbb50fc..acd5010e01c 100644
--- a/src/mongo/dbtests/query_stage_tests.cpp
+++ b/src/mongo/dbtests/query_stage_tests.cpp
@@ -80,8 +80,9 @@ public:
int countResults(const IndexScanParams& params, BSONObj filterObj = BSONObj()) {
AutoGetCollectionForRead ctx(&_txn, ns());
- StatusWithMatchExpression statusWithMatcher =
- MatchExpressionParser::parse(filterObj, ExtensionsCallbackDisallowExtensions());
+ CollatorInterface* collator = nullptr;
+ StatusWithMatchExpression statusWithMatcher = MatchExpressionParser::parse(
+ filterObj, ExtensionsCallbackDisallowExtensions(), collator);
verify(statusWithMatcher.isOK());
unique_ptr<MatchExpression> filterExpr = std::move(statusWithMatcher.getValue());