summaryrefslogtreecommitdiff
path: root/src/mongo/db/query/parsed_projection_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/query/parsed_projection_test.cpp')
-rw-r--r--src/mongo/db/query/parsed_projection_test.cpp481
1 files changed, 0 insertions, 481 deletions
diff --git a/src/mongo/db/query/parsed_projection_test.cpp b/src/mongo/db/query/parsed_projection_test.cpp
deleted file mode 100644
index 8994723a62d..00000000000
--- a/src/mongo/db/query/parsed_projection_test.cpp
+++ /dev/null
@@ -1,481 +0,0 @@
-/**
- * Copyright (C) 2018-present MongoDB, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the Server Side Public License, version 1,
- * as published by MongoDB, Inc.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * Server Side Public License for more details.
- *
- * You should have received a copy of the Server Side Public License
- * along with this program. If not, see
- * <http://www.mongodb.com/licensing/server-side-public-license>.
- *
- * As a special exception, the copyright holders give permission to link the
- * code of portions of this program with the OpenSSL library under certain
- * conditions as described in each individual source file and distribute
- * linked combinations including the program with the OpenSSL library. You
- * must comply with the Server Side Public License in all respects for
- * all of the code used other than as permitted herein. If you modify file(s)
- * with this exception, you may extend this exception to your version of the
- * file(s), but you are not obligated to do so. If you do not wish to do so,
- * delete this exception statement from your version. If you delete this
- * exception statement from all source files in the program, then also delete
- * it in the license file.
- */
-
-#include "mongo/db/query/parsed_projection.h"
-
-#include "mongo/db/json.h"
-#include "mongo/db/matcher/expression_always_boolean.h"
-#include "mongo/db/matcher/expression_parser.h"
-#include "mongo/db/query/query_test_service_context.h"
-#include "mongo/unittest/unittest.h"
-#include <memory>
-
-namespace {
-
-using std::string;
-using std::unique_ptr;
-using std::vector;
-
-using namespace mongo;
-
-//
-// creation function
-//
-
-unique_ptr<ParsedProjection> createParsedProjection(const BSONObj& query, const BSONObj& projObj) {
- QueryTestServiceContext serviceCtx;
- auto opCtx = serviceCtx.makeOperationContext();
- const CollatorInterface* collator = nullptr;
- const boost::intrusive_ptr<ExpressionContext> expCtx(
- new ExpressionContext(opCtx.get(), collator));
- StatusWithMatchExpression statusWithMatcher =
- MatchExpressionParser::parse(query, std::move(expCtx));
- ASSERT(statusWithMatcher.isOK());
- std::unique_ptr<MatchExpression> queryMatchExpr = std::move(statusWithMatcher.getValue());
- ParsedProjection* out = nullptr;
- Status status = ParsedProjection::make(opCtx.get(), projObj, queryMatchExpr.get(), &out);
- if (!status.isOK()) {
- FAIL(str::stream() << "failed to parse projection " << projObj << " (query: " << query
- << "): " << status.toString());
- }
- ASSERT(out);
- return unique_ptr<ParsedProjection>(out);
-}
-
-unique_ptr<ParsedProjection> createParsedProjection(const char* queryStr, const char* projStr) {
- BSONObj query = fromjson(queryStr);
- BSONObj projObj = fromjson(projStr);
- return createParsedProjection(query, projObj);
-}
-
-//
-// Failure to create a parsed projection is expected
-//
-
-void assertInvalidProjection(const char* queryStr, const char* projStr) {
- BSONObj query = fromjson(queryStr);
- BSONObj projObj = fromjson(projStr);
- QueryTestServiceContext serviceCtx;
- auto opCtx = serviceCtx.makeOperationContext();
- const CollatorInterface* collator = nullptr;
- const boost::intrusive_ptr<ExpressionContext> expCtx(
- new ExpressionContext(opCtx.get(), collator));
- StatusWithMatchExpression statusWithMatcher =
- MatchExpressionParser::parse(query, std::move(expCtx));
- ASSERT(statusWithMatcher.isOK());
- std::unique_ptr<MatchExpression> queryMatchExpr = std::move(statusWithMatcher.getValue());
- ParsedProjection* out = nullptr;
- Status status = ParsedProjection::make(opCtx.get(), projObj, queryMatchExpr.get(), &out);
- std::unique_ptr<ParsedProjection> destroy(out);
- ASSERT(!status.isOK());
-}
-
-// canonical_query.cpp will invoke ParsedProjection::make only when
-// the projection spec is non-empty. This test case is included for
-// completeness and do not reflect actual usage.
-TEST(ParsedProjectionTest, MakeId) {
- unique_ptr<ParsedProjection> parsedProj(createParsedProjection("{}", "{}"));
- ASSERT(parsedProj->requiresDocument());
-}
-
-TEST(ParsedProjectionTest, MakeEmpty) {
- unique_ptr<ParsedProjection> parsedProj(createParsedProjection("{}", "{_id: 0}"));
- ASSERT(parsedProj->requiresDocument());
-}
-
-TEST(ParsedProjectionTest, MakeSingleField) {
- unique_ptr<ParsedProjection> parsedProj(createParsedProjection("{}", "{a: 1}"));
- ASSERT(!parsedProj->requiresDocument());
- const vector<StringData>& fields = parsedProj->getRequiredFields();
- ASSERT_EQUALS(fields.size(), 2U);
- ASSERT_EQUALS(fields[0], "_id");
- ASSERT_EQUALS(fields[1], "a");
-}
-
-TEST(ParsedProjectionTest, MakeSingleFieldCovered) {
- unique_ptr<ParsedProjection> parsedProj(createParsedProjection("{}", "{_id: 0, a: 1}"));
- ASSERT(!parsedProj->requiresDocument());
- const vector<StringData>& fields = parsedProj->getRequiredFields();
- ASSERT_EQUALS(fields.size(), 1U);
- ASSERT_EQUALS(fields[0], "a");
-}
-
-TEST(ParsedProjectionTest, MakeSingleFieldIDCovered) {
- unique_ptr<ParsedProjection> parsedProj(createParsedProjection("{}", "{_id: 1}"));
- ASSERT(!parsedProj->requiresDocument());
- const vector<StringData>& fields = parsedProj->getRequiredFields();
- ASSERT_EQUALS(fields.size(), 1U);
- ASSERT_EQUALS(fields[0], "_id");
-}
-
-// boolean support is undocumented
-TEST(ParsedProjectionTest, MakeSingleFieldCoveredBoolean) {
- unique_ptr<ParsedProjection> parsedProj(createParsedProjection("{}", "{_id: 0, a: true}"));
- ASSERT(!parsedProj->requiresDocument());
- const vector<StringData>& fields = parsedProj->getRequiredFields();
- ASSERT_EQUALS(fields.size(), 1U);
- ASSERT_EQUALS(fields[0], "a");
-}
-
-// boolean support is undocumented
-TEST(ParsedProjectionTest, MakeSingleFieldCoveredIdBoolean) {
- unique_ptr<ParsedProjection> parsedProj(createParsedProjection("{}", "{_id: false, a: 1}"));
- ASSERT(!parsedProj->requiresDocument());
- const vector<StringData>& fields = parsedProj->getRequiredFields();
- ASSERT_EQUALS(fields.size(), 1U);
- ASSERT_EQUALS(fields[0], "a");
-}
-
-//
-// Positional operator validation
-//
-
-TEST(ParsedProjectionTest, InvalidPositionalOperatorProjections) {
- assertInvalidProjection("{}", "{'a.$': 1}");
- assertInvalidProjection("{a: 1}", "{'b.$': 1}");
- assertInvalidProjection("{a: 1}", "{'a.$': 0}");
- assertInvalidProjection("{a: 1}", "{'a.$.d.$': 1}");
- assertInvalidProjection("{a: 1}", "{'a.$.$': 1}");
- assertInvalidProjection("{a: 1}", "{'a.$.$': 1}");
- assertInvalidProjection("{a: 1, b: 1, c: 1}", "{'abc.$': 1}");
- assertInvalidProjection("{$or: [{a: 1}, {$or: [{b: 1}, {c: 1}]}]}", "{'d.$': 1}");
- assertInvalidProjection("{a: [1, 2, 3]}", "{'.$': 1}");
-}
-
-TEST(ParsedProjectionTest, InvalidElemMatchTextProjection) {
- assertInvalidProjection("{}", "{a: {$elemMatch: {$text: {$search: 'str'}}}}");
-}
-
-TEST(ParsedProjectionTest, InvalidElemMatchWhereProjection) {
- assertInvalidProjection("{}", "{a: {$elemMatch: {$where: 'this.a == this.b'}}}");
-}
-
-TEST(ParsedProjectionTest, InvalidElemMatchGeoNearProjection) {
- assertInvalidProjection(
- "{}",
- "{a: {$elemMatch: {$nearSphere: {$geometry: {type: 'Point', coordinates: [0, 0]}}}}}");
-}
-
-TEST(ParsedProjectionTest, InvalidElemMatchExprProjection) {
- assertInvalidProjection("{}", "{a: {$elemMatch: {$expr: 5}}}");
-}
-
-TEST(ParsedProjectionTest, ValidPositionalOperatorProjections) {
- createParsedProjection("{a: 1}", "{'a.$': 1}");
- createParsedProjection("{a: 1}", "{'a.foo.bar.$': 1}");
- createParsedProjection("{a: 1}", "{'a.foo.bar.$.x.y': 1}");
- createParsedProjection("{'a.b.c': 1}", "{'a.b.c.$': 1}");
- createParsedProjection("{'a.b.c': 1}", "{'a.e.f.$': 1}");
- createParsedProjection("{a: {b: 1}}", "{'a.$': 1}");
- createParsedProjection("{a: 1, b: 1}}", "{'a.$': 1}");
- createParsedProjection("{a: 1, b: 1}}", "{'b.$': 1}");
- createParsedProjection("{$and: [{a: 1}, {b: 1}]}", "{'a.$': 1}");
- createParsedProjection("{$and: [{a: 1}, {b: 1}]}", "{'b.$': 1}");
- createParsedProjection("{$or: [{a: 1}, {b: 1}]}", "{'a.$': 1}");
- createParsedProjection("{$or: [{a: 1}, {b: 1}]}", "{'b.$': 1}");
- createParsedProjection("{$and: [{$or: [{a: 1}, {$and: [{b: 1}, {c: 1}]}]}]}", "{'c.d.f.$': 1}");
- // Fields with empty name can be projected using the positional $ operator.
- createParsedProjection("{'': [1, 2, 3]}", "{'.$': 1}");
-}
-
-// Some match expressions (eg. $where) do not override MatchExpression::path()
-// In this test case, we use an internal match expression implementation ALWAYS_FALSE
-// to achieve the same effect.
-// Projection parser should handle this the same way as an empty path.
-TEST(ParsedProjectionTest, InvalidPositionalProjectionDefaultPathMatchExpression) {
- QueryTestServiceContext serviceCtx;
- auto opCtx = serviceCtx.makeOperationContext();
- unique_ptr<MatchExpression> queryMatchExpr(new AlwaysFalseMatchExpression());
- ASSERT(nullptr == queryMatchExpr->path().rawData());
-
- ParsedProjection* out = nullptr;
- BSONObj projObj = fromjson("{'a.$': 1}");
- Status status = ParsedProjection::make(opCtx.get(), projObj, queryMatchExpr.get(), &out);
- ASSERT(!status.isOK());
- std::unique_ptr<ParsedProjection> destroy(out);
-
- // Projecting onto empty field should fail.
- BSONObj emptyFieldProjObj = fromjson("{'.$': 1}");
- status = ParsedProjection::make(opCtx.get(), emptyFieldProjObj, queryMatchExpr.get(), &out);
- ASSERT(!status.isOK());
-}
-
-TEST(ParsedProjectionTest, ParsedProjectionDefaults) {
- auto parsedProjection = createParsedProjection("{}", "{}");
-
- ASSERT_FALSE(parsedProjection->wantSortKey());
- ASSERT_TRUE(parsedProjection->requiresDocument());
- ASSERT_FALSE(parsedProjection->requiresMatchDetails());
- ASSERT_FALSE(parsedProjection->wantGeoNearDistance());
- ASSERT_FALSE(parsedProjection->wantGeoNearPoint());
-}
-
-TEST(ParsedProjectionTest, SortKeyMetaProjection) {
- auto parsedProjection = createParsedProjection("{}", "{foo: {$meta: 'sortKey'}}");
-
- ASSERT_BSONOBJ_EQ(parsedProjection->getProjObj(), fromjson("{foo: {$meta: 'sortKey'}}"));
- ASSERT_TRUE(parsedProjection->wantSortKey());
- ASSERT_TRUE(parsedProjection->requiresDocument());
-
- ASSERT_FALSE(parsedProjection->requiresMatchDetails());
- ASSERT_FALSE(parsedProjection->wantGeoNearDistance());
- ASSERT_FALSE(parsedProjection->wantGeoNearPoint());
-}
-
-TEST(ParsedProjectionTest, SortKeyMetaProjectionCovered) {
- auto parsedProjection = createParsedProjection("{}", "{a: 1, foo: {$meta: 'sortKey'}, _id: 0}");
-
- ASSERT_BSONOBJ_EQ(parsedProjection->getProjObj(),
- fromjson("{a: 1, foo: {$meta: 'sortKey'}, _id: 0}"));
- ASSERT_TRUE(parsedProjection->wantSortKey());
-
- ASSERT_FALSE(parsedProjection->requiresDocument());
- ASSERT_FALSE(parsedProjection->requiresMatchDetails());
- ASSERT_FALSE(parsedProjection->wantGeoNearDistance());
- ASSERT_FALSE(parsedProjection->wantGeoNearPoint());
-}
-
-TEST(ParsedProjectionTest, SortKeyMetaAndSlice) {
- auto parsedProjection =
- createParsedProjection("{}", "{a: 1, foo: {$meta: 'sortKey'}, _id: 0, b: {$slice: 1}}");
-
- ASSERT_BSONOBJ_EQ(parsedProjection->getProjObj(),
- fromjson("{a: 1, foo: {$meta: 'sortKey'}, _id: 0, b: {$slice: 1}}"));
- ASSERT_TRUE(parsedProjection->wantSortKey());
- ASSERT_TRUE(parsedProjection->requiresDocument());
-
- ASSERT_FALSE(parsedProjection->requiresMatchDetails());
- ASSERT_FALSE(parsedProjection->wantGeoNearDistance());
- ASSERT_FALSE(parsedProjection->wantGeoNearPoint());
-}
-
-TEST(ParsedProjectionTest, SortKeyMetaAndElemMatch) {
- auto parsedProjection = createParsedProjection(
- "{}", "{a: 1, foo: {$meta: 'sortKey'}, _id: 0, b: {$elemMatch: {a: 1}}}");
-
- ASSERT_BSONOBJ_EQ(parsedProjection->getProjObj(),
- fromjson("{a: 1, foo: {$meta: 'sortKey'}, _id: 0, b: {$elemMatch: {a: 1}}}"));
- ASSERT_TRUE(parsedProjection->wantSortKey());
- ASSERT_TRUE(parsedProjection->requiresDocument());
-
- ASSERT_FALSE(parsedProjection->requiresMatchDetails());
- ASSERT_FALSE(parsedProjection->wantGeoNearDistance());
- ASSERT_FALSE(parsedProjection->wantGeoNearPoint());
-}
-
-TEST(ParsedProjectionTest, SortKeyMetaAndExclusion) {
- auto parsedProjection = createParsedProjection("{}", "{a: 0, foo: {$meta: 'sortKey'}, _id: 0}");
-
- ASSERT_BSONOBJ_EQ(parsedProjection->getProjObj(),
- fromjson("{a: 0, foo: {$meta: 'sortKey'}, _id: 0}"));
- ASSERT_TRUE(parsedProjection->wantSortKey());
- ASSERT_TRUE(parsedProjection->requiresDocument());
-
- ASSERT_FALSE(parsedProjection->requiresMatchDetails());
- ASSERT_FALSE(parsedProjection->wantGeoNearDistance());
- ASSERT_FALSE(parsedProjection->wantGeoNearPoint());
-}
-
-//
-// Cases for ParsedProjection::isFieldRetainedExactly().
-//
-
-TEST(ParsedProjectionTest, InclusionProjectionPreservesChild) {
- auto parsedProjection = createParsedProjection("{}", "{a: 1}");
- ASSERT_TRUE(parsedProjection->isFieldRetainedExactly("a.b"));
-}
-
-TEST(ParsedProjectionTest, InclusionProjectionDoesNotPreserveParent) {
- auto parsedProjection = createParsedProjection("{}", "{'a.b': 1}");
- ASSERT_FALSE(parsedProjection->isFieldRetainedExactly("a"));
-}
-
-TEST(ParsedProjectionTest, InclusionProjectionPreservesField) {
- auto parsedProjection = createParsedProjection("{}", "{a: 1}");
- ASSERT_TRUE(parsedProjection->isFieldRetainedExactly("a"));
-}
-
-TEST(ParsedProjectionTest, InclusionProjectionOrderingDeterminesPreservation) {
- auto parsedProjection = createParsedProjection("{}", "{a: 1, 'a.b': 1}");
- ASSERT_FALSE(parsedProjection->isFieldRetainedExactly("a"));
- ASSERT_TRUE(parsedProjection->isFieldRetainedExactly("a.b"));
-
- parsedProjection = createParsedProjection("{}", "{'a.b': 1, a: 1}");
- ASSERT_TRUE(parsedProjection->isFieldRetainedExactly("a"));
- ASSERT_TRUE(parsedProjection->isFieldRetainedExactly("a.b"));
-}
-
-TEST(ParsedProjectionTest, ExclusionProjectionDoesNotPreserveParent) {
- auto parsedProjection = createParsedProjection("{}", "{'a.b': 0}");
- ASSERT_FALSE(parsedProjection->isFieldRetainedExactly("a"));
-}
-
-TEST(ParsedProjectionTest, ExclusionProjectionDoesNotPreserveChild) {
- auto parsedProjection = createParsedProjection("{}", "{a: 0}");
- ASSERT_FALSE(parsedProjection->isFieldRetainedExactly("a.b"));
-}
-
-TEST(ParsedProjectionTest, ExclusionProjectionDoesNotPreserveField) {
- auto parsedProjection = createParsedProjection("{}", "{a: 0}");
- ASSERT_FALSE(parsedProjection->isFieldRetainedExactly("a"));
-}
-
-TEST(ParsedProjectionTest, InclusionProjectionDoesNotPreserveNonIncludedFields) {
- auto parsedProjection = createParsedProjection("{}", "{a: 1}");
- ASSERT_FALSE(parsedProjection->isFieldRetainedExactly("c"));
-}
-
-TEST(ParsedProjectionTest, ExclusionProjectionPreservesNonExcludedFields) {
- auto parsedProjection = createParsedProjection("{}", "{a: 0}");
- ASSERT_TRUE(parsedProjection->isFieldRetainedExactly("c"));
-}
-
-TEST(ParsedProjectionTest, PositionalProjectionDoesNotPreserveField) {
- auto parsedProjection = createParsedProjection("{a: {$elemMatch: {$eq: 0}}}", "{'a.$': 1}");
- ASSERT_FALSE(parsedProjection->isFieldRetainedExactly("a"));
-}
-
-TEST(ParsedProjectionTest, PositionalProjectionDoesNotPreserveChild) {
- auto parsedProjection = createParsedProjection("{a: {$elemMatch: {$eq: 0}}}", "{'a.$': 1}");
- ASSERT_FALSE(parsedProjection->isFieldRetainedExactly("a.b"));
-}
-
-TEST(ParsedProjectionTest, PositionalProjectionDoesNotPreserveParent) {
- auto parsedProjection =
- createParsedProjection("{'a.b': {$elemMatch: {$eq: 0}}}", "{'a.b.$': 1}");
- ASSERT_FALSE(parsedProjection->isFieldRetainedExactly("a"));
-}
-
-TEST(ParsedProjectionTest, MetaProjectionDoesNotPreserveField) {
- auto parsedProjection = createParsedProjection("{}", "{a: {$meta: 'textScore'}}");
- ASSERT_FALSE(parsedProjection->isFieldRetainedExactly("a"));
-}
-
-TEST(ParsedProjectionTest, MetaProjectionDoesNotPreserveChild) {
- auto parsedProjection = createParsedProjection("{}", "{a: {$meta: 'textScore'}}");
- ASSERT_FALSE(parsedProjection->isFieldRetainedExactly("a.b"));
-}
-
-TEST(ParsedProjectionTest, IdExclusionProjectionPreservesOtherFields) {
- auto parsedProjection = createParsedProjection("{}", "{_id: 0}");
- ASSERT_TRUE(parsedProjection->isFieldRetainedExactly("a"));
-}
-
-TEST(ParsedProjectionTest, IdInclusionProjectionDoesNotPreserveOtherFields) {
- auto parsedProjection = createParsedProjection("{}", "{_id: 1}");
- ASSERT_FALSE(parsedProjection->isFieldRetainedExactly("a"));
-}
-
-TEST(ParsedProjectionTest, IdSubfieldExclusionProjectionPreservesId) {
- auto parsedProjection = createParsedProjection("{}", "{'_id.a': 0}");
- ASSERT_TRUE(parsedProjection->isFieldRetainedExactly("b"));
- ASSERT_TRUE(parsedProjection->isFieldRetainedExactly("_id"));
- ASSERT_TRUE(parsedProjection->isFieldRetainedExactly("_id.a"));
-}
-
-TEST(ParsedProjectionTest, IdSubfieldInclusionProjectionPreservesId) {
- auto parsedProjection = createParsedProjection("{}", "{'_id.a': 1}");
- ASSERT_FALSE(parsedProjection->isFieldRetainedExactly("b"));
- ASSERT_TRUE(parsedProjection->isFieldRetainedExactly("_id"));
- ASSERT_TRUE(parsedProjection->isFieldRetainedExactly("_id.a"));
- ASSERT_TRUE(parsedProjection->isFieldRetainedExactly("_id.b"));
-}
-
-TEST(ParsedProjectionTest, IdExclusionWithExclusionProjectionDoesNotPreserveId) {
- auto parsedProjection = createParsedProjection("{}", "{_id: 0, a: 0}");
- ASSERT_FALSE(parsedProjection->isFieldRetainedExactly("_id"));
- ASSERT_TRUE(parsedProjection->isFieldRetainedExactly("b"));
- ASSERT_FALSE(parsedProjection->isFieldRetainedExactly("a"));
-}
-
-TEST(ParsedProjectionTest, IdInclusionWithInclusionProjectionPreservesId) {
- auto parsedProjection = createParsedProjection("{}", "{_id: 1, a: 1}");
- ASSERT_TRUE(parsedProjection->isFieldRetainedExactly("_id"));
- ASSERT_FALSE(parsedProjection->isFieldRetainedExactly("b"));
- ASSERT_TRUE(parsedProjection->isFieldRetainedExactly("a"));
-}
-
-TEST(ParsedProjectionTest, IdExclusionWithInclusionProjectionDoesNotPreserveId) {
- auto parsedProjection = createParsedProjection("{}", "{_id: 0, a: 1}");
- ASSERT_FALSE(parsedProjection->isFieldRetainedExactly("_id"));
- ASSERT_FALSE(parsedProjection->isFieldRetainedExactly("b"));
- ASSERT_TRUE(parsedProjection->isFieldRetainedExactly("a"));
-}
-
-TEST(ParsedProjectionTest, PositionalProjectionDoesNotPreserveFields) {
- auto parsedProjection = createParsedProjection("{a: 1}", "{'a.$': 1}");
- ASSERT_FALSE(parsedProjection->isFieldRetainedExactly("b"));
- ASSERT_FALSE(parsedProjection->isFieldRetainedExactly("a"));
- ASSERT_FALSE(parsedProjection->isFieldRetainedExactly("a.b"));
- ASSERT_TRUE(parsedProjection->isFieldRetainedExactly("_id"));
-}
-
-TEST(ParsedProjectionTest, PositionalProjectionWithIdExclusionDoesNotPreserveFields) {
- auto parsedProjection = createParsedProjection("{a: 1}", "{_id: 0, 'a.$': 1}");
- ASSERT_FALSE(parsedProjection->isFieldRetainedExactly("b"));
- ASSERT_FALSE(parsedProjection->isFieldRetainedExactly("a"));
- ASSERT_FALSE(parsedProjection->isFieldRetainedExactly("a.b"));
- ASSERT_FALSE(parsedProjection->isFieldRetainedExactly("_id"));
-}
-
-TEST(ParsedProjectionTest, PositionalProjectionWithIdInclusionPreservesId) {
- auto parsedProjection = createParsedProjection("{a: 1}", "{_id: 1, 'a.$': 1}");
- ASSERT_FALSE(parsedProjection->isFieldRetainedExactly("b"));
- ASSERT_FALSE(parsedProjection->isFieldRetainedExactly("a"));
- ASSERT_FALSE(parsedProjection->isFieldRetainedExactly("a.b"));
- ASSERT_TRUE(parsedProjection->isFieldRetainedExactly("_id"));
-}
-
-TEST(ParsedProjectionTest, ProjectionOfFieldSimilarToIdIsNotSpecial) {
- auto parsedProjection = createParsedProjection("{}", "{_idimpostor: 0}");
- ASSERT_TRUE(parsedProjection->isFieldRetainedExactly("_id"));
- ASSERT_FALSE(parsedProjection->isFieldRetainedExactly("_idimpostor"));
-}
-
-//
-// DBRef projections
-//
-
-TEST(ParsedProjectionTest, DBRefProjections) {
- // non-dotted
- createParsedProjection(BSONObj(), BSON("$ref" << 1));
- createParsedProjection(BSONObj(), BSON("$id" << 1));
- createParsedProjection(BSONObj(), BSON("$ref" << 1));
- // dotted before
- createParsedProjection("{}", "{'a.$ref': 1}");
- createParsedProjection("{}", "{'a.$id': 1}");
- createParsedProjection("{}", "{'a.$db': 1}");
- // dotted after
- createParsedProjection("{}", "{'$id.a': 1}");
- // position operator on $id
- // $ref and $db hold the collection and database names respectively,
- // so these fields cannot be arrays.
- createParsedProjection("{'a.$id': {$elemMatch: {x: 1}}}", "{'a.$id.$': 1}");
-}
-} // unnamed namespace