ExpressionContext::ExpressionContext(OperationContext* opCtx, const AggregationRequest& request, std::unique_ptr<CollatorInterface> collator, std::shared_ptr<MongoProcessInterface> processInterface, StringMap<ResolvedNamespace> resolvedNamespaces, boost::optional<UUID> collUUID) : ExpressionContext(opCtx, collator.get()) { explain = request.getExplain(); comment = request.getComment(); fromMongos = request.isFromMongos(); needsMerge = request.needsMerge(); mergeByPBRT = request.mergeByPBRT(); allowDiskUse = request.shouldAllowDiskUse(); bypassDocumentValidation = request.shouldBypassDocumentValidation(); ns = request.getNamespaceString(); mongoProcessInterface = std::move(processInterface); collation = request.getCollation(); _ownedCollator = std::move(collator); _resolvedNamespaces = std::move(resolvedNamespaces); uuid = std::move(collUUID); if (request.getRuntimeConstants()) { variables.setRuntimeConstants(request.getRuntimeConstants().get()); } else { variables.generateRuntimeConstants(opCtx); } }
std::unique_ptr<DocumentSourceOut::LiteParsed> DocumentSourceOut::LiteParsed::parse( const AggregationRequest& request, const BSONElement& spec) { uassert(ErrorCodes::TypeMismatch, str::stream() << "$out stage requires a string or object argument, but found " << typeName(spec.type()), spec.type() == BSONType::String || spec.type() == BSONType::Object); NamespaceString targetNss; bool allowSharded; WriteModeEnum mode; if (spec.type() == BSONType::String) { targetNss = NamespaceString(request.getNamespaceString().db(), spec.valueStringData()); allowSharded = false; mode = WriteModeEnum::kModeReplaceCollection; } else if (spec.type() == BSONType::Object) { auto outSpec = DocumentSourceOutSpec::parse(IDLParserErrorContext("$out"), spec.embeddedObject()); if (auto targetDb = outSpec.getTargetDb()) { targetNss = NamespaceString(*targetDb, outSpec.getTargetCollection()); } else { targetNss = NamespaceString(request.getNamespaceString().db(), outSpec.getTargetCollection()); } mode = outSpec.getMode(); // Sharded output collections are not allowed with mode "replaceCollection". allowSharded = mode != WriteModeEnum::kModeReplaceCollection; } uassert(ErrorCodes::InvalidNamespace, str::stream() << "Invalid $out target namespace, " << targetNss.ns(), targetNss.isValid()); // All modes require the "insert" action. ActionSet actions{ActionType::insert}; switch (mode) { case WriteModeEnum::kModeReplaceCollection: actions.addAction(ActionType::remove); break; case WriteModeEnum::kModeReplaceDocuments: actions.addAction(ActionType::update); break; case WriteModeEnum::kModeInsertDocuments: // "insertDocuments" mode only requires the "insert" action. break; } if (request.shouldBypassDocumentValidation()) { actions.addAction(ActionType::bypassDocumentValidation); } PrivilegeVector privileges{Privilege(ResourcePattern::forExactNamespace(targetNss), actions)}; return stdx::make_unique<DocumentSourceOut::LiteParsed>( std::move(targetNss), std::move(privileges), allowSharded); }
ExpressionContext::ExpressionContext(OperationContext* opCtx, const AggregationRequest& request, std::unique_ptr<CollatorInterface> collator, StringMap<ResolvedNamespace> resolvedNamespaces) : isExplain(request.isExplain()), inShard(request.isFromRouter()), extSortAllowed(request.shouldAllowDiskUse()), bypassDocumentValidation(request.shouldBypassDocumentValidation()), ns(request.getNamespaceString()), opCtx(opCtx), collation(request.getCollation()), _collator(std::move(collator)), _documentComparator(_collator.get()), _valueComparator(_collator.get()), _resolvedNamespaces(std::move(resolvedNamespaces)) {}
std::unique_ptr<LiteParsedDocumentSourceForeignCollections> DocumentSourceOut::liteParse( const AggregationRequest& request, const BSONElement& spec) { uassert(ErrorCodes::TypeMismatch, str::stream() << "$out stage requires a string argument, but found " << typeName(spec.type()), spec.type() == BSONType::String); NamespaceString targetNss(request.getNamespaceString().db(), spec.valueStringData()); uassert(ErrorCodes::InvalidNamespace, str::stream() << "Invalid $out target namespace, " << targetNss.ns(), targetNss.isValid()); ActionSet actions{ActionType::remove, ActionType::insert}; if (request.shouldBypassDocumentValidation()) { actions.addAction(ActionType::bypassDocumentValidation); } PrivilegeVector privileges{Privilege(ResourcePattern::forExactNamespace(targetNss), actions)}; return stdx::make_unique<LiteParsedDocumentSourceForeignCollections>(std::move(targetNss), std::move(privileges)); }