summaryrefslogtreecommitdiff
path: root/src/mongo/db/pipeline
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/pipeline')
-rw-r--r--src/mongo/db/pipeline/document_source_merge.h8
-rw-r--r--src/mongo/db/pipeline/document_source_set_window_fields.cpp4
-rw-r--r--src/mongo/db/pipeline/document_source_set_window_fields.h37
-rw-r--r--src/mongo/db/pipeline/lite_parsed_document_source.cpp15
-rw-r--r--src/mongo/db/pipeline/lite_parsed_document_source.h7
-rw-r--r--src/mongo/db/pipeline/lite_parsed_pipeline.cpp10
-rw-r--r--src/mongo/db/pipeline/lite_parsed_pipeline.h7
7 files changed, 84 insertions, 4 deletions
diff --git a/src/mongo/db/pipeline/document_source_merge.h b/src/mongo/db/pipeline/document_source_merge.h
index a3623fca678..05a87f1e340 100644
--- a/src/mongo/db/pipeline/document_source_merge.h
+++ b/src/mongo/db/pipeline/document_source_merge.h
@@ -90,11 +90,17 @@ public:
ReadConcernSupportResult supportsReadConcern(repl::ReadConcernLevel level,
bool isImplicitDefault) const final {
- return {
+ ReadConcernSupportResult result = {
{level == repl::ReadConcernLevel::kLinearizableReadConcern,
{ErrorCodes::InvalidOptions,
"{} cannot be used with a 'linearizable' read concern level"_format(kStageName)}},
Status::OK()};
+ auto pipelineReadConcern = LiteParsedDocumentSourceNestedPipelines::supportsReadConcern(
+ level, isImplicitDefault);
+ // Merge the result from the sub-pipeline into the $merge specific read concern result
+ // to preserve the $merge errors over the internal pipeline errors.
+ result.merge(pipelineReadConcern);
+ return result;
}
PrivilegeVector requiredPrivileges(bool isMongos,
diff --git a/src/mongo/db/pipeline/document_source_set_window_fields.cpp b/src/mongo/db/pipeline/document_source_set_window_fields.cpp
index 0df6d6d5927..7a9fe901c8f 100644
--- a/src/mongo/db/pipeline/document_source_set_window_fields.cpp
+++ b/src/mongo/db/pipeline/document_source_set_window_fields.cpp
@@ -75,14 +75,14 @@ bool modifiedSortPaths(const SortPattern& pat, const DocumentSource::GetModPaths
REGISTER_DOCUMENT_SOURCE_WITH_MIN_VERSION(
setWindowFields,
- LiteParsedDocumentSourceDefault::parse,
+ document_source_set_window_fields::LiteParsedSetWindowFields::parse,
document_source_set_window_fields::createFromBson,
AllowedWithApiStrict::kNeverInVersion1,
multiversion::FeatureCompatibilityVersion::kFullyDowngradedTo_5_0);
REGISTER_DOCUMENT_SOURCE_WITH_MIN_VERSION(
_internalSetWindowFields,
- LiteParsedDocumentSourceDefault::parse,
+ document_source_set_window_fields::LiteParsedSetWindowFields::parse,
DocumentSourceInternalSetWindowFields::createFromBson,
AllowedWithApiStrict::kNeverInVersion1,
multiversion::FeatureCompatibilityVersion::kFullyDowngradedTo_5_0);
diff --git a/src/mongo/db/pipeline/document_source_set_window_fields.h b/src/mongo/db/pipeline/document_source_set_window_fields.h
index f854de92653..313961216c4 100644
--- a/src/mongo/db/pipeline/document_source_set_window_fields.h
+++ b/src/mongo/db/pipeline/document_source_set_window_fields.h
@@ -89,6 +89,39 @@ std::list<boost::intrusive_ptr<DocumentSource>> create(
boost::optional<boost::intrusive_ptr<Expression>> partitionBy,
const boost::optional<SortPattern>& sortBy,
std::vector<WindowFunctionStatement> outputFields);
+
+class LiteParsedSetWindowFields : public LiteParsedDocumentSource {
+public:
+ static std::unique_ptr<LiteParsedSetWindowFields> parse(const NamespaceString& nss,
+ const BSONElement& spec) {
+ return std::make_unique<LiteParsedSetWindowFields>(spec.fieldName());
+ }
+
+ explicit LiteParsedSetWindowFields(std::string parseTimeName)
+ : LiteParsedDocumentSource(std::move(parseTimeName)) {}
+
+ ReadConcernSupportResult supportsReadConcern(repl::ReadConcernLevel level,
+ bool isImplicitDefault) const {
+ // $setWindowFields cannot spill to disk if read concern is set to "snapshot".
+ // TODO SERVER-59772 Enable $setWindowFields with read concern "snapshot".
+ return {{level == repl::ReadConcernLevel::kSnapshotReadConcern && !isImplicitDefault,
+ {ErrorCodes::InvalidOptions,
+ str::stream() << "Aggregation stage " << kStageName
+ << " cannot run with readConcern '"
+ << repl::readConcernLevels::toString(
+ repl::ReadConcernLevel::kSnapshotReadConcern)}},
+ // The default read concern can't be snapshot.
+ boost::none};
+ }
+
+ stdx::unordered_set<NamespaceString> getInvolvedNamespaces() const final {
+ return stdx::unordered_set<NamespaceString>();
+ }
+
+ PrivilegeVector requiredPrivileges(bool isMongos, bool bypassDocumentValidation) const final {
+ return {};
+ }
+};
} // namespace document_source_set_window_fields
class DocumentSourceInternalSetWindowFields final : public DocumentSource {
@@ -131,7 +164,9 @@ public:
HostTypeRequirement::kNone,
DiskUseRequirement::kWritesTmpData,
FacetRequirement::kAllowed,
- TransactionRequirement::kAllowed,
+ // $setWindowFields does not work inside transactions.
+ // TODO SERVER-59772 Enable $setWindowFields inside transactions.
+ TransactionRequirement::kNotAllowed,
LookupRequirement::kAllowed,
UnionRequirement::kAllowed);
}
diff --git a/src/mongo/db/pipeline/lite_parsed_document_source.cpp b/src/mongo/db/pipeline/lite_parsed_document_source.cpp
index 9b28609c9d7..121b916a389 100644
--- a/src/mongo/db/pipeline/lite_parsed_document_source.cpp
+++ b/src/mongo/db/pipeline/lite_parsed_document_source.cpp
@@ -132,4 +132,19 @@ bool LiteParsedDocumentSourceNestedPipelines::allowShardedForeignCollection(
});
}
+ReadConcernSupportResult LiteParsedDocumentSourceNestedPipelines::supportsReadConcern(
+ repl::ReadConcernLevel level, bool isImplicitDefault) const {
+ // Assume that the document source holding the pipeline has no constraints of its own, so
+ // return the strictest of the constraints on the sub-pipelines.
+ auto result = ReadConcernSupportResult::allSupportedAndDefaultPermitted();
+ for (auto& pipeline : _pipelines) {
+ result.merge(pipeline.sourcesSupportReadConcern(level, isImplicitDefault));
+ // If both result statuses are already not OK, stop checking.
+ if (!result.readConcernSupport.isOK() && !result.defaultReadConcernPermit.isOK()) {
+ break;
+ }
+ }
+ return result;
+}
+
} // namespace mongo
diff --git a/src/mongo/db/pipeline/lite_parsed_document_source.h b/src/mongo/db/pipeline/lite_parsed_document_source.h
index ecc56c170ab..f5fc5fbcb06 100644
--- a/src/mongo/db/pipeline/lite_parsed_document_source.h
+++ b/src/mongo/db/pipeline/lite_parsed_document_source.h
@@ -295,6 +295,13 @@ public:
return _pipelines;
}
+ /**
+ * Check the read concern constraints of all sub-pipelines. If the stage that owns the
+ * sub-pipelines has its own constraints this should be overridden to take those into account.
+ */
+ ReadConcernSupportResult supportsReadConcern(repl::ReadConcernLevel level,
+ bool isImplicitDefault) const override;
+
protected:
boost::optional<NamespaceString> _foreignNss;
std::vector<LiteParsedPipeline> _pipelines;
diff --git a/src/mongo/db/pipeline/lite_parsed_pipeline.cpp b/src/mongo/db/pipeline/lite_parsed_pipeline.cpp
index 94f29755d9b..ff8491c88b7 100644
--- a/src/mongo/db/pipeline/lite_parsed_pipeline.cpp
+++ b/src/mongo/db/pipeline/lite_parsed_pipeline.cpp
@@ -73,6 +73,16 @@ ReadConcernSupportResult LiteParsedPipeline::supportsReadConcern(
// 3. If either the specified or default readConcern have not already been rejected, determine
// whether the pipeline stages support them. If not, we record the first error we encounter.
+ result.merge(sourcesSupportReadConcern(level, isImplicitDefault));
+
+ return result;
+}
+
+ReadConcernSupportResult LiteParsedPipeline::sourcesSupportReadConcern(
+ repl::ReadConcernLevel level, bool isImplicitDefault) const {
+ // Start by assuming that we will support both readConcern and cluster-wide default.
+ ReadConcernSupportResult result = ReadConcernSupportResult::allSupportedAndDefaultPermitted();
+
for (auto&& spec : _stageSpecs) {
// If both result statuses are already not OK, stop checking further stages.
if (!result.readConcernSupport.isOK() && !result.defaultReadConcernPermit.isOK()) {
diff --git a/src/mongo/db/pipeline/lite_parsed_pipeline.h b/src/mongo/db/pipeline/lite_parsed_pipeline.h
index 0a7f24b83a5..eecaaa937e1 100644
--- a/src/mongo/db/pipeline/lite_parsed_pipeline.h
+++ b/src/mongo/db/pipeline/lite_parsed_pipeline.h
@@ -136,6 +136,13 @@ public:
bool enableMajorityReadConcern) const;
/**
+ * Checks that all of the stages in this pipeline are allowed to run with the specified read
+ * concern level. Does not do any pipeline global checks.
+ */
+ ReadConcernSupportResult sourcesSupportReadConcern(repl::ReadConcernLevel level,
+ bool isImplicitDefault) const;
+
+ /**
* Verifies that this pipeline is allowed to run in a multi-document transaction. This ensures
* that each stage is compatible, and throws a UserException if not. This should only be called
* if the caller has determined the current operation is part of a transaction.