diff options
author | Charlie Swanson <charlie.swanson@mongodb.com> | 2016-12-13 10:15:08 -0500 |
---|---|---|
committer | Charlie Swanson <charlie.swanson@mongodb.com> | 2016-12-16 16:24:32 -0500 |
commit | 37e720678f6e468726c6cc775a5dc898d080f0f3 (patch) | |
tree | 4bd6b4932cc0ac436c0d7c949f7e37df613684d2 /src/mongo/db/pipeline/parsed_aggregation_projection_test.cpp | |
parent | 0cd2bf29d5798a395a07e67ae79ede9a5cefd411 (diff) | |
download | mongo-37e720678f6e468726c6cc775a5dc898d080f0f3.tar.gz |
SERVER-25535 Remove injectExpressionContext().
These methods were formally used to propagate a new ExpressionContext to
stages, accumulators, or expressions which potentially needed to
comparisons. Originally, this was necessary since Pipeline parsing
happened outside of the collection lock and thus could not determine if
there was a default collation on the collection. This meant that the
collation could change after parsing and any operators that might
compare strings would need to know about it.
We have since moved parsing within the lock, so the collation can be
known at parse time and the ExpressionContext should not change. This
patch requires an ExpressionContext at construction time, and disallows
changing the collation on an ExpressionContext.
Diffstat (limited to 'src/mongo/db/pipeline/parsed_aggregation_projection_test.cpp')
-rw-r--r-- | src/mongo/db/pipeline/parsed_aggregation_projection_test.cpp | 313 |
1 files changed, 179 insertions, 134 deletions
diff --git a/src/mongo/db/pipeline/parsed_aggregation_projection_test.cpp b/src/mongo/db/pipeline/parsed_aggregation_projection_test.cpp index 5b55071a6bf..71dd1c2378f 100644 --- a/src/mongo/db/pipeline/parsed_aggregation_projection_test.cpp +++ b/src/mongo/db/pipeline/parsed_aggregation_projection_test.cpp @@ -36,6 +36,7 @@ #include "mongo/bson/bsonobjbuilder.h" #include "mongo/bson/json.h" #include "mongo/db/pipeline/document.h" +#include "mongo/db/pipeline/expression_context_for_test.h" #include "mongo/db/pipeline/value.h" #include "mongo/unittest/unittest.h" @@ -53,262 +54,296 @@ BSONObj wrapInLiteral(const T& arg) { // TEST(ParsedAggregationProjectionErrors, ShouldRejectDuplicateFieldNames) { + const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest()); // Include/exclude the same field twice. - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("a" << true << "a" << true)), + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("a" << true << "a" << true)), UserException); - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("a" << false << "a" << false)), + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("a" << false << "a" << false)), + UserException); + ASSERT_THROWS(ParsedAggregationProjection::create( + expCtx, BSON("a" << BSON("b" << false << "b" << false))), UserException); - ASSERT_THROWS( - ParsedAggregationProjection::create(BSON("a" << BSON("b" << false << "b" << false))), - UserException); // Mix of include/exclude and adding a field. - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("a" << wrapInLiteral(1) << "a" << true)), - UserException); ASSERT_THROWS( - ParsedAggregationProjection::create(BSON("a" << false << "a" << wrapInLiteral(0))), + ParsedAggregationProjection::create(expCtx, BSON("a" << wrapInLiteral(1) << "a" << true)), + UserException); + ASSERT_THROWS( + ParsedAggregationProjection::create(expCtx, BSON("a" << false << "a" << wrapInLiteral(0))), UserException); // Adding the same field twice. ASSERT_THROWS(ParsedAggregationProjection::create( - BSON("a" << wrapInLiteral(1) << "a" << wrapInLiteral(0))), + expCtx, BSON("a" << wrapInLiteral(1) << "a" << wrapInLiteral(0))), UserException); } TEST(ParsedAggregationProjectionErrors, ShouldRejectDuplicateIds) { + const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest()); // Include/exclude _id twice. - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("_id" << true << "_id" << true)), - UserException); - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("_id" << false << "_id" << false)), + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("_id" << true << "_id" << true)), UserException); - - // Mix of including/excluding and adding _id. ASSERT_THROWS( - ParsedAggregationProjection::create(BSON("_id" << wrapInLiteral(1) << "_id" << true)), - UserException); - ASSERT_THROWS( - ParsedAggregationProjection::create(BSON("_id" << false << "_id" << wrapInLiteral(0))), + ParsedAggregationProjection::create(expCtx, BSON("_id" << false << "_id" << false)), UserException); + // Mix of including/excluding and adding _id. + ASSERT_THROWS(ParsedAggregationProjection::create( + expCtx, BSON("_id" << wrapInLiteral(1) << "_id" << true)), + UserException); + ASSERT_THROWS(ParsedAggregationProjection::create( + expCtx, BSON("_id" << false << "_id" << wrapInLiteral(0))), + UserException); + // Adding _id twice. ASSERT_THROWS(ParsedAggregationProjection::create( - BSON("_id" << wrapInLiteral(1) << "_id" << wrapInLiteral(0))), + expCtx, BSON("_id" << wrapInLiteral(1) << "_id" << wrapInLiteral(0))), UserException); } TEST(ParsedAggregationProjectionErrors, ShouldRejectFieldsWithSharedPrefix) { + const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest()); // Include/exclude Fields with a shared prefix. - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("a" << true << "a.b" << true)), + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("a" << true << "a.b" << true)), UserException); - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("a.b" << false << "a" << false)), + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("a.b" << false << "a" << false)), UserException); // Mix of include/exclude and adding a shared prefix. ASSERT_THROWS( - ParsedAggregationProjection::create(BSON("a" << wrapInLiteral(1) << "a.b" << true)), - UserException); - ASSERT_THROWS( - ParsedAggregationProjection::create(BSON("a.b" << false << "a" << wrapInLiteral(0))), + ParsedAggregationProjection::create(expCtx, BSON("a" << wrapInLiteral(1) << "a.b" << true)), UserException); + ASSERT_THROWS(ParsedAggregationProjection::create( + expCtx, BSON("a.b" << false << "a" << wrapInLiteral(0))), + UserException); // Adding a shared prefix twice. ASSERT_THROWS(ParsedAggregationProjection::create( - BSON("a" << wrapInLiteral(1) << "a.b" << wrapInLiteral(0))), + expCtx, BSON("a" << wrapInLiteral(1) << "a.b" << wrapInLiteral(0))), UserException); ASSERT_THROWS(ParsedAggregationProjection::create( - BSON("a.b.c.d" << wrapInLiteral(1) << "a.b.c" << wrapInLiteral(0))), + expCtx, BSON("a.b.c.d" << wrapInLiteral(1) << "a.b.c" << wrapInLiteral(0))), UserException); } TEST(ParsedAggregationProjectionErrors, ShouldRejectMixOfIdAndSubFieldsOfId) { + const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest()); // Include/exclude _id twice. - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("_id" << true << "_id.x" << true)), - UserException); - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("_id.x" << false << "_id" << false)), - UserException); - - // Mix of including/excluding and adding _id. ASSERT_THROWS( - ParsedAggregationProjection::create(BSON("_id" << wrapInLiteral(1) << "_id.x" << true)), + ParsedAggregationProjection::create(expCtx, BSON("_id" << true << "_id.x" << true)), UserException); ASSERT_THROWS( - ParsedAggregationProjection::create(BSON("_id.x" << false << "_id" << wrapInLiteral(0))), + ParsedAggregationProjection::create(expCtx, BSON("_id.x" << false << "_id" << false)), UserException); - // Adding _id twice. + // Mix of including/excluding and adding _id. ASSERT_THROWS(ParsedAggregationProjection::create( - BSON("_id" << wrapInLiteral(1) << "_id.x" << wrapInLiteral(0))), + expCtx, BSON("_id" << wrapInLiteral(1) << "_id.x" << true)), UserException); ASSERT_THROWS(ParsedAggregationProjection::create( - BSON("_id.b.c.d" << wrapInLiteral(1) << "_id.b.c" << wrapInLiteral(0))), + expCtx, BSON("_id.x" << false << "_id" << wrapInLiteral(0))), UserException); + + // Adding _id twice. + ASSERT_THROWS(ParsedAggregationProjection::create( + expCtx, BSON("_id" << wrapInLiteral(1) << "_id.x" << wrapInLiteral(0))), + UserException); + ASSERT_THROWS( + ParsedAggregationProjection::create( + expCtx, BSON("_id.b.c.d" << wrapInLiteral(1) << "_id.b.c" << wrapInLiteral(0))), + UserException); } TEST(ParsedAggregationProjectionErrors, ShouldRejectMixOfInclusionAndExclusion) { + const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest()); // Simple mix. - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("a" << true << "b" << false)), + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("a" << true << "b" << false)), UserException); - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("a" << false << "b" << true)), + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("a" << false << "b" << true)), UserException); ASSERT_THROWS( - ParsedAggregationProjection::create(BSON("a" << BSON("b" << false << "c" << true))), + ParsedAggregationProjection::create(expCtx, BSON("a" << BSON("b" << false << "c" << true))), UserException); + ASSERT_THROWS(ParsedAggregationProjection::create( + expCtx, BSON("_id" << BSON("b" << false << "c" << true))), + UserException); ASSERT_THROWS( - ParsedAggregationProjection::create(BSON("_id" << BSON("b" << false << "c" << true))), + ParsedAggregationProjection::create(expCtx, BSON("_id.b" << false << "a.c" << true)), UserException); - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("_id.b" << false << "a.c" << true)), - UserException); // Mix while also adding a field. ASSERT_THROWS(ParsedAggregationProjection::create( - BSON("a" << true << "b" << wrapInLiteral(1) << "c" << false)), + expCtx, BSON("a" << true << "b" << wrapInLiteral(1) << "c" << false)), UserException); ASSERT_THROWS(ParsedAggregationProjection::create( - BSON("a" << false << "b" << wrapInLiteral(1) << "c" << true)), + expCtx, BSON("a" << false << "b" << wrapInLiteral(1) << "c" << true)), UserException); // Mixing "_id" inclusion with exclusion. - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("_id" << true << "a" << false)), - UserException); - - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("a" << false << "_id" << true)), + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("_id" << true << "a" << false)), UserException); - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("_id" << true << "a.b.c" << false)), + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("a" << false << "_id" << true)), UserException); - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("_id.x" << true << "a.b.c" << false)), - UserException); -} - -TEST(ParsedAggregationProjectionType, ShouldRejectMixOfExclusionAndComputedFields) { ASSERT_THROWS( - ParsedAggregationProjection::create(BSON("a" << false << "b" << wrapInLiteral(1))), + ParsedAggregationProjection::create(expCtx, BSON("_id" << true << "a.b.c" << false)), UserException); ASSERT_THROWS( - ParsedAggregationProjection::create(BSON("a" << wrapInLiteral(1) << "b" << false)), + ParsedAggregationProjection::create(expCtx, BSON("_id.x" << true << "a.b.c" << false)), UserException); +} +TEST(ParsedAggregationProjectionType, ShouldRejectMixOfExclusionAndComputedFields) { + const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest()); ASSERT_THROWS( - ParsedAggregationProjection::create(BSON("a.b" << false << "a.c" << wrapInLiteral(1))), + ParsedAggregationProjection::create(expCtx, BSON("a" << false << "b" << wrapInLiteral(1))), UserException); ASSERT_THROWS( - ParsedAggregationProjection::create(BSON("a.b" << wrapInLiteral(1) << "a.c" << false)), + ParsedAggregationProjection::create(expCtx, BSON("a" << wrapInLiteral(1) << "b" << false)), UserException); ASSERT_THROWS(ParsedAggregationProjection::create( - BSON("a" << BSON("b" << false << "c" << wrapInLiteral(1)))), + expCtx, BSON("a.b" << false << "a.c" << wrapInLiteral(1))), + UserException); + + ASSERT_THROWS(ParsedAggregationProjection::create( + expCtx, BSON("a.b" << wrapInLiteral(1) << "a.c" << false)), + UserException); + + ASSERT_THROWS(ParsedAggregationProjection::create( + expCtx, BSON("a" << BSON("b" << false << "c" << wrapInLiteral(1)))), UserException); ASSERT_THROWS(ParsedAggregationProjection::create( - BSON("a" << BSON("b" << wrapInLiteral(1) << "c" << false))), + expCtx, BSON("a" << BSON("b" << wrapInLiteral(1) << "c" << false))), UserException); } TEST(ParsedAggregationProjectionErrors, ShouldRejectDottedFieldInSubDocument) { - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("a" << BSON("b.c" << true))), - UserException); - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("a" << BSON("b.c" << wrapInLiteral(1)))), + const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest()); + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("a" << BSON("b.c" << true))), UserException); + ASSERT_THROWS( + ParsedAggregationProjection::create(expCtx, BSON("a" << BSON("b.c" << wrapInLiteral(1)))), + UserException); } TEST(ParsedAggregationProjectionErrors, ShouldRejectFieldNamesStartingWithADollar) { - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("$dollar" << 0)), UserException); - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("$dollar" << 1)), UserException); + const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest()); + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("$dollar" << 0)), UserException); + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("$dollar" << 1)), UserException); - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("b.$dollar" << 0)), UserException); - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("b.$dollar" << 1)), UserException); + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("b.$dollar" << 0)), + UserException); + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("b.$dollar" << 1)), + UserException); - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("b" << BSON("$dollar" << 0))), + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("b" << BSON("$dollar" << 0))), UserException); - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("b" << BSON("$dollar" << 1))), + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("b" << BSON("$dollar" << 1))), UserException); - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("$add" << 0)), UserException); - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("$add" << 1)), UserException); + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("$add" << 0)), UserException); + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("$add" << 1)), UserException); } TEST(ParsedAggregationProjectionErrors, ShouldRejectTopLevelExpressions) { - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("$add" << BSON_ARRAY(4 << 2))), + const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest()); + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("$add" << BSON_ARRAY(4 << 2))), UserException); } TEST(ParsedAggregationProjectionErrors, ShouldRejectExpressionWithMultipleFieldNames) { + const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest()); ASSERT_THROWS(ParsedAggregationProjection::create( - BSON("a" << BSON("$add" << BSON_ARRAY(4 << 2) << "b" << 1))), + expCtx, BSON("a" << BSON("$add" << BSON_ARRAY(4 << 2) << "b" << 1))), UserException); ASSERT_THROWS(ParsedAggregationProjection::create( - BSON("a" << BSON("b" << 1 << "$add" << BSON_ARRAY(4 << 2)))), - UserException); - ASSERT_THROWS(ParsedAggregationProjection::create( - BSON("a" << BSON("b" << BSON("c" << 1 << "$add" << BSON_ARRAY(4 << 2))))), - UserException); - ASSERT_THROWS(ParsedAggregationProjection::create( - BSON("a" << BSON("b" << BSON("$add" << BSON_ARRAY(4 << 2) << "c" << 1)))), + expCtx, BSON("a" << BSON("b" << 1 << "$add" << BSON_ARRAY(4 << 2)))), UserException); + ASSERT_THROWS( + ParsedAggregationProjection::create( + expCtx, BSON("a" << BSON("b" << BSON("c" << 1 << "$add" << BSON_ARRAY(4 << 2))))), + UserException); + ASSERT_THROWS( + ParsedAggregationProjection::create( + expCtx, BSON("a" << BSON("b" << BSON("$add" << BSON_ARRAY(4 << 2) << "c" << 1)))), + UserException); } TEST(ParsedAggregationProjectionErrors, ShouldRejectEmptyProjection) { - ASSERT_THROWS(ParsedAggregationProjection::create(BSONObj()), UserException); + const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest()); + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSONObj()), UserException); } TEST(ParsedAggregationProjectionErrors, ShouldRejectEmptyNestedObject) { - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("a" << BSONObj())), UserException); - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("a" << false << "b" << BSONObj())), + const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest()); + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("a" << BSONObj())), UserException); - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("a" << true << "b" << BSONObj())), + ASSERT_THROWS( + ParsedAggregationProjection::create(expCtx, BSON("a" << false << "b" << BSONObj())), + UserException); + ASSERT_THROWS( + ParsedAggregationProjection::create(expCtx, BSON("a" << true << "b" << BSONObj())), + UserException); + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("a.b" << BSONObj())), UserException); - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("a.b" << BSONObj())), UserException); - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("a" << BSON("b" << BSONObj()))), + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("a" << BSON("b" << BSONObj()))), UserException); } TEST(ParsedAggregationProjectionErrors, ShouldErrorOnInvalidExpression) { + const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest()); ASSERT_THROWS(ParsedAggregationProjection::create( - BSON("a" << false << "b" << BSON("$unknown" << BSON_ARRAY(4 << 2)))), + expCtx, BSON("a" << false << "b" << BSON("$unknown" << BSON_ARRAY(4 << 2)))), UserException); ASSERT_THROWS(ParsedAggregationProjection::create( - BSON("a" << true << "b" << BSON("$unknown" << BSON_ARRAY(4 << 2)))), + expCtx, BSON("a" << true << "b" << BSON("$unknown" << BSON_ARRAY(4 << 2)))), UserException); } TEST(ParsedAggregationProjectionErrors, ShouldErrorOnInvalidFieldPath) { + const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest()); // Empty field names. - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("" << wrapInLiteral(2))), UserException); - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("" << true)), UserException); - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("" << false)), UserException); + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("" << wrapInLiteral(2))), + UserException); + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("" << true)), UserException); + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("" << false)), UserException); - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("a" << BSON("" << true))), + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("a" << BSON("" << true))), UserException); - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("a" << BSON("" << false))), + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("a" << BSON("" << false))), UserException); - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("" << BSON("a" << true))), + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("" << BSON("a" << true))), UserException); - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("" << BSON("a" << false))), + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("" << BSON("a" << false))), UserException); - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("a." << true)), UserException); - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("a." << false)), UserException); + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("a." << true)), UserException); + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("a." << false)), UserException); - ASSERT_THROWS(ParsedAggregationProjection::create(BSON(".a" << true)), UserException); - ASSERT_THROWS(ParsedAggregationProjection::create(BSON(".a" << false)), UserException); + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON(".a" << true)), UserException); + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON(".a" << false)), UserException); // Not testing field names with null bytes, since that is invalid BSON, and won't make it to the // $project stage without a previous error. // Field names starting with '$'. - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("$x" << wrapInLiteral(2))), + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("$x" << wrapInLiteral(2))), + UserException); + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("c.$d" << true)), UserException); + ASSERT_THROWS(ParsedAggregationProjection::create(expCtx, BSON("c.$d" << false)), UserException); - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("c.$d" << true)), UserException); - ASSERT_THROWS(ParsedAggregationProjection::create(BSON("c.$d" << false)), UserException); } TEST(ParsedAggregationProjectionErrors, ShouldNotErrorOnTwoNestedFields) { - ParsedAggregationProjection::create(BSON("a.b" << true << "a.c" << true)); - ParsedAggregationProjection::create(BSON("a.b" << true << "a" << BSON("c" << true))); + const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest()); + ParsedAggregationProjection::create(expCtx, BSON("a.b" << true << "a.c" << true)); + ParsedAggregationProjection::create(expCtx, BSON("a.b" << true << "a" << BSON("c" << true))); } // @@ -316,102 +351,112 @@ TEST(ParsedAggregationProjectionErrors, ShouldNotErrorOnTwoNestedFields) { // TEST(ParsedAggregationProjectionType, ShouldDefaultToInclusionProjection) { - auto parsedProject = ParsedAggregationProjection::create(BSON("_id" << true)); + const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest()); + auto parsedProject = ParsedAggregationProjection::create(expCtx, BSON("_id" << true)); ASSERT(parsedProject->getType() == ProjectionType::kInclusion); - parsedProject = ParsedAggregationProjection::create(BSON("_id" << wrapInLiteral(1))); + parsedProject = ParsedAggregationProjection::create(expCtx, BSON("_id" << wrapInLiteral(1))); ASSERT(parsedProject->getType() == ProjectionType::kInclusion); - parsedProject = ParsedAggregationProjection::create(BSON("a" << wrapInLiteral(1))); + parsedProject = ParsedAggregationProjection::create(expCtx, BSON("a" << wrapInLiteral(1))); ASSERT(parsedProject->getType() == ProjectionType::kInclusion); } TEST(ParsedAggregationProjectionType, ShouldDetectExclusionProjection) { - auto parsedProject = ParsedAggregationProjection::create(BSON("a" << false)); + const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest()); + auto parsedProject = ParsedAggregationProjection::create(expCtx, BSON("a" << false)); ASSERT(parsedProject->getType() == ProjectionType::kExclusion); - parsedProject = ParsedAggregationProjection::create(BSON("_id.x" << false)); + parsedProject = ParsedAggregationProjection::create(expCtx, BSON("_id.x" << false)); ASSERT(parsedProject->getType() == ProjectionType::kExclusion); - parsedProject = ParsedAggregationProjection::create(BSON("_id" << BSON("x" << false))); + parsedProject = ParsedAggregationProjection::create(expCtx, BSON("_id" << BSON("x" << false))); ASSERT(parsedProject->getType() == ProjectionType::kExclusion); - parsedProject = ParsedAggregationProjection::create(BSON("x" << BSON("_id" << false))); + parsedProject = ParsedAggregationProjection::create(expCtx, BSON("x" << BSON("_id" << false))); ASSERT(parsedProject->getType() == ProjectionType::kExclusion); - parsedProject = ParsedAggregationProjection::create(BSON("_id" << false)); + parsedProject = ParsedAggregationProjection::create(expCtx, BSON("_id" << false)); ASSERT(parsedProject->getType() == ProjectionType::kExclusion); } TEST(ParsedAggregationProjectionType, ShouldDetectInclusionProjection) { - auto parsedProject = ParsedAggregationProjection::create(BSON("a" << true)); + const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest()); + auto parsedProject = ParsedAggregationProjection::create(expCtx, BSON("a" << true)); ASSERT(parsedProject->getType() == ProjectionType::kInclusion); - parsedProject = ParsedAggregationProjection::create(BSON("_id" << false << "a" << true)); + parsedProject = + ParsedAggregationProjection::create(expCtx, BSON("_id" << false << "a" << true)); ASSERT(parsedProject->getType() == ProjectionType::kInclusion); - parsedProject = ParsedAggregationProjection::create(BSON("_id" << false << "a.b.c" << true)); + parsedProject = + ParsedAggregationProjection::create(expCtx, BSON("_id" << false << "a.b.c" << true)); ASSERT(parsedProject->getType() == ProjectionType::kInclusion); - parsedProject = ParsedAggregationProjection::create(BSON("_id.x" << true)); + parsedProject = ParsedAggregationProjection::create(expCtx, BSON("_id.x" << true)); ASSERT(parsedProject->getType() == ProjectionType::kInclusion); - parsedProject = ParsedAggregationProjection::create(BSON("_id" << BSON("x" << true))); + parsedProject = ParsedAggregationProjection::create(expCtx, BSON("_id" << BSON("x" << true))); ASSERT(parsedProject->getType() == ProjectionType::kInclusion); - parsedProject = ParsedAggregationProjection::create(BSON("x" << BSON("_id" << true))); + parsedProject = ParsedAggregationProjection::create(expCtx, BSON("x" << BSON("_id" << true))); ASSERT(parsedProject->getType() == ProjectionType::kInclusion); } TEST(ParsedAggregationProjectionType, ShouldTreatOnlyComputedFieldsAsAnInclusionProjection) { - auto parsedProject = ParsedAggregationProjection::create(BSON("a" << wrapInLiteral(1))); + const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest()); + auto parsedProject = ParsedAggregationProjection::create(expCtx, BSON("a" << wrapInLiteral(1))); ASSERT(parsedProject->getType() == ProjectionType::kInclusion); - parsedProject = - ParsedAggregationProjection::create(BSON("_id" << false << "a" << wrapInLiteral(1))); + parsedProject = ParsedAggregationProjection::create( + expCtx, BSON("_id" << false << "a" << wrapInLiteral(1))); ASSERT(parsedProject->getType() == ProjectionType::kInclusion); - parsedProject = - ParsedAggregationProjection::create(BSON("_id" << false << "a.b.c" << wrapInLiteral(1))); + parsedProject = ParsedAggregationProjection::create( + expCtx, BSON("_id" << false << "a.b.c" << wrapInLiteral(1))); ASSERT(parsedProject->getType() == ProjectionType::kInclusion); - parsedProject = ParsedAggregationProjection::create(BSON("_id.x" << wrapInLiteral(1))); + parsedProject = ParsedAggregationProjection::create(expCtx, BSON("_id.x" << wrapInLiteral(1))); ASSERT(parsedProject->getType() == ProjectionType::kInclusion); parsedProject = - ParsedAggregationProjection::create(BSON("_id" << BSON("x" << wrapInLiteral(1)))); + ParsedAggregationProjection::create(expCtx, BSON("_id" << BSON("x" << wrapInLiteral(1)))); ASSERT(parsedProject->getType() == ProjectionType::kInclusion); parsedProject = - ParsedAggregationProjection::create(BSON("x" << BSON("_id" << wrapInLiteral(1)))); + ParsedAggregationProjection::create(expCtx, BSON("x" << BSON("_id" << wrapInLiteral(1)))); ASSERT(parsedProject->getType() == ProjectionType::kInclusion); } TEST(ParsedAggregationProjectionType, ShouldAllowMixOfInclusionAndComputedFields) { + const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest()); auto parsedProject = - ParsedAggregationProjection::create(BSON("a" << true << "b" << wrapInLiteral(1))); + ParsedAggregationProjection::create(expCtx, BSON("a" << true << "b" << wrapInLiteral(1))); ASSERT(parsedProject->getType() == ProjectionType::kInclusion); - parsedProject = - ParsedAggregationProjection::create(BSON("a.b" << true << "a.c" << wrapInLiteral(1))); + parsedProject = ParsedAggregationProjection::create( + expCtx, BSON("a.b" << true << "a.c" << wrapInLiteral(1))); ASSERT(parsedProject->getType() == ProjectionType::kInclusion); parsedProject = ParsedAggregationProjection::create( - BSON("a" << BSON("b" << true << "c" << wrapInLiteral(1)))); + expCtx, BSON("a" << BSON("b" << true << "c" << wrapInLiteral(1)))); ASSERT(parsedProject->getType() == ProjectionType::kInclusion); } TEST(ParsedAggregationProjectionType, ShouldCoerceNumericsToBools) { + const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest()); std::vector<Value> zeros = {Value(0), Value(0LL), Value(0.0), Value(Decimal128(0))}; for (auto&& zero : zeros) { - auto parsedProject = ParsedAggregationProjection::create(Document{{"a", zero}}.toBson()); + auto parsedProject = + ParsedAggregationProjection::create(expCtx, Document{{"a", zero}}.toBson()); ASSERT(parsedProject->getType() == ProjectionType::kExclusion); } std::vector<Value> nonZeroes = { Value(1), Value(-1), Value(3), Value(1LL), Value(1.0), Value(Decimal128(1))}; for (auto&& nonZero : nonZeroes) { - auto parsedProject = ParsedAggregationProjection::create(Document{{"a", nonZero}}.toBson()); + auto parsedProject = + ParsedAggregationProjection::create(expCtx, Document{{"a", nonZero}}.toBson()); ASSERT(parsedProject->getType() == ProjectionType::kInclusion); } } |