summaryrefslogtreecommitdiff
path: root/src/mongo/db/pipeline/document_source_lookup_test.cpp
diff options
context:
space:
mode:
authorJames Wahlin <james@mongodb.com>2017-05-25 16:34:41 -0400
committerJames Wahlin <james@mongodb.com>2017-06-05 15:19:44 -0400
commitcc6f3af6e1361c62f04a10596e86e651e1226525 (patch)
tree412eb486170f5dd3e009aa136994cabfde4736cc /src/mongo/db/pipeline/document_source_lookup_test.cpp
parent2daa02b7294412f2d5f2b7f224ef94f290f12f12 (diff)
downloadmongo-cc6f3af6e1361c62f04a10596e86e651e1226525.tar.gz
SERVER-29073 Allow variable definition within $lookup
Diffstat (limited to 'src/mongo/db/pipeline/document_source_lookup_test.cpp')
-rw-r--r--src/mongo/db/pipeline/document_source_lookup_test.cpp106
1 files changed, 104 insertions, 2 deletions
diff --git a/src/mongo/db/pipeline/document_source_lookup_test.cpp b/src/mongo/db/pipeline/document_source_lookup_test.cpp
index e43d8efb5b6..9398473da5a 100644
--- a/src/mongo/db/pipeline/document_source_lookup_test.cpp
+++ b/src/mongo/db/pipeline/document_source_lookup_test.cpp
@@ -117,6 +117,29 @@ TEST_F(DocumentSourceLookUpTest, AcceptsPipelineSyntax) {
ASSERT_TRUE(lookup->wasConstructedWithPipelineSyntax());
}
+TEST_F(DocumentSourceLookUpTest, AcceptsPipelineWithLetSyntax) {
+ auto expCtx = getExpCtx();
+ NamespaceString fromNs("test", "coll");
+ expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+
+ auto docSource = DocumentSourceLookUp::createFromBson(
+ BSON("$lookup" << BSON("from"
+ << "coll"
+ << "let"
+ << BSON("var1"
+ << "$x")
+ << "pipeline"
+ << BSON_ARRAY(BSON("$project" << BSON("hasX"
+ << "$$var1"))
+ << BSON("$match" << BSON("$hasX" << true)))
+ << "as"
+ << "as"))
+ .firstElement(),
+ expCtx);
+ auto lookup = static_cast<DocumentSourceLookUp*>(docSource.get());
+ ASSERT_TRUE(lookup->wasConstructedWithPipelineSyntax());
+}
+
TEST_F(DocumentSourceLookUpTest, RejectsLocalFieldForeignFieldWhenPipelineIsSpecified) {
auto expCtx = getExpCtx();
NamespaceString fromNs("test", "coll");
@@ -142,10 +165,83 @@ TEST_F(DocumentSourceLookUpTest, RejectsLocalFieldForeignFieldWhenPipelineIsSpec
<< lookupStage->getSourceName()
<< " stage to uassert on mix of localField/foreignField and pipeline options");
} catch (const UserException& ex) {
- ASSERT_EQ(40450, ex.getCode());
+ ASSERT_EQ(ErrorCodes::FailedToParse, ex.getCode());
}
}
+TEST_F(DocumentSourceLookUpTest, RejectsLocalFieldForeignFieldWhenLetIsSpecified) {
+ auto expCtx = getExpCtx();
+ NamespaceString fromNs("test", "coll");
+ expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+
+ ASSERT_THROWS_CODE(DocumentSourceLookUp::createFromBson(BSON("$lookup" << BSON("from"
+ << "coll"
+ << "let"
+ << BSON("var1"
+ << "$a")
+ << "localField"
+ << "a"
+ << "foreignField"
+ << "b"
+ << "as"
+ << "as"))
+ .firstElement(),
+ expCtx),
+ UserException,
+ ErrorCodes::FailedToParse);
+}
+
+TEST_F(DocumentSourceLookUpTest, RejectsInvalidLetVariableName) {
+ auto expCtx = getExpCtx();
+ NamespaceString fromNs("test", "coll");
+ expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+
+ ASSERT_THROWS_CODE(DocumentSourceLookUp::createFromBson(
+ BSON("$lookup" << BSON("from"
+ << "coll"
+ << "let"
+ << BSON("" // Empty variable name.
+ << "$a")
+ << "pipeline"
+ << BSON_ARRAY(BSON("$match" << BSON("x" << 1)))
+ << "as"
+ << "as"))
+ .firstElement(),
+ expCtx),
+ UserException,
+ 16866);
+
+ ASSERT_THROWS_CODE(DocumentSourceLookUp::createFromBson(
+ BSON("$lookup" << BSON("from"
+ << "coll"
+ << "let"
+ << BSON("^invalidFirstChar"
+ << "$a")
+ << "pipeline"
+ << BSON_ARRAY(BSON("$match" << BSON("x" << 1)))
+ << "as"
+ << "as"))
+ .firstElement(),
+ expCtx),
+ UserException,
+ 16867);
+
+ ASSERT_THROWS_CODE(DocumentSourceLookUp::createFromBson(
+ BSON("$lookup" << BSON("from"
+ << "coll"
+ << "let"
+ << BSON("contains.invalidChar"
+ << "$a")
+ << "pipeline"
+ << BSON_ARRAY(BSON("$match" << BSON("x" << 1)))
+ << "as"
+ << "as"))
+ .firstElement(),
+ expCtx),
+ UserException,
+ 16868);
+}
+
TEST_F(DocumentSourceLookUpTest, ShouldBeAbleToReParseSerializedStage) {
auto expCtx = getExpCtx();
NamespaceString fromNs("test", "coll");
@@ -154,6 +250,9 @@ TEST_F(DocumentSourceLookUpTest, ShouldBeAbleToReParseSerializedStage) {
auto lookupStage = DocumentSourceLookUp::createFromBson(
BSON("$lookup" << BSON("from"
<< "coll"
+ << "let"
+ << BSON("local_x"
+ << "$x")
<< "pipeline"
<< BSON_ARRAY(BSON("$match" << BSON("x" << 1)))
<< "as"
@@ -174,10 +273,13 @@ TEST_F(DocumentSourceLookUpTest, ShouldBeAbleToReParseSerializedStage) {
ASSERT_EQ(serializedDoc["$lookup"].getType(), BSONType::Object);
auto serializedStage = serializedDoc["$lookup"].getDocument();
- ASSERT_EQ(serializedStage.size(), 3UL);
+ ASSERT_EQ(serializedStage.size(), 4UL);
ASSERT_VALUE_EQ(serializedStage["from"], Value(std::string("coll")));
ASSERT_VALUE_EQ(serializedStage["as"], Value(std::string("as")));
+ ASSERT_DOCUMENT_EQ(serializedStage["let"].getDocument(),
+ Document(fromjson("{local_x: \"$x\"}")));
+
ASSERT_EQ(serializedStage["pipeline"].getType(), BSONType::Array);
ASSERT_EQ(serializedStage["pipeline"].getArrayLength(), 1UL);