diff --git a/src/mongo/db/pipeline/pipeline_optimization_bm.cpp b/src/mongo/db/pipeline/pipeline_optimization_bm.cpp index f6b5f18a9a9..175486b6dfa 100644 --- a/src/mongo/db/pipeline/pipeline_optimization_bm.cpp +++ b/src/mongo/db/pipeline/pipeline_optimization_bm.cpp @@ -234,7 +234,7 @@ BENCHMARK_DEFINE_F(PipelineOptimizationBMFixture, BM_RebuildDependencyGraphFromM DependencyGraph graph(pipeline->getSources()); for (auto keepRunning : state) { - graph.recompute(middleIt); + graph.recompute_forTest(middleIt); } } BENCHMARK_REGISTER_F(PipelineOptimizationBMFixture, BM_RebuildDependencyGraphFromMiddle) diff --git a/src/mongo/db/query/compiler/dependency_analysis/pipeline_dependency_graph.cpp b/src/mongo/db/query/compiler/dependency_analysis/pipeline_dependency_graph.cpp index 4aae94dbe73..c677a4b8a9a 100644 --- a/src/mongo/db/query/compiler/dependency_analysis/pipeline_dependency_graph.cpp +++ b/src/mongo/db/query/compiler/dependency_analysis/pipeline_dependency_graph.cpp @@ -570,7 +570,7 @@ public: grow(endIt); } - boost::intrusive_ptr getDeclaringStage(DocumentSource* ds, + boost::intrusive_ptr getDeclaringStage(const DocumentSource* ds, PathRef path) const { auto stageId = getPreviousStageId(ds); if (!stageId) { @@ -589,7 +589,7 @@ public: return nullptr; } - DeclaringStageResult getDeclaringStageIncludingSubpipelines(DocumentSource* ds, + DeclaringStageResult getDeclaringStageIncludingSubpipelines(const DocumentSource* ds, PathRef path) const { auto stageId = getPreviousStageId(ds); if (!stageId) { @@ -610,8 +610,8 @@ public: if (auto* subGraph = _stages[declaringStageId].subpipelineGraph) { auto suffixPath = skipPathComponents(path, prefix.size() + 1); if (!suffixPath.empty()) { - auto result = - subGraph->getDeclaringStageIncludingSubpipelines(nullptr, suffixPath); + auto result = subGraph->getDeclaringStageIncludingSubpipelines_forTest( + nullptr, suffixPath); result.srcStages.insert(result.srcStages.begin(), _stages[declaringStageId].documentSource); result.fromSubpipeline = true; @@ -623,7 +623,7 @@ public: return {{getDeclaringStage(ds, path)}}; } - bool canPathBeArray(DocumentSource* ds, PathRef path) const { + bool canPathBeArray(const DocumentSource* ds, PathRef path) const { auto stageId = getPreviousStageId(ds); if (!stageId) { // Empty pipeline - all paths come from the base collection. @@ -687,7 +687,7 @@ public: MONGO_UNREACHABLE_TASSERT(12266805); } - boost::optional getConstant(DocumentSource* ds, PathRef path) const { + boost::optional getConstant(const DocumentSource* ds, PathRef path) const { auto stageId = getPreviousStageId(ds); if (!stageId) { return boost::none; @@ -731,7 +731,7 @@ public: MONGO_UNREACHABLE_TASSERT(11939201); } - const DependencyGraph* getSubpipelineGraph(DocumentSource* ds) const { + const DependencyGraph* getSubpipelineGraph(const DocumentSource* ds) const { auto stageId = getStageId(ds); return _stages[stageId].subpipelineGraph; } @@ -1367,7 +1367,7 @@ private: /** * Gets the stage node that represents the given DocumentSource in the graph. */ - StageId getStageId(DocumentSource* ds) const { + StageId getStageId(const DocumentSource* ds) const { if (!ds) { return _stages.getLastId(); } @@ -1382,7 +1382,7 @@ private: * Gets the stage node that represents the stage before the given DocumentSource in the graph. A * nullptr denotes the position after last stage. */ - StageId getPreviousStageId(DocumentSource* ds) const { + StageId getPreviousStageId(const DocumentSource* ds) const { auto stageId = getStageId(ds); if (ds) { if (stageId == StageId{0}) { @@ -1945,29 +1945,30 @@ DependencyGraph::~DependencyGraph() = default; DependencyGraph::DependencyGraph(DependencyGraph&&) noexcept = default; DependencyGraph& DependencyGraph::operator=(DependencyGraph&&) noexcept = default; -boost::intrusive_ptr DependencyGraph::getDeclaringStage(DocumentSource* ds, - PathRef path) const { +boost::intrusive_ptr DependencyGraph::getDeclaringStage_forTest( + const DocumentSource* ds, PathRef path) const { return _impl->getDeclaringStage(ds, path); } -DeclaringStageResult DependencyGraph::getDeclaringStageIncludingSubpipelines(DocumentSource* ds, - PathRef path) const { +DeclaringStageResult DependencyGraph::getDeclaringStageIncludingSubpipelines_forTest( + const DocumentSource* ds, PathRef path) const { return _impl->getDeclaringStageIncludingSubpipelines(ds, path); } -bool DependencyGraph::canPathBeArray(DocumentSource* ds, PathRef path) const { +bool DependencyGraph::canPathBeArray(const DocumentSource* ds, PathRef path) const { return _impl->canPathBeArray(ds, path); } -boost::optional DependencyGraph::getConstant(DocumentSource* ds, PathRef path) const { +boost::optional DependencyGraph::getConstant(const DocumentSource* ds, PathRef path) const { return _impl->getConstant(ds, path); } -const DependencyGraph* DependencyGraph::getSubpipelineGraph(DocumentSource* ds) const { +const DependencyGraph* DependencyGraph::getSubpipelineGraph(const DocumentSource* ds) const { return _impl->getSubpipelineGraph(ds); } -void DependencyGraph::recompute(boost::optional stageIt) { +void DependencyGraph::recompute_forTest( + boost::optional stageIt) { _impl->recompute(stageIt); } diff --git a/src/mongo/db/query/compiler/dependency_analysis/pipeline_dependency_graph.h b/src/mongo/db/query/compiler/dependency_analysis/pipeline_dependency_graph.h index 739b3e8bfcf..3ab702716d3 100644 --- a/src/mongo/db/query/compiler/dependency_analysis/pipeline_dependency_graph.h +++ b/src/mongo/db/query/compiler/dependency_analysis/pipeline_dependency_graph.h @@ -44,10 +44,21 @@ namespace mongo::pipeline::dependency_graph { +/** + * A dot-separated field path. Every component is interpreted as a field name and never as an + * array index. + */ using PathRef = StringData; +/** + * Callback used to query whether a path from the input of the pipeline (i.e. the base collection) + * may resolve to an array. + */ using CanPathBeArray = std::function; +/** + * Always returns true (any path may be an array). + */ bool defaultCanPathBeArray(StringData path); /** @@ -97,39 +108,38 @@ public: DependencyGraph& operator=(DependencyGraph&&) noexcept; /** - * Return the stage which last modified the path visible from the given DocumentSource. If no - * DocumentSource is given, returns the stage which last modified the path in the whole - * pipeline. The stage must have either declared, modified or removed the path. If nullptr, the - * path is unmodified and assumed to originate from the pipeline input. + * Returns the stage which last declared, modified or removed the path as seen at the input of + * 'stage'. If 'stage' is nullptr, returns the stage which last touched the path at the end of + * the pipeline. Returns nullptr when the path passes through unchanged from the pipeline input + * (the base collection or sub-pipeline input). Only used for testing. * - * For example, the following stages all modify the path 'a'. + * For example, the following stages all modify the path 'a': * - {$set: {a: 1}} * - {$set: {a.b: 1}} * - {$project: {a: 0}} * - {$group: {_id: ...}} */ - boost::intrusive_ptr getDeclaringStage(DocumentSource* stage, - PathRef path) const; + boost::intrusive_ptr getDeclaringStage_forTest( + const DocumentSource* stage, PathRef path) const; /** - * Return the stage which last modified the path visible from the given DocumentSource along - * with all the intermediate stages that contain subpipelines. The stage must have either - * declared, modified or removed the path. If the stage is nullptr, the path is originating from - * the pipeline input. + * Like getDeclaringStage_forTest, but additionally records the chain of intermediate + * sub-pipeline containing stages that the path crosses through. * - * When the path crosses into a sub-pipeline (e.g. "docs.x" through a $lookup), the result - * will have 'fromSubpipeline' set to true and 'srcStages' vector populated with pointers to the - * sequence of intermediate stages with subpipelines and the final declaring stage or nullptr - * (if it comes from the collection). + * When the path crosses into a sub-pipeline (e.g. "docs.x" through a $lookup), the result has + * 'fromSubpipeline' set to true and 'srcStages' populated with the chain of intermediate + * sub-pipeline containing stages followed by the final declaring stage (or nullptr if the path + * comes from the sub-pipeline's input). */ - DeclaringStageResult getDeclaringStageIncludingSubpipelines(DocumentSource* stage, - PathRef path) const; + DeclaringStageResult getDeclaringStageIncludingSubpipelines_forTest(const DocumentSource* stage, + PathRef path) const; /** - * Returns false if the path visible from the given DocumentSource can be assumed to not contain - * arrays. If nullptr, the path is assumed to originate from the pipeline input. + * Returns false if the path as seen at the input of 'stage' can be proven to not be an array. + * Returns true otherwise. If 'stage' is nullptr, the path is evaluated as it appears at the end + * of the pipeline. */ - bool canPathBeArray(DocumentSource* stage, PathRef path) const; + bool canPathBeArray(const DocumentSource* stage, PathRef path) const; /** * Returns the constant value of 'path' visible to 'stage' (i.e., as it appears in the input @@ -141,19 +151,20 @@ public: * not statically known, which includes the case where resolving the path would have to * traverse an array element. */ - boost::optional getConstant(DocumentSource* stage, PathRef path) const; + boost::optional getConstant(const DocumentSource* stage, PathRef path) const; /** * Returns the dependency graph for the sub-pipeline of the given stage (e.g. $lookup, * $unionWith), or nullptr if the stage has no sub-pipeline. */ - const DependencyGraph* getSubpipelineGraph(DocumentSource* stage) const; + const DependencyGraph* getSubpipelineGraph(const DocumentSource* stage) const; /** - * Invalidate and recompute the subgraph starting from the earliest nodes which correspond to - * the stage pointed to by 'stageIt'. + * Invalidate and recompute the graph from the stage pointed to by 'stageIt' onwards. If + * 'stageIt' is not given, recomputes the entire graph from the beginning of the container. Only + * used for testing. */ - void recompute(boost::optional stageIt = {}); + void recompute_forTest(boost::optional stageIt = {}); /** * Resizes the graph so that it covers the stages in the range [container.begin(), newEndIt). @@ -211,7 +222,14 @@ public: */ std::vector getDeadFields() const; + /** + * Renders the graph as a string for debug and golden-test output. + */ std::string toDebugString() const; + + /** + * Renders the graph as BSON for debug and golden-test output. + */ BSONObj toBSON() const; private: @@ -220,20 +238,23 @@ private: }; /** - * Constructs the DependencyGraph and allows it to be invalidated and recomputed. + * Owns and lazily constructs the DependencyGraph for a pipeline and allows it to be invalidated and + * recomputed as the pipeline is rewritten. */ class DependencyGraphContext { public: DependencyGraphContext(ExpressionContext& expCtx, DocumentSourceContainer& container); /** - * Get a dependency graph which is valid up to the given element. + * Returns a dependency graph that covers the stages from the beginning of the container up to + * and including 'maxStageIt'. If 'maxStageIt' is not given, covers the whole container. */ const DependencyGraph& getGraph( boost::optional maxStageIt = {}) const; /** - * Report that the stages starting at 'startIt' may have changed. + * Report that the stages starting at 'startIt' may have changed. The graph will be recomputed + * for those stages on the next call to getGraph(). */ void invalidateFrom(DocumentSourceContainer::const_iterator startIt); diff --git a/src/mongo/db/query/compiler/dependency_analysis/pipeline_dependency_graph_test.cpp b/src/mongo/db/query/compiler/dependency_analysis/pipeline_dependency_graph_test.cpp index a9749aeb227..bdcceb35107 100644 --- a/src/mongo/db/query/compiler/dependency_analysis/pipeline_dependency_graph_test.cpp +++ b/src/mongo/db/query/compiler/dependency_analysis/pipeline_dependency_graph_test.cpp @@ -206,17 +206,18 @@ TEST_F(PipelineDependencyGraphTest, SubPipelineGetDeclaringStageDelegatesToSubGr runTest([&] { // 'docs' itself is declared by the $lookup stage. - ASSERT_EQUALS(graph->getDeclaringStageIncludingSubpipelines(nullptr, "docs").srcStages, - stages); - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "docs"), stages[0]); + ASSERT_EQUALS( + graph->getDeclaringStageIncludingSubpipelines_forTest(nullptr, "docs").srcStages, + stages); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "docs"), stages[0]); // 'docs.b_ssn' should resolve across the $lookup into the sub-pipeline's $set stage. auto* subGraph = graph->getSubpipelineGraph(stages[0].get()); ASSERT_NOT_EQUALS(subGraph, nullptr); - auto result = graph->getDeclaringStageIncludingSubpipelines(nullptr, "docs.b_ssn"); + auto result = graph->getDeclaringStageIncludingSubpipelines_forTest(nullptr, "docs.b_ssn"); // The declaring stage should come from the sub-pipeline (the $set). - auto subDeclaringStage = subGraph->getDeclaringStage(nullptr, "b_ssn"); + auto subDeclaringStage = subGraph->getDeclaringStage_forTest(nullptr, "b_ssn"); ASSERT_EQUALS(result.srcStages.back(), subDeclaringStage); ASSERT_TRUE(result.fromSubpipeline); }); @@ -235,17 +236,19 @@ TEST_F(PipelineDependencyGraphTest, runTest([&] { // 'docs.x' itself is declared by the $lookup stage. - ASSERT_EQUALS(graph->getDeclaringStageIncludingSubpipelines(nullptr, "docs.x").srcStages, - stages); - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "docs.x"), stages[0]); + ASSERT_EQUALS( + graph->getDeclaringStageIncludingSubpipelines_forTest(nullptr, "docs.x").srcStages, + stages); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "docs.x"), stages[0]); // 'docs.x.b_ssn' should resolve across the $lookup into the sub-pipeline's $set stage. auto* subGraph = graph->getSubpipelineGraph(stages[0].get()); ASSERT_NOT_EQUALS(subGraph, nullptr); - auto result = graph->getDeclaringStageIncludingSubpipelines(nullptr, "docs.x.b_ssn"); + auto result = + graph->getDeclaringStageIncludingSubpipelines_forTest(nullptr, "docs.x.b_ssn"); // The declaring stage should come from the sub-pipeline (the $set). - auto subDeclaringStage = subGraph->getDeclaringStage(nullptr, "b_ssn"); + auto subDeclaringStage = subGraph->getDeclaringStage_forTest(nullptr, "b_ssn"); ASSERT_EQUALS(result.srcStages.back(), subDeclaringStage); ASSERT_TRUE(result.fromSubpipeline); }); @@ -263,8 +266,9 @@ TEST_F(PipelineDependencyGraphTest, SubPipelineGetDeclaringStageUnknownSubField) runTest([&] { // 'docs.unknown' - the sub-pipeline's $set does not define 'unknown', - // so getDeclaringStage should return nullptr (comes from the sub-pipeline's input). - auto result = graph->getDeclaringStageIncludingSubpipelines(nullptr, "docs.unknown"); + // so getDeclaringStage_forTestshould return nullptr (comes from the sub-pipeline's input). + auto result = + graph->getDeclaringStageIncludingSubpipelines_forTest(nullptr, "docs.unknown"); ASSERT_EQUALS(result.srcStages.back(), nullptr); ASSERT_TRUE(result.fromSubpipeline); }); @@ -289,15 +293,15 @@ TEST_F(PipelineDependencyGraphTest, NestedSubPipelineGetDeclaringStageSubField) runTest([&] { // 'docs.rocks.unknown' - the inner sub-pipeline's $set does not define 'unknown', - // so getDeclaringStage should return nullptr (comes from the sub-pipeline's input). + // so getDeclaringStage_forTestshould return nullptr (comes from the sub-pipeline's input). auto unknownResult = - graph->getDeclaringStageIncludingSubpipelines(nullptr, "docs.rocks.unknown"); + graph->getDeclaringStageIncludingSubpipelines_forTest(nullptr, "docs.rocks.unknown"); ASSERT_EQUALS(unknownResult.srcStages.back(), nullptr); ASSERT_TRUE(unknownResult.fromSubpipeline); // 'docs.rocks.c_ssn' is declared by the innermost $set stage. auto knownResult = - graph->getDeclaringStageIncludingSubpipelines(nullptr, "docs.rocks.c_ssn"); + graph->getDeclaringStageIncludingSubpipelines_forTest(nullptr, "docs.rocks.c_ssn"); // get the stage generating 'c_ssn' (subpipeline of the subpipeline) auto innerSetStage = stages[0]->getSubPipeline()->front()->getSubPipeline()->front(); ASSERT_EQUALS(knownResult.srcStages.back(), innerSetStage); @@ -317,11 +321,11 @@ TEST_F(PipelineDependencyGraphTest, SubPipelineGetDeclaringStageWithInclusionPro runTest([&] { auto resultSubPipelines = - graph->getDeclaringStageIncludingSubpipelines(nullptr, "docs.b_ssn"); + graph->getDeclaringStageIncludingSubpipelines_forTest(nullptr, "docs.b_ssn"); ASSERT_EQUALS(resultSubPipelines.srcStages.back(), nullptr); ASSERT_TRUE(resultSubPipelines.fromSubpipeline); - auto resultMainPipeline = graph->getDeclaringStage(nullptr, "docs.b_ssn"); + auto resultMainPipeline = graph->getDeclaringStage_forTest(nullptr, "docs.b_ssn"); ASSERT_EQUALS(resultMainPipeline, stages[0]); }); } @@ -363,8 +367,8 @@ TEST_F(PipelineDependencyGraphTest, SubPipelineLookupDottedPathDelegation) { // 'docs.a' should resolve through the $lookup into the subpipeline's $set. auto* subGraph = graph->getSubpipelineGraph(stages[0].get()); ASSERT_NOT_EQUALS(subGraph, nullptr); - auto subDeclStage = subGraph->getDeclaringStage(nullptr, "a"); - auto result = graph->getDeclaringStageIncludingSubpipelines(matchStage, "docs.a"); + auto subDeclStage = subGraph->getDeclaringStage_forTest(nullptr, "a"); + auto result = graph->getDeclaringStageIncludingSubpipelines_forTest(matchStage, "docs.a"); ASSERT_EQUALS(result.srcStages.back(), subDeclStage); ASSERT_TRUE(result.fromSubpipeline); }); @@ -385,18 +389,19 @@ TEST_F(PipelineDependencyGraphTest, SubPipelineLookupInclusionProjection) { ASSERT_NOT_EQUALS(subGraph, nullptr); ASSERT_EQUALS( - graph->getDeclaringStageIncludingSubpipelines(nullptr, "docs").srcStages.back(), + graph->getDeclaringStageIncludingSubpipelines_forTest(nullptr, "docs").srcStages.back(), stages[0]); // 'docs.b_ssn' crosses into the sub-pipeline. The inclusion projection preserves // b_ssn from the sub-pipeline's input, so it originates from the base collection. - auto result = graph->getDeclaringStageIncludingSubpipelines(nullptr, "docs.b_ssn"); + auto result = graph->getDeclaringStageIncludingSubpipelines_forTest(nullptr, "docs.b_ssn"); ASSERT_EQUALS(result.srcStages.back(), nullptr); ASSERT_TRUE(result.fromSubpipeline); // 'docs.other' is excluded by the inclusion projection, so it's declared by the $project // (deleted). - auto otherResult = graph->getDeclaringStageIncludingSubpipelines(nullptr, "docs.other"); + auto otherResult = + graph->getDeclaringStageIncludingSubpipelines_forTest(nullptr, "docs.other"); ASSERT_NOT_EQUALS(otherResult.srcStages.back(), nullptr); ASSERT_TRUE(otherResult.fromSubpipeline); @@ -430,13 +435,13 @@ TEST_F(PipelineDependencyGraphTest, AddFieldsUnionWithMatchDependencies) { // From $match (stages[2]), 's' is attributed to $unionWith (stages[1]) since // $unionWith replaces all paths with an exhaustive scope. - ASSERT_EQUALS( - graph->getDeclaringStageIncludingSubpipelines(stages[2].get(), "s").srcStages.back(), - stages[1]); + ASSERT_EQUALS(graph->getDeclaringStageIncludingSubpipelines_forTest(stages[2].get(), "s") + .srcStages.back(), + stages[1]); // Within the sub-pipeline, 's' is declared by the sub-pipeline's $addFields. auto subDeclStage = - subGraph->getDeclaringStageIncludingSubpipelines(nullptr, "s").srcStages.back(); + subGraph->getDeclaringStageIncludingSubpipelines_forTest(nullptr, "s").srcStages.back(); ASSERT_NOT_EQUALS(subDeclStage, nullptr); // After $unionWith, 's' could come from either branch so canPathBeArray is true. @@ -541,10 +546,10 @@ TEST_F(PipelineDependencyGraphTest, SubPipelineGetDeclaringStageThenMatch) { runTest([&] { auto* last = stages.back().get(); // 'docs.b_ssn' visible from the $match stage should still resolve into the sub-pipeline. - auto result = graph->getDeclaringStageIncludingSubpipelines(last, "docs.b_ssn"); + auto result = graph->getDeclaringStageIncludingSubpipelines_forTest(last, "docs.b_ssn"); auto* subGraph = graph->getSubpipelineGraph(stages[0].get()); ASSERT_NOT_EQUALS(subGraph, nullptr); - auto subDeclaringStage = subGraph->getDeclaringStage(nullptr, "b_ssn"); + auto subDeclaringStage = subGraph->getDeclaringStage_forTest(nullptr, "b_ssn"); ASSERT_EQUALS(result.srcStages.back(), subDeclaringStage); ASSERT_TRUE(result.fromSubpipeline); }); @@ -589,7 +594,7 @@ TEST_F(PipelineDependencyGraphTest, SubPipelineUnionWithDeclaringStage) { // After $unionWith, any field is attributed to the $unionWith stage since it // replaces all paths (kAllPaths). auto declStage = - graph->getDeclaringStageIncludingSubpipelines(matchStage, "x").srcStages.back(); + graph->getDeclaringStageIncludingSubpipelines_forTest(matchStage, "x").srcStages.back(); ASSERT_EQUALS(declStage, stages[0]); }); } @@ -606,7 +611,7 @@ TEST_F(PipelineDependencyGraphTest, SubPipelineUnionWithDeclaringStageUnknownFie // Even fields NOT in the sub-pipeline are attributed to $unionWith since // it creates an exhaustive scope. auto declStage = - graph->getDeclaringStageIncludingSubpipelines(matchStage, "y").srcStages.back(); + graph->getDeclaringStageIncludingSubpipelines_forTest(matchStage, "y").srcStages.back(); ASSERT_EQUALS(declStage, stages[0]); }); } @@ -736,13 +741,13 @@ TEST_F(PipelineDependencyGraphTest, SubPipelineUnionWithSubGraphDeclaringStage) {$match: {x: 1}}])"); runTest([&] { - // Although getDeclaringStage for the main pipeline returns $unionWith, + // Although getDeclaringStage_forTestfor the main pipeline returns $unionWith, // we can independently query the sub-pipeline graph. auto* subGraph = graph->getSubpipelineGraph(stages[0].get()); ASSERT_NOT_EQUALS(subGraph, nullptr); auto subDeclStage = - subGraph->getDeclaringStageIncludingSubpipelines(nullptr, "x").srcStages.back(); + subGraph->getDeclaringStageIncludingSubpipelines_forTest(nullptr, "x").srcStages.back(); ASSERT_NOT_EQUALS(subDeclStage, nullptr); // The sub-pipeline's $set declares "x". }); @@ -778,12 +783,12 @@ TEST_F(PipelineDependencyGraphTest, SubPipelineUnionWithThenSet) { auto* matchStage = stages[2].get(); // $set after $unionWith overrides: field "x" is now declared by the $set. auto declStage = - graph->getDeclaringStageIncludingSubpipelines(matchStage, "x").srcStages.back(); + graph->getDeclaringStageIncludingSubpipelines_forTest(matchStage, "x").srcStages.back(); ASSERT_EQUALS(declStage, stages[1]); // "y" not set by the outer $set, still attributed to $unionWith. auto declY = - graph->getDeclaringStageIncludingSubpipelines(matchStage, "y").srcStages.back(); + graph->getDeclaringStageIncludingSubpipelines_forTest(matchStage, "y").srcStages.back(); ASSERT_EQUALS(declY, stages[0]); }); } @@ -926,7 +931,7 @@ TEST_F(PipelineDependencyGraphTest, SimpleCase) { "[{$set: { a: 'foo' }}," "{$match: { a: 'foo' }}]"); - runTest([&] { ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a"), stages[0]); }); + runTest([&] { ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a"), stages[0]); }); } TEST_F(PipelineDependencyGraphTest, Shadowing) { @@ -936,7 +941,7 @@ TEST_F(PipelineDependencyGraphTest, Shadowing) { "{$set: { a: 'baz' }}," "{$match: { a: 'baz' }}]"); - runTest([&] { ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a"), stages[2]); }); + runTest([&] { ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a"), stages[2]); }); } TEST_F(PipelineDependencyGraphTest, Shadowing2) { @@ -948,7 +953,7 @@ TEST_F(PipelineDependencyGraphTest, Shadowing2) { runTest([&] { // Expected stage is the first one since $match comes before the last $set - ASSERT_EQUALS(graph->getDeclaringStage(stages[2].get(), "a"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(stages[2].get(), "a"), stages[0]); }); } @@ -957,7 +962,7 @@ TEST_F(PipelineDependencyGraphTest, UnknownField) { runTest([&] { // Return nullptr to indicate it comes from document. - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a"), nullptr); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a"), nullptr); }); } @@ -966,7 +971,7 @@ TEST_F(PipelineDependencyGraphTest, UnknownComplex) { runTest([&] { // Return nullptr to indicate it comes from document. - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a.b"), nullptr); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a.b"), nullptr); }); } @@ -975,7 +980,7 @@ TEST_F(PipelineDependencyGraphTest, UnknownComplexPrefix) { runTest([&] { // Return stages[0] to indicate it was modified by setting the prefix. - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a.b.c"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a.b.c"), stages[0]); }); } @@ -987,7 +992,7 @@ TEST_F(PipelineDependencyGraphTest, UnknownFieldAfterExhaustive) { runTest([&] { // Return stage[0] to indicate it would be modified by $replaceRoot. - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a"), stages[0]); }); } @@ -999,7 +1004,7 @@ TEST_F(PipelineDependencyGraphTest, UnknownComplexAfterExhaustive) { runTest([&] { // Return stage[0] to indicate it would be modified by $replaceRoot. - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a.b"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a.b"), stages[0]); }); } @@ -1011,9 +1016,9 @@ TEST_F(PipelineDependencyGraphTest, MatchMultiple) { runTest([&] { // For field 'a', expect first stage. - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a"), stages[0]); // For field 'b', expect second stage. - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "b"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "b"), stages[1]); }); } @@ -1026,9 +1031,9 @@ TEST_F(PipelineDependencyGraphTest, MatchMultipleWithShadowing) { runTest([&] { // For field 'a', expect stage 2 (the shadowing stage) - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a"), stages[1]); // For field 'b', expect stage 3 - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "b"), stages[2]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "b"), stages[2]); }); } @@ -1040,10 +1045,10 @@ TEST_F(PipelineDependencyGraphTest, MatchMultipleWithPartialShadowing) { runTest([&] { // For field 'a', expect stage 1 (no shadowing for 'a') - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a"), stages[0]); // For field 'b', expect stage 2 (shadowing stage) - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "b"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "b"), stages[1]); }); } @@ -1056,7 +1061,7 @@ TEST_F(PipelineDependencyGraphTest, FalseDependency) { runTest([&] { // For field 'a', expect stage 3 (the $$REMOVE stage) - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a"), stages[2]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a"), stages[2]); }); } @@ -1070,7 +1075,7 @@ TEST_F(PipelineDependencyGraphTest, FalseDependencyFromInclusionProjection) { runTest([&] { // For field 'a', expect stage 4 (the $project that excludes 'a') - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a"), stages[3]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a"), stages[3]); }); } @@ -1083,7 +1088,7 @@ TEST_F(PipelineDependencyGraphTest, FalseDependencyFromInclusionProjectionWithUn runTest([&] { // For field 'a', expect stage 3 (the $project) - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a"), stages[2]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a"), stages[2]); }); } @@ -1095,7 +1100,7 @@ TEST_F(PipelineDependencyGraphTest, ComplexPathShadowing) { runTest([&] { // Lookup from the end of the pipeline. - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "d.b.c"), stages.back()); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "d.b.c"), stages.back()); }); } @@ -1105,8 +1110,9 @@ TEST_F(PipelineDependencyGraphTest, ComplexPathInclusionProjection) { "{$project: { 'a.b': 1 }}," "{$set: { 'c': 1 }}]"); - runTest( - [&] { ASSERT_EQUALS(graph->getDeclaringStage(stages.back().get(), "a.b.c"), stages[0]); }); + runTest([&] { + ASSERT_EQUALS(graph->getDeclaringStage_forTest(stages.back().get(), "a.b.c"), stages[0]); + }); } TEST_F(PipelineDependencyGraphTest, ComplexPathInclusionProjectionNonExistent) { @@ -1117,15 +1123,15 @@ TEST_F(PipelineDependencyGraphTest, ComplexPathInclusionProjectionNonExistent) { runTest([&] { // The inclusion modified a (filtered its subfields). - ASSERT_EQUALS(graph->getDeclaringStage(stages.back().get(), "a"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(stages.back().get(), "a"), stages[1]); // The inclusion modified a.b (filtered its subfields). - ASSERT_EQUALS(graph->getDeclaringStage(stages.back().get(), "a.b"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(stages.back().get(), "a.b"), stages[1]); // Excluded by the inclusion. - ASSERT_EQUALS(graph->getDeclaringStage(stages.back().get(), "a.b.c"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(stages.back().get(), "a.b.c"), stages[1]); // Preserved from the base doc, never defined by any stage. - ASSERT_EQUALS(graph->getDeclaringStage(stages.back().get(), "a.b.d"), nullptr); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(stages.back().get(), "a.b.d"), nullptr); // Excluded by the inclusion. - ASSERT_EQUALS(graph->getDeclaringStage(stages.back().get(), "a.b.c.e"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(stages.back().get(), "a.b.c.e"), stages[1]); }); } @@ -1137,16 +1143,16 @@ TEST_F(PipelineDependencyGraphTest, ComplexPathInclusionProjectionModifiedPath) runTest([&] { // The inclusion modified a (filtered its subfields). - ASSERT_EQUALS(graph->getDeclaringStage(stages.back().get(), "a"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(stages.back().get(), "a"), stages[1]); // The inclusion modified a.b (filtered its subfields). - ASSERT_EQUALS(graph->getDeclaringStage(stages.back().get(), "a.b"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(stages.back().get(), "a.b"), stages[1]); // The inclusion modified a.b.c (filtered its subfields). - ASSERT_EQUALS(graph->getDeclaringStage(stages.back().get(), "a.b.c"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(stages.back().get(), "a.b.c"), stages[1]); // TODO(SERVER-119392): This is technically kept by the inclusion (prefix "a.b.c" was // defined by the $set), so the declaring field should be $set. - ASSERT_EQUALS(graph->getDeclaringStage(stages.back().get(), "a.b.c.d"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(stages.back().get(), "a.b.c.d"), stages[1]); // Excluded by the inclusion. - ASSERT_EQUALS(graph->getDeclaringStage(stages.back().get(), "a.b.c.e"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(stages.back().get(), "a.b.c.e"), stages[1]); }); } @@ -1159,11 +1165,11 @@ TEST_F(PipelineDependencyGraphTest, InclusionBaseCollectionField) { runTest([&] { auto* last = stages.back().get(); // 'a' was set by stage 0, preserved by inclusion. - ASSERT_EQUALS(graph->getDeclaringStage(last, "a"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "a"), stages[0]); // 'b' never defined — from base collection. - ASSERT_EQUALS(graph->getDeclaringStage(last, "b"), nullptr); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "b"), nullptr); // 'd' not included — excluded by projection. - ASSERT_EQUALS(graph->getDeclaringStage(last, "d"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "d"), stages[1]); }); } @@ -1176,11 +1182,11 @@ TEST_F(PipelineDependencyGraphTest, InclusionAfterExhaustiveStage) { runTest([&] { auto* last = stages.back().get(); // 'a' included but originates from $replaceRoot. - ASSERT_EQUALS(graph->getDeclaringStage(last, "a"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "a"), stages[0]); // 'b' same — from $replaceRoot. - ASSERT_EQUALS(graph->getDeclaringStage(last, "b"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "b"), stages[0]); // 'd' not included — excluded by projection. - ASSERT_EQUALS(graph->getDeclaringStage(last, "d"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "d"), stages[1]); }); } @@ -1192,12 +1198,12 @@ TEST_F(PipelineDependencyGraphTest, InclusionDottedBaseCollectionMultipleSubfiel runTest([&] { auto* last = stages.back().get(); // 'a' modified by inclusion (by excluding subfields). - ASSERT_EQUALS(graph->getDeclaringStage(last, "a"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "a"), stages[0]); // 'a.b' and 'a.c' included from base collection. - ASSERT_EQUALS(graph->getDeclaringStage(last, "a.b"), nullptr); - ASSERT_EQUALS(graph->getDeclaringStage(last, "a.c"), nullptr); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "a.b"), nullptr); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "a.c"), nullptr); // 'a.d' excluded. - ASSERT_EQUALS(graph->getDeclaringStage(last, "a.d"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "a.d"), stages[0]); }); } @@ -1209,14 +1215,14 @@ TEST_F(PipelineDependencyGraphTest, InclusionLongDottedBaseCollectionMultipleSub runTest([&] { auto* last = stages.back().get(); // 'a' modified by inclusion (by excluding subfields). - ASSERT_EQUALS(graph->getDeclaringStage(last, "a"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "a"), stages[0]); // 'a.b' modified by inclusion (by excluding subfields). - ASSERT_EQUALS(graph->getDeclaringStage(last, "a.b"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "a.b"), stages[0]); // 'a.b.c' and 'a.b.d' included from base collection. - ASSERT_EQUALS(graph->getDeclaringStage(last, "a.b.d"), nullptr); - ASSERT_EQUALS(graph->getDeclaringStage(last, "a.b.c"), nullptr); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "a.b.d"), nullptr); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "a.b.c"), nullptr); // 'a.d' excluded. - ASSERT_EQUALS(graph->getDeclaringStage(last, "a.d"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "a.d"), stages[0]); }); } @@ -1230,15 +1236,15 @@ TEST_F(PipelineDependencyGraphTest, ChainedInclusionProjections) { runTest([&] { auto* last = stages.back().get(); // 'a' preserved through both inclusions, defined by from $set. - ASSERT_EQUALS(graph->getDeclaringStage(last, "a"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "a"), stages[0]); // 'b' excluded by second projection. - ASSERT_EQUALS(graph->getDeclaringStage(last, "b"), stages[2]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "b"), stages[2]); // 'c' excluded by both projections, but most recently by the second projection. // One could argue that the second $project didn't change 'c' since it was already excluded // by the first one, but for simplicity we don't consider that when building the graph. This // is consistent with dependency tracking for exclusion projections (see // 'ChainedExclusionProjections'). - ASSERT_EQUALS(graph->getDeclaringStage(last, "c"), stages[2]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "c"), stages[2]); }); } @@ -1252,11 +1258,11 @@ TEST_F(PipelineDependencyGraphTest, ChainedExclusionProjections) { runTest([&] { auto* last = stages.back().get(); // 'a' preserved through both inclusions, defined by from $set. - ASSERT_EQUALS(graph->getDeclaringStage(last, "a"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "a"), stages[0]); // 'b' excluded by second projection. - ASSERT_EQUALS(graph->getDeclaringStage(last, "b"), stages[2]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "b"), stages[2]); // 'c' excluded by both projections, but most recently by the second projection. - ASSERT_EQUALS(graph->getDeclaringStage(last, "c"), stages[2]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "c"), stages[2]); }); } @@ -1269,11 +1275,11 @@ TEST_F(PipelineDependencyGraphTest, InclusionDottedAfterExhaustive) { runTest([&] { auto* last = stages.back().get(); // 'a' modified by inclusion. - ASSERT_EQUALS(graph->getDeclaringStage(last, "a"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "a"), stages[1]); // 'a.b' included — originates from $replaceRoot. - ASSERT_EQUALS(graph->getDeclaringStage(last, "a.b"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "a.b"), stages[0]); // 'a.c' not included — excluded by projection. - ASSERT_EQUALS(graph->getDeclaringStage(last, "a.c"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "a.c"), stages[1]); }); } @@ -1286,12 +1292,12 @@ TEST_F(PipelineDependencyGraphTest, SetFieldThenIncludeDottedPath) { runTest([&] { auto* last = stages.back().get(); // 'a' modified by inclusion (by filtering subfields). - ASSERT_EQUALS(graph->getDeclaringStage(last, "a"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "a"), stages[1]); // TODO(SERVER-119392): 'a.b' preserved by projection, originates from $set (we currently // report it as being declared by the inclusion projection). - ASSERT_EQUALS(graph->getDeclaringStage(last, "a.b"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "a.b"), stages[1]); // 'a.c' excluded by projection. - ASSERT_EQUALS(graph->getDeclaringStage(last, "a.c"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "a.c"), stages[1]); }); } @@ -1303,12 +1309,12 @@ TEST_F(PipelineDependencyGraphTest, DottedPathAfterBaseField) { runTest([&] { // The a.x seen from the first stage is whatever a.x comes from the base document. - ASSERT_EQUALS(graph->getDeclaringStage(stages[0].get(), "a.x"), nullptr); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(stages[0].get(), "a.x"), nullptr); // The a.x seen from the second stage is non-existent erased by the first stage. - ASSERT_EQUALS(graph->getDeclaringStage(stages[1].get(), "a.x"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(stages[1].get(), "a.x"), stages[0]); // The a.x seen from the second stage is still the non-existent erased by the first stage. - ASSERT_EQUALS(graph->getDeclaringStage(stages[2].get(), "a.x"), stages[1]); - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a.x"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(stages[2].get(), "a.x"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a.x"), stages[1]); }); } @@ -1321,16 +1327,16 @@ TEST_F(PipelineDependencyGraphTest, ComplexPathsMultiple) { runTest([&] { // Lookup from the end of the pipeline. DocumentSource* ds = nullptr; - ASSERT_EQUALS(graph->getDeclaringStage(ds, "a"), stages[2]); - ASSERT_EQUALS(graph->getDeclaringStage(ds, "b"), stages[2]); - ASSERT_EQUALS(graph->getDeclaringStage(ds, "c"), stages[1]); - ASSERT_EQUALS(graph->getDeclaringStage(ds, "c.c"), stages[1]); - ASSERT_EQUALS(graph->getDeclaringStage(ds, "a.b"), stages[2]); - ASSERT_EQUALS(graph->getDeclaringStage(ds, "a.a"), stages[1]); - ASSERT_EQUALS(graph->getDeclaringStage(ds, "b.b.b"), stages[2]); - ASSERT_EQUALS(graph->getDeclaringStage(ds, "b.b"), stages[2]); - ASSERT_EQUALS(graph->getDeclaringStage(ds, "b.a"), stages[2]); - ASSERT_EQUALS(graph->getDeclaringStage(ds, "a.b.a"), stages[2]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(ds, "a"), stages[2]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(ds, "b"), stages[2]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(ds, "c"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(ds, "c.c"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(ds, "a.b"), stages[2]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(ds, "a.a"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(ds, "b.b.b"), stages[2]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(ds, "b.b"), stages[2]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(ds, "b.a"), stages[2]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(ds, "a.b.a"), stages[2]); }); } @@ -1572,10 +1578,10 @@ TEST_F(PipelineDependencyGraphTest, ReplaceRootAttributesAllFields) { runTest([&] { // All pre-existing fields are attributed to $replaceRoot. - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a"), stages[1]); - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "b"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "b"), stages[1]); // 'c' set after $replaceRoot. - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "c"), stages[2]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "c"), stages[2]); }); } @@ -1589,8 +1595,8 @@ TEST_F(PipelineDependencyGraphTest, ReplaceRootShadowsPriorDefinitions) { runTest([&] { auto* last = stages.back().get(); // Both fields are attributed to $replaceRoot, not the $set. - ASSERT_EQUALS(graph->getDeclaringStage(last, "a"), stages[1]); - ASSERT_EQUALS(graph->getDeclaringStage(last, "b"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "a"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "b"), stages[1]); }); } @@ -1603,9 +1609,9 @@ TEST_F(PipelineDependencyGraphTest, ReplaceRootThenSetThenLookup) { runTest([&] { auto* last = stages.back().get(); // 'a' redefined after $replaceRoot. - ASSERT_EQUALS(graph->getDeclaringStage(last, "a"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "a"), stages[1]); // 'b' not redefined — still attributed to $replaceRoot. - ASSERT_EQUALS(graph->getDeclaringStage(last, "b"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "b"), stages[0]); }); } @@ -1619,8 +1625,8 @@ TEST_F(PipelineDependencyGraphTest, ChainedReplaceRoots) { runTest([&] { auto* last = stages.back().get(); // Second $replaceRoot is the last exhaustive stage. - ASSERT_EQUALS(graph->getDeclaringStage(last, "a"), stages[2]); - ASSERT_EQUALS(graph->getDeclaringStage(last, "b"), stages[2]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "a"), stages[2]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "b"), stages[2]); }); } @@ -1633,13 +1639,13 @@ TEST_F(PipelineDependencyGraphTest, GroupSimpleKey) { runTest([&] { auto* last = stages.back().get(); // _id declared by $group. - ASSERT_EQUALS(graph->getDeclaringStage(last, "_id"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "_id"), stages[1]); // 'count' is also declared by $group. - ASSERT_EQUALS(graph->getDeclaringStage(last, "count"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "count"), stages[1]); // 'a' from the base document is made missing by $group. - ASSERT_EQUALS(graph->getDeclaringStage(last, "a"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "a"), stages[1]); // 'x' is also made missing by $group. - ASSERT_EQUALS(graph->getDeclaringStage(last, "x"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "x"), stages[1]); }); } @@ -1651,7 +1657,7 @@ TEST_F(PipelineDependencyGraphTest, GroupKeyFromBaseDocument) { runTest([&] { auto* last = stages.back().get(); // _id declared by $group. - ASSERT_EQUALS(graph->getDeclaringStage(last, "_id"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "_id"), stages[0]); }); } @@ -1664,13 +1670,13 @@ TEST_F(PipelineDependencyGraphTest, GroupCompoundKey) { runTest([&] { auto* last = stages.back().get(); // _id.a declared by $group. - ASSERT_EQUALS(graph->getDeclaringStage(last, "_id.a"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "_id.a"), stages[1]); // _id.b declared by $group. - ASSERT_EQUALS(graph->getDeclaringStage(last, "_id.b"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "_id.b"), stages[1]); // _id declared by group. - ASSERT_EQUALS(graph->getDeclaringStage(last, "_id"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "_id"), stages[1]); // _id.c is not a group key field — attributed to $group via missing sentinel. - ASSERT_EQUALS(graph->getDeclaringStage(last, "_id.c"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "_id.c"), stages[1]); }); } @@ -1683,10 +1689,10 @@ TEST_F(PipelineDependencyGraphTest, GroupDottedKeyNoRename) { runTest([&] { auto* last = stages.back().get(); // _id declared by $group. - ASSERT_EQUALS(graph->getDeclaringStage(last, "_id"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "_id"), stages[1]); // Everything else is made missing by $group. - ASSERT_EQUALS(graph->getDeclaringStage(last, "x"), stages[1]); - ASSERT_EQUALS(graph->getDeclaringStage(last, "x.y"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "x"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "x.y"), stages[1]); }); } @@ -1699,13 +1705,13 @@ TEST_F(PipelineDependencyGraphTest, GroupNullKey) { runTest([&] { auto* last = stages.back().get(); // _id is declared by $group. - ASSERT_EQUALS(graph->getDeclaringStage(last, "_id"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "_id"), stages[0]); // 'total' is declared by $group. - ASSERT_EQUALS(graph->getDeclaringStage(last, "total"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "total"), stages[0]); // 'a' set after $group. - ASSERT_EQUALS(graph->getDeclaringStage(last, "a"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "a"), stages[1]); // 'b' is made missing by $group. - ASSERT_EQUALS(graph->getDeclaringStage(last, "b"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "b"), stages[0]); }); } @@ -1718,11 +1724,11 @@ TEST_F(PipelineDependencyGraphTest, GroupThenInclusion) { runTest([&] { auto* last = stages.back().get(); // _id preserved through inclusion, most recently declared by $group. - ASSERT_EQUALS(graph->getDeclaringStage(last, "_id"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "_id"), stages[0]); // 'count' excluded by inclusion projection. - ASSERT_EQUALS(graph->getDeclaringStage(last, "count"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "count"), stages[1]); // Any arbitrary field last excluded by the inclusion projection. - ASSERT_EQUALS(graph->getDeclaringStage(last, "foo"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "foo"), stages[1]); }); } @@ -1736,11 +1742,11 @@ TEST_F(PipelineDependencyGraphTest, SetThenGroupThenSetThenMatch) { runTest([&] { auto* last = stages.back().get(); // _id declared by $group. - ASSERT_EQUALS(graph->getDeclaringStage(last, "_id"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "_id"), stages[1]); // 'a' set after $group. - ASSERT_EQUALS(graph->getDeclaringStage(last, "a"), stages[2]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "a"), stages[2]); // 'b' made missing by $group. - ASSERT_EQUALS(graph->getDeclaringStage(last, "b"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(last, "b"), stages[1]); }); } @@ -1786,8 +1792,8 @@ TEST_F(PipelineDependencyGraphTest, ModifyPathLookupDottedAsMayDestroySibling) { runTest([&] { // 'a.c' may have been destroyed if 'a' was an array, so we attribute it to the lookup. - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a.c"), stages[0]); - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a.b"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a.c"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a.b"), stages[0]); // The prefix is always a plain object. ASSERT_FALSE(graph->canPathBeArray(nullptr, "a")); ASSERT_TRUE(graph->canPathBeArray(nullptr, "a.c")); @@ -1850,9 +1856,9 @@ TEST_F(PipelineDependencyGraphTest, LeafRedeclaredAsDottedPath) { runTest([&] { // Before stage 1: 'a.unknown' is shadowed by a:1, declared by stage 0. - ASSERT_EQUALS(graph->getDeclaringStage(stages[1].get(), "a.unknown"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(stages[1].get(), "a.unknown"), stages[0]); // After stage 1: 'a.unknown' is now attributed to stage 1. - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a.unknown"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a.unknown"), stages[1]); }); } @@ -1891,8 +1897,8 @@ TEST_F(PipelineDependencyGraphTest, PathEmptyString) { setPipeline(R"([{$match: {"": 1}}])"); runTest([&] { - // getDeclaringStage with empty string returns nullptr (comes from base collection) - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, ""), nullptr); + // getDeclaringStage_forTestwith empty string returns nullptr (comes from base collection) + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, ""), nullptr); // canPathBeArray uses FieldRef. ASSERT_TRUE(graph->canPathBeArray(nullptr, "")); @@ -1908,10 +1914,10 @@ TEST_F(PipelineDependencyGraphTest, PathWithLeadingDot) { setPipeline(R"([{$set: {"a": 1}}, {$match: {".a": 1}}])"); runTest([&] { - // getDeclaringStage returns nullptr (field comes from base collection) - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, ".a"), nullptr); + // getDeclaringStage_forTest returns nullptr (field comes from base collection) + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, ".a"), nullptr); - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a"), stages[0]); // canPathBeArray uses FieldRef. ASSERT_TRUE(graph->canPathBeArray(nullptr, ".a")); @@ -1939,10 +1945,10 @@ TEST_F(PipelineDependencyGraphTest, PathWithTrailingDot) { setPipeline(R"([{$set: {"a": 1}}, {$match: {"a.": 1}}])"); runTest([&] { - // getDeclaringStage returns stage[0] (field comes from the preceding stage) - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a."), stages[0]); + // getDeclaringStage_forTest returns stage[0] (field comes from the preceding stage) + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a."), stages[0]); - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a"), stages[0]); // canPathBeArray accepts both FieldPath and FieldRef. ASSERT_TRUE(graph->canPathBeArray(nullptr, "a.")); @@ -1959,8 +1965,8 @@ TEST_F(PipelineDependencyGraphTest, PathWithBareDot) { setPipeline(R"([{$match: {".": 1}}])"); runTest([&] { - // getDeclaringStage returns nullptr (field comes from base collection) - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "."), nullptr); + // getDeclaringStage_forTest returns nullptr (field comes from base collection) + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "."), nullptr); // canPathBeArray uses FieldRef which is less restrictive. ASSERT_TRUE(graph->canPathBeArray(nullptr, ".")); @@ -1978,8 +1984,8 @@ TEST_F(PipelineDependencyGraphTest, PathWithDoubleDot) { setPipeline(R"([{$match: {"a..b": 1}}])"); runTest([&] { - // getDeclaringStage returns nullptr (field comes from base collection) - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a..b"), nullptr); + // getDeclaringStage_forTest returns nullptr (field comes from base collection) + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a..b"), nullptr); // canPathBeArray uses FieldRef which is less restrictive. ASSERT_TRUE(graph->canPathBeArray(nullptr, "a..b")); @@ -2037,8 +2043,8 @@ TEST_F(PipelineDependencyGraphTest, PathWithEmptyComponentInMiddle) { setPipeline(R"([{$match: {"a..b.c": 1}}])"); runTest([&] { - // getDeclaringStage returns nullptr (field comes from base collection) - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a..b.c"), nullptr); + // getDeclaringStage_forTest returns nullptr (field comes from base collection) + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a..b.c"), nullptr); // canPathBeArray accepts both FieldPath and FieldRef. ASSERT_TRUE(graph->canPathBeArray(nullptr, "a..b.c")); @@ -2056,8 +2062,8 @@ TEST_F(PipelineDependencyGraphTest, PathWithMultipleEmptyComponents) { setPipeline(R"([{$match: {"a...b": 1}}])"); runTest([&] { - // getDeclaringStage returns nullptr (field comes from base collection) - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a...c"), nullptr); + // getDeclaringStage_forTest returns nullptr (field comes from base collection) + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a...c"), nullptr); // canPathBeArray accepts both FieldPath and FieldRef. ASSERT_TRUE(graph->canPathBeArray(nullptr, "a...c")); @@ -2088,8 +2094,8 @@ TEST_F(PipelineDependencyGraphTest, DollarSignAsComponentInFieldName) { setPipeline(R"([{$match: {"a.$": 1}}])"); runTest([&] { - // getDeclaringStage returns nullptr (field comes from base collection) - ASSERT_EQ(graph->getDeclaringStage(nullptr, "a.$"), nullptr); + // getDeclaringStage_forTest returns nullptr (field comes from base collection) + ASSERT_EQ(graph->getDeclaringStage_forTest(nullptr, "a.$"), nullptr); ASSERT_TRUE(graph->canPathBeArray(nullptr, "a.$")); }); @@ -2110,8 +2116,8 @@ TEST_F(PipelineDependencyGraphTest, DollarSignInMiddleOfFieldName) { setPipeline(R"([{$match: {"field$name": 1}}])"); runTest([&] { - // getDeclaringStage returns nullptr (field comes from base collection) - ASSERT_EQ(graph->getDeclaringStage(nullptr, "field$name"), nullptr); + // getDeclaringStage_forTest returns nullptr (field comes from base collection) + ASSERT_EQ(graph->getDeclaringStage_forTest(nullptr, "field$name"), nullptr); ASSERT_TRUE(graph->canPathBeArray(nullptr, "field$name")); }); @@ -2123,8 +2129,8 @@ TEST_F(PipelineDependencyGraphTest, DollarSignInMiddleOfNestedPath) { setPipeline(R"([{$match: {"a.b$c.d": 1}}])"); runTest([&] { - // getDeclaringStage returns nullptr (field comes from base collection) - ASSERT_EQ(graph->getDeclaringStage(nullptr, "a.b$c.d"), nullptr); + // getDeclaringStage_forTest returns nullptr (field comes from base collection) + ASSERT_EQ(graph->getDeclaringStage_forTest(nullptr, "a.b$c.d"), nullptr); ASSERT_TRUE(graph->canPathBeArray(nullptr, "a")); ASSERT_TRUE(graph->canPathBeArray(nullptr, "a.b$c")); @@ -2138,8 +2144,8 @@ TEST_F(PipelineDependencyGraphTest, DollarSignAtEndOfNestedPath) { setPipeline(R"([{$match: {"a.b.c$": 1}}])"); runTest([&] { - // getDeclaringStage returns nullptr (field comes from base collection) - ASSERT_EQ(graph->getDeclaringStage(nullptr, "a.b.c$"), nullptr); + // getDeclaringStage_forTest returns nullptr (field comes from base collection) + ASSERT_EQ(graph->getDeclaringStage_forTest(nullptr, "a.b.c$"), nullptr); ASSERT_TRUE(graph->canPathBeArray(nullptr, "a")); ASSERT_TRUE(graph->canPathBeArray(nullptr, "a.b")); @@ -2153,8 +2159,8 @@ TEST_F(PipelineDependencyGraphTest, MultipleDollarSignsInFieldName) { setPipeline(R"([{$match: {"a$b$c": 1}}])"); runTest([&] { - // getDeclaringStage returns nullptr (field comes from base collection) - ASSERT_EQ(graph->getDeclaringStage(nullptr, "a$b$c"), nullptr); + // getDeclaringStage_forTest returns nullptr (field comes from base collection) + ASSERT_EQ(graph->getDeclaringStage_forTest(nullptr, "a$b$c"), nullptr); ASSERT_TRUE(graph->canPathBeArray(nullptr, "a$b$c")); }); @@ -2168,8 +2174,8 @@ TEST_F(PipelineDependencyGraphTest, DollarPrefixedNestedPathComponent) { setPipeline(R"([{$match: {"foo.$bar": 1}}])"); runTest([&] { - // getDeclaringStage returns nullptr (field comes from base collection) - ASSERT_EQ(graph->getDeclaringStage(nullptr, "foo.$bar"), nullptr); + // getDeclaringStage_forTest returns nullptr (field comes from base collection) + ASSERT_EQ(graph->getDeclaringStage_forTest(nullptr, "foo.$bar"), nullptr); ASSERT_TRUE(graph->canPathBeArray(nullptr, "foo")); ASSERT_TRUE(graph->canPathBeArray(nullptr, "foo.$bar")); @@ -2196,7 +2202,7 @@ TEST_F(PipelineDependencyGraphTest, LookupWithDollarInAsField) { runTest([&] { // The $lookup stage declares "result$data" - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "result$data"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "result$data"), stages[0]); // "result$data" can be an array (it's the output array from $lookup) ASSERT_TRUE(graph->canPathBeArray(nullptr, "result$data")); @@ -2235,9 +2241,9 @@ TEST_F(PipelineDependencyGraphTest, NumericFirstComponentIsFieldName) { runTest([&] { // First component "0" is treated as a field name. Will look up path "0.sub". // Should find the stage removing "0.sub" - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "0.sub"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "0.sub"), stages[1]); // 0 comes originally from the collection - ASSERT_EQUALS(graph->getDeclaringStage(stages[0].get(), "0"), nullptr); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(stages[0].get(), "0"), nullptr); // "a" is removed by the 'project' operator and goes to 'kMissing'. ASSERT_FALSE(graph->canPathBeArray(nullptr, "a")); @@ -2265,7 +2271,7 @@ TEST_F(PipelineDependencyGraphTest, NumericPathComponentInMiddle) { ])"); runTest([&] { - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "items.0.details"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "items.0.details"), stages[1]); // "items.0.details" was set as non-array, thus this should be false. ASSERT_FALSE(graph->canPathBeArray(nullptr, "result")); @@ -2284,9 +2290,9 @@ TEST_F(PipelineDependencyGraphTest, MultipleNumericComponentsInMiddle) { runTest([&] { // Should handle nested numeric paths without crashing - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "matrix"), stages[2]); - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "matrix.0.1"), stages[2]); - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "matrix.0.1.value"), stages[2]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "matrix"), stages[2]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "matrix.0.1"), stages[2]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "matrix.0.1.value"), stages[2]); // "matrix" was set as non-array, thus this should be false. // This goes to kMissing @@ -2309,7 +2315,7 @@ TEST_F(PipelineDependencyGraphTest, NumericWithLeadingZeroNotTruncated) { ])"); runTest([&] { - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "data.01.value"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "data.01.value"), stages[1]); // goes to kMissing ASSERT_FALSE(graph->canPathBeArray(nullptr, "data")); @@ -2331,7 +2337,7 @@ TEST_F(PipelineDependencyGraphTest, CheckingValidityOfNumericWithLeadingZeroNotT ])"); runTest([&] { - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "data.foo.value"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "data.foo.value"), stages[1]); // goes to kMissing ASSERT_FALSE(graph->canPathBeArray(nullptr, "data")); @@ -2354,7 +2360,7 @@ TEST_F(PipelineDependencyGraphTest, SuffixNumericPathComponentSimple) { ])"); runTest([&] { - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "arr.0"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "arr.0"), stages[1]); // goes to kMissing ASSERT_FALSE(graph->canPathBeArray(nullptr, "arr.0")); @@ -2369,7 +2375,7 @@ TEST_F(PipelineDependencyGraphTest, SuffixNumericPathSetToArray) { ])"); runTest([&] { - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "items.0"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "items.0"), stages[1]); ASSERT_TRUE(graph->canPathBeArray(nullptr, "first")); @@ -2386,7 +2392,7 @@ TEST_F(PipelineDependencyGraphTest, SuffixNumericPathMultipleComponents) { ])"); runTest([&] { - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "matrix.0"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "matrix.0"), stages[1]); ASSERT_TRUE(graph->canPathBeArray(nullptr, "val")); @@ -2404,7 +2410,7 @@ TEST_F(PipelineDependencyGraphTest, SuffixNumericPathSetToNonArray) { runTest([&] { // The $project stage declares "matrix.0" (and by extension "matrix.0.1") - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "matrix.0"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "matrix.0"), stages[1]); ASSERT_FALSE(graph->canPathBeArray(nullptr, "val")); }); @@ -2418,7 +2424,7 @@ TEST_F(PipelineDependencyGraphTest, SuffixNumericPathSetToNonArrayWithSet) { runTest([&] { // The $set stage declares "val" - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "val"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "val"), stages[1]); ASSERT_FALSE(graph->canPathBeArray(nullptr, "val")); }); @@ -2433,8 +2439,8 @@ TEST_F(PipelineDependencyGraphTest, DollarPrefixedNestedPathComponentWithArrayne setPipeline(R"([{$match: {"foo.$bar": 1}}])"); runTest([&] { - // getDeclaringStage returns nullptr (field comes from base collection) - ASSERT_EQ(graph->getDeclaringStage(nullptr, "foo.$bar"), nullptr); + // getDeclaringStage_forTest returns nullptr (field comes from base collection) + ASSERT_EQ(graph->getDeclaringStage_forTest(nullptr, "foo.$bar"), nullptr); // Without PathArrayness metadata, both conservatively assume they can be an array ASSERT_TRUE(graph->canPathBeArray(nullptr, "foo")); @@ -2454,10 +2460,10 @@ TEST_F(PipelineDependencyGraphTest, SuffixNumericPathSetToNonArrayWithArrayness) ])"); runTest([&] { - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "matrix"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "matrix"), stages[1]); // The $project stage declares "matrix.0" (and by extension "matrix.0.1") - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "matrix.0"), stages[1]); - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "matrix.0.1"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "matrix.0"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "matrix.0.1"), stages[1]); // "matrix" is explicitly marked as non-array in PathArrayness, but // after the $set it goes to kMissing since the $project doesn't include it @@ -2481,7 +2487,7 @@ TEST_F(PipelineDependencyGraphTest, SuffixNumericPathSetToNonArrayWithSetAndArra runTest([&] { // The $set stage declares "val" - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "val"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "val"), stages[1]); // With $set (unlike $project), "matrix" is still accessible // "matrix" is explicitly marked as non-array in PathArrayness @@ -2498,8 +2504,8 @@ TEST_F(PipelineDependencyGraphTest, ModifyPathLookupDottedAsPreservesSiblingWhen runTest([&] { // 'a.c' definitely comes from the base document, if it exists. - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a.c"), nullptr); - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a.b"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a.c"), nullptr); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a.b"), stages[0]); // The prefix is always a plain object. ASSERT_FALSE(graph->canPathBeArray(nullptr, "a")); ASSERT_FALSE(graph->canPathBeArray(nullptr, "a.c")); @@ -2517,8 +2523,8 @@ TEST_F(PipelineDependencyGraphTest, ModifyPathLookupDottedAsShadowsPriorSibling) runTest([&] { // The $set declared 'a.c', but the $lookup will discard it if 'a' is an array. - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a.c"), stages[1]); - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a.b"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a.c"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a.b"), stages[1]); ASSERT_FALSE(graph->canPathBeArray(nullptr, "a")); }); } @@ -2532,8 +2538,8 @@ TEST_F(PipelineDependencyGraphTest, ModifyPathLookupDottedAsPreservesPriorSiblin ])"); runTest([&] { - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a.c"), stages[0]); - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a.b"), stages[1]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a.c"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a.b"), stages[1]); }); } @@ -2541,8 +2547,8 @@ TEST_F(PipelineDependencyGraphTest, ModifyPathLookupDottedAsPreservesPriorSiblin TEST_F(PipelineDependencyGraphTest, LookupDeepAsDestroySiblingsAtAllLevels) { setPipeline(R"([{$lookup: {from: "coll_b", as: "a.b.c", pipeline: []}}])"); runTest([&] { - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a.d"), stages[0]); - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a.b.d"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a.d"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a.b.d"), stages[0]); ASSERT_FALSE(graph->canPathBeArray(nullptr, "a")); ASSERT_FALSE(graph->canPathBeArray(nullptr, "a.b")); }); @@ -2555,8 +2561,8 @@ TEST_F(PipelineDependencyGraphTest, LookupDeepAsPartialPreservation) { setPipeline(R"([{$lookup: {from: "coll_b", as: "a.b.c", pipeline: []}}])"); runTest([&] { - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a.d"), nullptr); - ASSERT_EQUALS(graph->getDeclaringStage(nullptr, "a.b.d"), stages[0]); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a.d"), nullptr); + ASSERT_EQUALS(graph->getDeclaringStage_forTest(nullptr, "a.b.d"), stages[0]); ASSERT_FALSE(graph->canPathBeArray(nullptr, "a")); ASSERT_FALSE(graph->canPathBeArray(nullptr, "a.b")); }); diff --git a/src/mongo/db/query/compiler/dependency_analysis/pipeline_dependency_graph_test_util.h b/src/mongo/db/query/compiler/dependency_analysis/pipeline_dependency_graph_test_util.h index 898fd29ebf2..3469f1dbc06 100644 --- a/src/mongo/db/query/compiler/dependency_analysis/pipeline_dependency_graph_test_util.h +++ b/src/mongo/db/query/compiler/dependency_analysis/pipeline_dependency_graph_test_util.h @@ -38,7 +38,7 @@ inline void recomputeAndAssert(DependencyGraph& graph, const Pipeline& pipeline, const auto& sources = pipeline.getSources(); for (auto it = sources.begin(); it != sources.end(); ++it) { func(); - graph.recompute(it); + graph.recompute_forTest(it); } func(); }