diff options
Diffstat (limited to 'src/mongo/db/pipeline/pipeline.cpp')
-rw-r--r-- | src/mongo/db/pipeline/pipeline.cpp | 35 |
1 files changed, 23 insertions, 12 deletions
diff --git a/src/mongo/db/pipeline/pipeline.cpp b/src/mongo/db/pipeline/pipeline.cpp index 89a76aa9412..4125bc242ff 100644 --- a/src/mongo/db/pipeline/pipeline.cpp +++ b/src/mongo/db/pipeline/pipeline.cpp @@ -185,20 +185,31 @@ intrusive_ptr<Pipeline> Pipeline::parseCommand(string& errmsg, str::stream() << "pipeline element " << iStep << " is not an object", pipeElement.type() == Object); - sources.push_back(DocumentSource::parse(pCtx, pipeElement.Obj())); - if (sources.back()->isValidInitialSource()) { - uassert(28837, - str::stream() << sources.back()->getSourceName() - << " is only valid as the first stage in a pipeline.", - iStep == 0); - } + vector<intrusive_ptr<DocumentSource>> stepSources = + DocumentSource::parse(pCtx, pipeElement.Obj()); + + // Iterate over the steps in stepSource. stepSource may have more than one step if the + // current step is a DocumentSource alias. + const size_t nStepSources = stepSources.size(); + for (size_t iStepSource = 0; iStepSource < nStepSources; ++iStepSource) { + sources.push_back(stepSources[iStepSource]); + + if (sources.back()->isValidInitialSource()) { + uassert(28837, + str::stream() << sources.back()->getSourceName() + << " is only valid as the first stage in a pipeline.", + iStep == 0 && iStepSource == 0); + } - if (dynamic_cast<DocumentSourceOut*>(sources.back().get())) { - uassert(16991, "$out can only be the final stage in the pipeline", iStep == nSteps - 1); + if (dynamic_cast<DocumentSourceOut*>(sources.back().get())) { + uassert(16991, + "$out can only be the final stage in the pipeline", + iStep == nSteps - 1 && iStepSource == nStepSources - 1); - uassert(ErrorCodes::InvalidOptions, - "$out can only be used with the 'local' read concern level", - readConcernArgs.getLevel() == repl::ReadConcernLevel::kLocalReadConcern); + uassert(ErrorCodes::InvalidOptions, + "$out can only be used with the 'local' read concern level", + readConcernArgs.getLevel() == repl::ReadConcernLevel::kLocalReadConcern); + } } } |