summaryrefslogtreecommitdiff
path: root/src/mongo/db/pipeline/pipeline_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/pipeline/pipeline_test.cpp')
-rw-r--r--src/mongo/db/pipeline/pipeline_test.cpp210
1 files changed, 114 insertions, 96 deletions
diff --git a/src/mongo/db/pipeline/pipeline_test.cpp b/src/mongo/db/pipeline/pipeline_test.cpp
index 41cd6e567d3..dba575017ce 100644
--- a/src/mongo/db/pipeline/pipeline_test.cpp
+++ b/src/mongo/db/pipeline/pipeline_test.cpp
@@ -39,7 +39,7 @@
#include "mongo/db/pipeline/document_source.h"
#include "mongo/db/pipeline/document_source_mock.h"
#include "mongo/db/pipeline/document_value_test_util.h"
-#include "mongo/db/pipeline/expression_context.h"
+#include "mongo/db/pipeline/expression_context_for_test.h"
#include "mongo/db/pipeline/field_path.h"
#include "mongo/db/pipeline/pipeline.h"
#include "mongo/db/query/collation/collator_interface_mock.h"
@@ -86,7 +86,14 @@ public:
rawPipeline.push_back(stageElem.embeddedObject());
}
AggregationRequest request(NamespaceString("a.collection"), rawPipeline);
- intrusive_ptr<ExpressionContext> ctx = new ExpressionContext(&_opCtx, request);
+ intrusive_ptr<ExpressionContextForTest> ctx =
+ new ExpressionContextForTest(&_opCtx, request);
+
+ // For $graphLookup and $lookup, we have to populate the resolvedNamespaces so that the
+ // operations will be able to have a resolved view definition.
+ NamespaceString lookupCollNs("a", "lookupColl");
+ ctx->setResolvedNamespace(lookupCollNs, {lookupCollNs, std::vector<BSONObj>{}});
+
auto outputPipe = uassertStatusOK(Pipeline::parse(request.getPipeline(), ctx));
outputPipe->optimizePipeline();
@@ -240,17 +247,17 @@ class MoveMatchBeforeSort : public Base {
class LookupShouldCoalesceWithUnwindOnAs : public Base {
string inputPipeJson() {
- return "[{$lookup: {from : 'coll2', as : 'same', localField: 'left', foreignField: "
+ return "[{$lookup: {from : 'lookupColl', as : 'same', localField: 'left', foreignField: "
"'right'}}"
",{$unwind: {path: '$same'}}"
"]";
}
string outputPipeJson() {
- return "[{$lookup: {from : 'coll2', as : 'same', localField: 'left', foreignField: "
+ return "[{$lookup: {from : 'lookupColl', as : 'same', localField: 'left', foreignField: "
"'right', unwinding: {preserveNullAndEmptyArrays: false}}}]";
}
string serializedPipeJson() {
- return "[{$lookup: {from : 'coll2', as : 'same', localField: 'left', foreignField: "
+ return "[{$lookup: {from : 'lookupColl', as : 'same', localField: 'left', foreignField: "
"'right'}}"
",{$unwind: {path: '$same'}}"
"]";
@@ -259,17 +266,17 @@ class LookupShouldCoalesceWithUnwindOnAs : public Base {
class LookupShouldCoalesceWithUnwindOnAsWithPreserveEmpty : public Base {
string inputPipeJson() {
- return "[{$lookup: {from : 'coll2', as : 'same', localField: 'left', foreignField: "
+ return "[{$lookup: {from : 'lookupColl', as : 'same', localField: 'left', foreignField: "
"'right'}}"
",{$unwind: {path: '$same', preserveNullAndEmptyArrays: true}}"
"]";
}
string outputPipeJson() {
- return "[{$lookup: {from : 'coll2', as : 'same', localField: 'left', foreignField: "
+ return "[{$lookup: {from : 'lookupColl', as : 'same', localField: 'left', foreignField: "
"'right', unwinding: {preserveNullAndEmptyArrays: true}}}]";
}
string serializedPipeJson() {
- return "[{$lookup: {from : 'coll2', as : 'same', localField: 'left', foreignField: "
+ return "[{$lookup: {from : 'lookupColl', as : 'same', localField: 'left', foreignField: "
"'right'}}"
",{$unwind: {path: '$same', preserveNullAndEmptyArrays: true}}"
"]";
@@ -278,18 +285,18 @@ class LookupShouldCoalesceWithUnwindOnAsWithPreserveEmpty : public Base {
class LookupShouldCoalesceWithUnwindOnAsWithIncludeArrayIndex : public Base {
string inputPipeJson() {
- return "[{$lookup: {from : 'coll2', as : 'same', localField: 'left', foreignField: "
+ return "[{$lookup: {from : 'lookupColl', as : 'same', localField: 'left', foreignField: "
"'right'}}"
",{$unwind: {path: '$same', includeArrayIndex: 'index'}}"
"]";
}
string outputPipeJson() {
- return "[{$lookup: {from : 'coll2', as : 'same', localField: 'left', foreignField: "
+ return "[{$lookup: {from : 'lookupColl', as : 'same', localField: 'left', foreignField: "
"'right', unwinding: {preserveNullAndEmptyArrays: false, includeArrayIndex: "
"'index'}}}]";
}
string serializedPipeJson() {
- return "[{$lookup: {from : 'coll2', as : 'same', localField: 'left', foreignField: "
+ return "[{$lookup: {from : 'lookupColl', as : 'same', localField: 'left', foreignField: "
"'right'}}"
",{$unwind: {path: '$same', includeArrayIndex: 'index'}}"
"]";
@@ -298,13 +305,13 @@ class LookupShouldCoalesceWithUnwindOnAsWithIncludeArrayIndex : public Base {
class LookupShouldNotCoalesceWithUnwindNotOnAs : public Base {
string inputPipeJson() {
- return "[{$lookup: {from : 'coll2', as : 'same', localField: 'left', foreignField: "
+ return "[{$lookup: {from : 'lookupColl', as : 'same', localField: 'left', foreignField: "
"'right'}}"
",{$unwind: {path: '$from'}}"
"]";
}
string outputPipeJson() {
- return "[{$lookup: {from : 'coll2', as : 'same', localField: 'left', foreignField: "
+ return "[{$lookup: {from : 'lookupColl', as : 'same', localField: 'left', foreignField: "
"'right'}}"
",{$unwind: {path: '$from'}}"
"]";
@@ -313,51 +320,59 @@ class LookupShouldNotCoalesceWithUnwindNotOnAs : public Base {
class LookupShouldSwapWithMatch : public Base {
string inputPipeJson() {
- return "[{$lookup: {from: 'foo', as: 'asField', localField: 'y', foreignField: 'z'}}, "
+ return "[{$lookup: {from: 'lookupColl', as: 'asField', localField: 'y', foreignField: "
+ "'z'}}, "
" {$match: {'independent': 0}}]";
}
string outputPipeJson() {
return "[{$match: {independent: 0}}, "
- " {$lookup: {from: 'foo', as: 'asField', localField: 'y', foreignField: 'z'}}]";
+ " {$lookup: {from: 'lookupColl', as: 'asField', localField: 'y', foreignField: "
+ "'z'}}]";
}
};
class LookupShouldSplitMatch : public Base {
string inputPipeJson() {
- return "[{$lookup: {from: 'foo', as: 'asField', localField: 'y', foreignField: 'z'}}, "
+ return "[{$lookup: {from: 'lookupColl', as: 'asField', localField: 'y', foreignField: "
+ "'z'}}, "
" {$match: {'independent': 0, asField: {$eq: 3}}}]";
}
string outputPipeJson() {
return "[{$match: {independent: {$eq: 0}}}, "
- " {$lookup: {from: 'foo', as: 'asField', localField: 'y', foreignField: 'z'}}, "
+ " {$lookup: {from: 'lookupColl', as: 'asField', localField: 'y', foreignField: "
+ "'z'}}, "
" {$match: {asField: {$eq: 3}}}]";
}
};
class LookupShouldNotAbsorbMatchOnAs : public Base {
string inputPipeJson() {
- return "[{$lookup: {from: 'foo', as: 'asField', localField: 'y', foreignField: 'z'}}, "
+ return "[{$lookup: {from: 'lookupColl', as: 'asField', localField: 'y', foreignField: "
+ "'z'}}, "
" {$match: {'asField.subfield': 0}}]";
}
string outputPipeJson() {
- return "[{$lookup: {from: 'foo', as: 'asField', localField: 'y', foreignField: 'z'}}, "
+ return "[{$lookup: {from: 'lookupColl', as: 'asField', localField: 'y', foreignField: "
+ "'z'}}, "
" {$match: {'asField.subfield': 0}}]";
}
};
class LookupShouldAbsorbUnwindMatch : public Base {
string inputPipeJson() {
- return "[{$lookup: {from: 'foo', as: 'asField', localField: 'y', foreignField: 'z'}}, "
+ return "[{$lookup: {from: 'lookupColl', as: 'asField', localField: 'y', foreignField: "
+ "'z'}}, "
"{$unwind: '$asField'}, "
"{$match: {'asField.subfield': {$eq: 1}}}]";
}
string outputPipeJson() {
- return "[{$lookup: {from: 'foo', as: 'asField', localField: 'y', foreignField: 'z', "
+ return "[{$lookup: {from: 'lookupColl', as: 'asField', localField: 'y', foreignField: 'z', "
" unwinding: {preserveNullAndEmptyArrays: false}, "
" matching: {subfield: {$eq: 1}}}}]";
}
string serializedPipeJson() {
- return "[{$lookup: {from: 'foo', as: 'asField', localField: 'y', foreignField: 'z'}}, "
+ return "[{$lookup: {from: 'lookupColl', as: 'asField', localField: 'y', foreignField: "
+ "'z'}}, "
"{$unwind: {path: '$asField'}}, "
"{$match: {'asField.subfield': {$eq: 1}}}]";
}
@@ -365,14 +380,15 @@ class LookupShouldAbsorbUnwindMatch : public Base {
class LookupShouldAbsorbUnwindAndSplitAndAbsorbMatch : public Base {
string inputPipeJson() {
- return "[{$lookup: {from: 'foo', as: 'asField', localField: 'y', foreignField: 'z'}}, "
+ return "[{$lookup: {from: 'lookupColl', as: 'asField', localField: 'y', foreignField: "
+ "'z'}}, "
" {$unwind: '$asField'}, "
" {$match: {'asField.subfield': {$eq: 1}, independentField: {$gt: 2}}}]";
}
string outputPipeJson() {
return "[{$match: {independentField: {$gt: 2}}}, "
" {$lookup: { "
- " from: 'foo', "
+ " from: 'lookupColl', "
" as: 'asField', "
" localField: 'y', "
" foreignField: 'z', "
@@ -386,7 +402,8 @@ class LookupShouldAbsorbUnwindAndSplitAndAbsorbMatch : public Base {
}
string serializedPipeJson() {
return "[{$match: {independentField: {$gt: 2}}}, "
- " {$lookup: {from: 'foo', as: 'asField', localField: 'y', foreignField: 'z'}}, "
+ " {$lookup: {from: 'lookupColl', as: 'asField', localField: 'y', foreignField: "
+ "'z'}}, "
" {$unwind: {path: '$asField'}}, "
" {$match: {'asField.subfield': {$eq: 1}}}]";
}
@@ -397,19 +414,21 @@ class LookupShouldNotSplitIndependentAndDependentOrClauses : public Base {
// the $lookup, and if any child of the $or is independent of the 'asField', then the $match
// cannot be absorbed by the $lookup.
string inputPipeJson() {
- return "[{$lookup: {from: 'foo', as: 'asField', localField: 'y', foreignField: 'z'}}, "
+ return "[{$lookup: {from: 'lookupColl', as: 'asField', localField: 'y', foreignField: "
+ "'z'}}, "
" {$unwind: '$asField'}, "
" {$match: {$or: [{'independent': {$gt: 4}}, "
" {'asField.dependent': {$elemMatch: {a: {$eq: 1}}}}]}}]";
}
string outputPipeJson() {
- return "[{$lookup: {from: 'foo', as: 'asField', localField: 'y', foreignField: 'z', "
+ return "[{$lookup: {from: 'lookupColl', as: 'asField', localField: 'y', foreignField: 'z', "
" unwinding: {preserveNullAndEmptyArrays: false}}}, "
" {$match: {$or: [{'independent': {$gt: 4}}, "
" {'asField.dependent': {$elemMatch: {a: {$eq: 1}}}}]}}]";
}
string serializedPipeJson() {
- return "[{$lookup: {from: 'foo', as: 'asField', localField: 'y', foreignField: 'z'}}, "
+ return "[{$lookup: {from: 'lookupColl', as: 'asField', localField: 'y', foreignField: "
+ "'z'}}, "
" {$unwind: {path: '$asField'}}, "
" {$match: {$or: [{'independent': {$gt: 4}}, "
" {'asField.dependent': {$elemMatch: {a: {$eq: 1}}}}]}}]";
@@ -418,14 +437,15 @@ class LookupShouldNotSplitIndependentAndDependentOrClauses : public Base {
class LookupWithMatchOnArrayIndexFieldShouldNotCoalesce : public Base {
string inputPipeJson() {
- return "[{$lookup: {from: 'foo', as: 'asField', localField: 'y', foreignField: 'z'}}, "
+ return "[{$lookup: {from: 'lookupColl', as: 'asField', localField: 'y', foreignField: "
+ "'z'}}, "
" {$unwind: {path: '$asField', includeArrayIndex: 'index'}}, "
" {$match: {index: 0, 'asField.value': {$gt: 0}, independent: 1}}]";
}
string outputPipeJson() {
return "[{$match: {independent: {$eq: 1}}}, "
" {$lookup: { "
- " from: 'foo', "
+ " from: 'lookupColl', "
" as: 'asField', "
" localField: 'y', "
" foreignField: 'z', "
@@ -438,7 +458,8 @@ class LookupWithMatchOnArrayIndexFieldShouldNotCoalesce : public Base {
}
string serializedPipeJson() {
return "[{$match: {independent: {$eq: 1}}}, "
- " {$lookup: {from: 'foo', as: 'asField', localField: 'y', foreignField: 'z'}}, "
+ " {$lookup: {from: 'lookupColl', as: 'asField', localField: 'y', foreignField: "
+ "'z'}}, "
" {$unwind: {path: '$asField', includeArrayIndex: 'index'}}, "
" {$match: {$and: [{index: {$eq: 0}}, {'asField.value': {$gt: 0}}]}}]";
}
@@ -446,14 +467,15 @@ class LookupWithMatchOnArrayIndexFieldShouldNotCoalesce : public Base {
class LookupWithUnwindPreservingNullAndEmptyArraysShouldNotCoalesce : public Base {
string inputPipeJson() {
- return "[{$lookup: {from: 'foo', as: 'asField', localField: 'y', foreignField: 'z'}}, "
+ return "[{$lookup: {from: 'lookupColl', as: 'asField', localField: 'y', foreignField: "
+ "'z'}}, "
" {$unwind: {path: '$asField', preserveNullAndEmptyArrays: true}}, "
" {$match: {'asField.value': {$gt: 0}, independent: 1}}]";
}
string outputPipeJson() {
return "[{$match: {independent: {$eq: 1}}}, "
" {$lookup: { "
- " from: 'foo', "
+ " from: 'lookupColl', "
" as: 'asField', "
" localField: 'y', "
" foreignField: 'z', "
@@ -465,7 +487,8 @@ class LookupWithUnwindPreservingNullAndEmptyArraysShouldNotCoalesce : public Bas
}
string serializedPipeJson() {
return "[{$match: {independent: {$eq: 1}}}, "
- " {$lookup: {from: 'foo', as: 'asField', localField: 'y', foreignField: 'z'}}, "
+ " {$lookup: {from: 'lookupColl', as: 'asField', localField: 'y', foreignField: "
+ "'z'}}, "
" {$unwind: {path: '$asField', preserveNullAndEmptyArrays: true}}, "
" {$match: {'asField.value': {$gt: 0}}}]";
}
@@ -473,13 +496,13 @@ class LookupWithUnwindPreservingNullAndEmptyArraysShouldNotCoalesce : public Bas
class LookupDoesNotAbsorbElemMatch : public Base {
string inputPipeJson() {
- return "[{$lookup: {from: 'foo', as: 'x', localField: 'y', foreignField: 'z'}}, "
+ return "[{$lookup: {from: 'lookupColl', as: 'x', localField: 'y', foreignField: 'z'}}, "
" {$unwind: '$x'}, "
" {$match: {x: {$elemMatch: {a: 1}}}}]";
}
string outputPipeJson() {
return "[{$lookup: { "
- " from: 'foo', "
+ " from: 'lookupColl', "
" as: 'x', "
" localField: 'y', "
" foreignField: 'z', "
@@ -491,7 +514,7 @@ class LookupDoesNotAbsorbElemMatch : public Base {
" {$match: {x: {$elemMatch: {a: 1}}}}]";
}
string serializedPipeJson() {
- return "[{$lookup: {from: 'foo', as: 'x', localField: 'y', foreignField: 'z'}}, "
+ return "[{$lookup: {from: 'lookupColl', as: 'x', localField: 'y', foreignField: 'z'}}, "
" {$unwind: {path: '$x'}}, "
" {$match: {x: {$elemMatch: {a: 1}}}}]";
}
@@ -499,35 +522,35 @@ class LookupDoesNotAbsorbElemMatch : public Base {
class LookupDoesSwapWithMatchOnLocalField : public Base {
string inputPipeJson() {
- return "[{$lookup: {from: 'foo', as: 'x', localField: 'y', foreignField: 'z'}}, "
+ return "[{$lookup: {from: 'lookupColl', as: 'x', localField: 'y', foreignField: 'z'}}, "
" {$match: {y: {$eq: 3}}}]";
}
string outputPipeJson() {
return "[{$match: {y: {$eq: 3}}}, "
- " {$lookup: {from: 'foo', as: 'x', localField: 'y', foreignField: 'z'}}]";
+ " {$lookup: {from: 'lookupColl', as: 'x', localField: 'y', foreignField: 'z'}}]";
}
};
class LookupDoesSwapWithMatchOnFieldWithSameNameAsForeignField : public Base {
string inputPipeJson() {
- return "[{$lookup: {from: 'foo', as: 'x', localField: 'y', foreignField: 'z'}}, "
+ return "[{$lookup: {from: 'lookupColl', as: 'x', localField: 'y', foreignField: 'z'}}, "
" {$match: {z: {$eq: 3}}}]";
}
string outputPipeJson() {
return "[{$match: {z: {$eq: 3}}}, "
- " {$lookup: {from: 'foo', as: 'x', localField: 'y', foreignField: 'z'}}]";
+ " {$lookup: {from: 'lookupColl', as: 'x', localField: 'y', foreignField: 'z'}}]";
}
};
class LookupDoesNotAbsorbUnwindOnSubfieldOfAsButStillMovesMatch : public Base {
string inputPipeJson() {
- return "[{$lookup: {from: 'foo', as: 'x', localField: 'y', foreignField: 'z'}}, "
+ return "[{$lookup: {from: 'lookupColl', as: 'x', localField: 'y', foreignField: 'z'}}, "
" {$unwind: {path: '$x.subfield'}}, "
" {$match: {'independent': 2, 'x.dependent': 2}}]";
}
string outputPipeJson() {
return "[{$match: {'independent': {$eq: 2}}}, "
- " {$lookup: {from: 'foo', as: 'x', localField: 'y', foreignField: 'z'}}, "
+ " {$lookup: {from: 'lookupColl', as: 'x', localField: 'y', foreignField: 'z'}}, "
" {$match: {'x.dependent': {$eq: 2}}}, "
" {$unwind: {path: '$x.subfield'}}]";
}
@@ -639,58 +662,61 @@ class UnwindBeforeDoubleMatchShouldRepeatedlyOptimize : public Base {
class GraphLookupShouldCoalesceWithUnwindOnAs : public Base {
string inputPipeJson() final {
- return "[{$graphLookup: {from: 'a', as: 'out', connectToField: 'b', connectFromField: 'c', "
- " startWith: '$d'}}, "
+ return "[{$graphLookup: {from: 'lookupColl', as: 'out', connectToField: 'b', "
+ " connectFromField: 'c', startWith: '$d'}}, "
" {$unwind: '$out'}]";
}
string outputPipeJson() final {
- return "[{$graphLookup: {from: 'a', as: 'out', connectToField: 'b', connectFromField: 'c', "
- " startWith: '$d', unwinding: {preserveNullAndEmptyArrays: "
- "false}}}]";
+ return "[{$graphLookup: {from: 'lookupColl', as: 'out', connectToField: 'b', "
+ " connectFromField: 'c', startWith: '$d', "
+ " unwinding: {preserveNullAndEmptyArrays: false}}}]";
}
string serializedPipeJson() final {
- return "[{$graphLookup: {from: 'a', as: 'out', connectToField: 'b', connectFromField: 'c', "
- " startWith: '$d'}}, "
+ return "[{$graphLookup: {from: 'lookupColl', as: 'out', connectToField: 'b', "
+ " connectFromField: 'c', startWith: '$d'}}, "
" {$unwind: {path: '$out'}}]";
}
};
class GraphLookupShouldCoalesceWithUnwindOnAsWithPreserveEmpty : public Base {
string inputPipeJson() final {
- return "[{$graphLookup: {from: 'a', as: 'out', connectToField: 'b', connectFromField: 'c', "
- " startWith: '$d'}}, "
+ return "[{$graphLookup: {from: 'lookupColl', as: 'out', connectToField: 'b', "
+ " connectFromField: 'c', startWith: '$d'}}, "
" {$unwind: {path: '$out', preserveNullAndEmptyArrays: true}}]";
}
string outputPipeJson() final {
- return "[{$graphLookup: {from: 'a', as: 'out', connectToField: 'b', connectFromField: 'c', "
- " startWith: '$d', unwinding: {preserveNullAndEmptyArrays: true}}}]";
+ return "[{$graphLookup: {from: 'lookupColl', as: 'out', connectToField: 'b', "
+ " connectFromField: 'c', startWith: '$d', "
+ " unwinding: {preserveNullAndEmptyArrays: true}}}]";
}
string serializedPipeJson() final {
- return "[{$graphLookup: {from: 'a', as: 'out', connectToField: 'b', connectFromField: 'c', "
- " startWith: '$d'}}, "
+ return "[{$graphLookup: {from: 'lookupColl', as: 'out', connectToField: 'b', "
+ " connectFromField: 'c', startWith: '$d'}}, "
" {$unwind: {path: '$out', preserveNullAndEmptyArrays: true}}]";
}
};
class GraphLookupShouldCoalesceWithUnwindOnAsWithIncludeArrayIndex : public Base {
string inputPipeJson() final {
- return "[{$graphLookup: {from: 'a', as: 'out', connectToField: 'b', connectFromField: 'c', "
- " startWith: '$d'}}, "
+ return "[{$graphLookup: {from: 'lookupColl', as: 'out', connectToField: 'b', "
+ " connectFromField: 'c', startWith: '$d'}}, "
" {$unwind: {path: '$out', includeArrayIndex: 'index'}}]";
}
string outputPipeJson() final {
- return "[{$graphLookup: {from: 'a', as: 'out', connectToField: 'b', connectFromField: 'c', "
- " startWith: '$d', unwinding: {preserveNullAndEmptyArrays: false, "
- " includeArrayIndex: 'index'}}}]";
+ return "[{$graphLookup: {from: 'lookupColl', as: 'out', connectToField: 'b', "
+ " connectFromField: 'c', startWith: '$d', "
+ " unwinding: {preserveNullAndEmptyArrays: false, "
+ " includeArrayIndex: 'index'}}}]";
}
string serializedPipeJson() final {
- return "[{$graphLookup: {from: 'a', as: 'out', connectToField: 'b', connectFromField: 'c', "
+ return "[{$graphLookup: {from: 'lookupColl', as: 'out', connectToField: 'b', "
+ " connectFromField: 'c', "
" startWith: '$d'}}, "
" {$unwind: {path: '$out', includeArrayIndex: 'index'}}]";
}
@@ -698,14 +724,14 @@ class GraphLookupShouldCoalesceWithUnwindOnAsWithIncludeArrayIndex : public Base
class GraphLookupShouldNotCoalesceWithUnwindNotOnAs : public Base {
string inputPipeJson() final {
- return "[{$graphLookup: {from: 'a', as: 'out', connectToField: 'b', connectFromField: 'c', "
- " startWith: '$d'}}, "
+ return "[{$graphLookup: {from: 'lookupColl', as: 'out', connectToField: 'b', "
+ " connectFromField: 'c', startWith: '$d'}}, "
" {$unwind: '$nottherightthing'}]";
}
string outputPipeJson() final {
- return "[{$graphLookup: {from: 'a', as: 'out', connectToField: 'b', connectFromField: 'c', "
- " startWith: '$d'}}, "
+ return "[{$graphLookup: {from: 'lookupColl', as: 'out', connectToField: 'b', "
+ " connectFromField: 'c', startWith: '$d'}}, "
" {$unwind: {path: '$nottherightthing'}}]";
}
};
@@ -713,7 +739,7 @@ class GraphLookupShouldNotCoalesceWithUnwindNotOnAs : public Base {
class GraphLookupShouldSwapWithMatch : public Base {
string inputPipeJson() {
return "[{$graphLookup: {"
- " from: 'coll2',"
+ " from: 'lookupColl',"
" as: 'results',"
" connectToField: 'to',"
" connectFromField: 'from',"
@@ -725,7 +751,7 @@ class GraphLookupShouldSwapWithMatch : public Base {
string outputPipeJson() {
return "[{$match: {independent: 'x'}},"
" {$graphLookup: {"
- " from: 'coll2',"
+ " from: 'lookupColl',"
" as: 'results',"
" connectToField: 'to',"
" connectFromField: 'from',"
@@ -863,7 +889,14 @@ public:
rawPipeline.push_back(stageElem.embeddedObject());
}
AggregationRequest request(NamespaceString("a.collection"), rawPipeline);
- intrusive_ptr<ExpressionContext> ctx = new ExpressionContext(&_opCtx, request);
+ intrusive_ptr<ExpressionContextForTest> ctx =
+ new ExpressionContextForTest(&_opCtx, request);
+
+ // For $graphLookup and $lookup, we have to populate the resolvedNamespaces so that the
+ // operations will be able to have a resolved view definition.
+ NamespaceString lookupCollNs("a", "lookupColl");
+ ctx->setResolvedNamespace(lookupCollNs, {lookupCollNs, std::vector<BSONObj>{}});
+
mergePipe = uassertStatusOK(Pipeline::parse(request.getPipeline(), ctx));
mergePipe->optimizePipeline();
@@ -1057,7 +1090,7 @@ namespace coalesceLookUpAndUnwind {
class ShouldCoalesceUnwindOnAs : public Base {
string inputPipeJson() {
- return "[{$lookup: {from : 'coll2', as : 'same', localField: 'left', foreignField: "
+ return "[{$lookup: {from : 'lookupColl', as : 'same', localField: 'left', foreignField: "
"'right'}}"
",{$unwind: {path: '$same'}}"
"]";
@@ -1066,14 +1099,14 @@ class ShouldCoalesceUnwindOnAs : public Base {
return "[]";
}
string mergePipeJson() {
- return "[{$lookup: {from : 'coll2', as : 'same', localField: 'left', foreignField: "
+ return "[{$lookup: {from : 'lookupColl', as : 'same', localField: 'left', foreignField: "
"'right', unwinding: {preserveNullAndEmptyArrays: false}}}]";
}
};
class ShouldCoalesceUnwindOnAsWithPreserveEmpty : public Base {
string inputPipeJson() {
- return "[{$lookup: {from : 'coll2', as : 'same', localField: 'left', foreignField: "
+ return "[{$lookup: {from : 'lookupColl', as : 'same', localField: 'left', foreignField: "
"'right'}}"
",{$unwind: {path: '$same', preserveNullAndEmptyArrays: true}}"
"]";
@@ -1082,14 +1115,14 @@ class ShouldCoalesceUnwindOnAsWithPreserveEmpty : public Base {
return "[]";
}
string mergePipeJson() {
- return "[{$lookup: {from : 'coll2', as : 'same', localField: 'left', foreignField: "
+ return "[{$lookup: {from : 'lookupColl', as : 'same', localField: 'left', foreignField: "
"'right', unwinding: {preserveNullAndEmptyArrays: true}}}]";
}
};
class ShouldCoalesceUnwindOnAsWithIncludeArrayIndex : public Base {
string inputPipeJson() {
- return "[{$lookup: {from : 'coll2', as : 'same', localField: 'left', foreignField: "
+ return "[{$lookup: {from : 'lookupColl', as : 'same', localField: 'left', foreignField: "
"'right'}}"
",{$unwind: {path: '$same', includeArrayIndex: 'index'}}"
"]";
@@ -1098,7 +1131,7 @@ class ShouldCoalesceUnwindOnAsWithIncludeArrayIndex : public Base {
return "[]";
}
string mergePipeJson() {
- return "[{$lookup: {from : 'coll2', as : 'same', localField: 'left', foreignField: "
+ return "[{$lookup: {from : 'lookupColl', as : 'same', localField: 'left', foreignField: "
"'right', unwinding: {preserveNullAndEmptyArrays: false, includeArrayIndex: "
"'index'}}}]";
}
@@ -1106,7 +1139,7 @@ class ShouldCoalesceUnwindOnAsWithIncludeArrayIndex : public Base {
class ShouldNotCoalesceUnwindNotOnAs : public Base {
string inputPipeJson() {
- return "[{$lookup: {from : 'coll2', as : 'same', localField: 'left', foreignField: "
+ return "[{$lookup: {from : 'lookupColl', as : 'same', localField: 'left', foreignField: "
"'right'}}"
",{$unwind: {path: '$from'}}"
"]";
@@ -1115,7 +1148,7 @@ class ShouldNotCoalesceUnwindNotOnAs : public Base {
return "[]";
}
string mergePipeJson() {
- return "[{$lookup: {from : 'coll2', as : 'same', localField: 'left', foreignField: "
+ return "[{$lookup: {from : 'lookupColl', as : 'same', localField: 'left', foreignField: "
"'right'}}"
",{$unwind: {path: '$from'}}"
"]";
@@ -1170,14 +1203,14 @@ class LookUp : public needsPrimaryShardMergerBase {
return true;
}
string inputPipeJson() {
- return "[{$lookup: {from : 'coll2', as : 'same', localField: 'left', foreignField: "
+ return "[{$lookup: {from : 'lookupColl', as : 'same', localField: 'left', foreignField: "
"'right'}}]";
}
string shardPipeJson() {
return "[]";
}
string mergePipeJson() {
- return "[{$lookup: {from : 'coll2', as : 'same', localField: 'left', foreignField: "
+ return "[{$lookup: {from : 'lookupColl', as : 'same', localField: 'left', foreignField: "
"'right'}}]";
}
};
@@ -1192,7 +1225,7 @@ TEST(PipelineInitialSource, GeoNearInitialQuery) {
OperationContextNoop _opCtx;
const std::vector<BSONObj> rawPipeline = {
fromjson("{$geoNear: {distanceField: 'd', near: [0, 0], query: {a: 1}}}")};
- intrusive_ptr<ExpressionContext> ctx = new ExpressionContext(
+ intrusive_ptr<ExpressionContextForTest> ctx = new ExpressionContextForTest(
&_opCtx, AggregationRequest(NamespaceString("a.collection"), rawPipeline));
auto pipe = uassertStatusOK(Pipeline::parse(rawPipeline, ctx));
ASSERT_BSONOBJ_EQ(pipe->getInitialQuery(), BSON("a" << 1));
@@ -1201,28 +1234,13 @@ TEST(PipelineInitialSource, GeoNearInitialQuery) {
TEST(PipelineInitialSource, MatchInitialQuery) {
OperationContextNoop _opCtx;
const std::vector<BSONObj> rawPipeline = {fromjson("{$match: {'a': 4}}")};
- intrusive_ptr<ExpressionContext> ctx = new ExpressionContext(
+ intrusive_ptr<ExpressionContextForTest> ctx = new ExpressionContextForTest(
&_opCtx, AggregationRequest(NamespaceString("a.collection"), rawPipeline));
auto pipe = uassertStatusOK(Pipeline::parse(rawPipeline, ctx));
ASSERT_BSONOBJ_EQ(pipe->getInitialQuery(), BSON("a" << 4));
}
-TEST(PipelineInitialSource, ParseCollation) {
- QueryTestServiceContext serviceContext;
- auto opCtx = serviceContext.makeOperationContext();
-
- const BSONObj inputBson =
- fromjson("{pipeline: [{$match: {a: 'abc'}}], collation: {locale: 'reverse'}}");
- auto request = AggregationRequest::parseFromBSON(NamespaceString("a.collection"), inputBson);
- ASSERT_OK(request.getStatus());
-
- intrusive_ptr<ExpressionContext> ctx = new ExpressionContext(opCtx.get(), request.getValue());
- ASSERT(ctx->getCollator());
- CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
- ASSERT_TRUE(CollatorInterface::collatorsMatch(ctx->getCollator(), &collator));
-}
-
namespace Dependencies {
using PipelineDependenciesTest = AggregationContextFixture;