summaryrefslogtreecommitdiff
path: root/src/mongo/db/pipeline/document_source_match.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/pipeline/document_source_match.cpp')
-rw-r--r--src/mongo/db/pipeline/document_source_match.cpp50
1 files changed, 33 insertions, 17 deletions
diff --git a/src/mongo/db/pipeline/document_source_match.cpp b/src/mongo/db/pipeline/document_source_match.cpp
index 418f1821b4b..3690b603ab7 100644
--- a/src/mongo/db/pipeline/document_source_match.cpp
+++ b/src/mongo/db/pipeline/document_source_match.cpp
@@ -47,6 +47,7 @@
#include "mongo/db/pipeline/expression.h"
#include "mongo/db/pipeline/lite_parsed_document_source.h"
#include "mongo/db/pipeline/semantic_analysis.h"
+#include "mongo/logv2/redaction.h"
#include "mongo/util/ctype.h"
#include "mongo/util/str.h"
@@ -67,11 +68,10 @@ const char* DocumentSourceMatch::getSourceName() const {
return kStageName.rawData();
}
-Value DocumentSourceMatch::serialize(boost::optional<ExplainOptions::Verbosity> explain) const {
- if (explain) {
- BSONObjBuilder builder;
- _expression->serialize(&builder);
- return Value(DOC(getSourceName() << Document(builder.obj())));
+Value DocumentSourceMatch::serialize(const SerializationOptions& opts) const {
+ if (opts.verbosity || opts.transformIdentifiers ||
+ opts.literalPolicy != LiteralSerializationPolicy::kUnchanged) {
+ return Value(DOC(getSourceName() << Document(_expression->serialize(opts))));
}
return Value(DOC(getSourceName() << Document(getQuery())));
}
@@ -449,15 +449,11 @@ DocumentSourceMatch::splitSourceByFunc(const OrderedPathSet& fields,
// the corresponding BSONObj may not exist. Therefore, we take each of these expressions,
// serialize them, and then re-parse them, constructing new BSON that is owned by the
// DocumentSourceMatch.
- BSONObjBuilder firstBob;
- newExpr.first->serialize(&firstBob);
- auto firstMatch = DocumentSourceMatch::create(firstBob.obj(), pExpCtx);
+ auto firstMatch = DocumentSourceMatch::create(newExpr.first->serialize(), pExpCtx);
intrusive_ptr<DocumentSourceMatch> secondMatch;
if (newExpr.second) {
- BSONObjBuilder secondBob;
- newExpr.second->serialize(&secondBob);
- secondMatch = DocumentSourceMatch::create(secondBob.obj(), pExpCtx);
+ secondMatch = DocumentSourceMatch::create(newExpr.second->serialize(), pExpCtx);
}
return {std::move(firstMatch), std::move(secondMatch)};
@@ -469,8 +465,9 @@ boost::intrusive_ptr<DocumentSourceMatch> DocumentSourceMatch::descendMatchOnPat
const intrusive_ptr<ExpressionContext>& expCtx) {
expression::mapOver(matchExpr, [&descendOn](MatchExpression* node, std::string path) -> void {
// Cannot call this method on a $match including a $elemMatch.
- invariant(node->matchType() != MatchExpression::ELEM_MATCH_OBJECT &&
- node->matchType() != MatchExpression::ELEM_MATCH_VALUE);
+ tassert(9224700,
+ "The given match expression has a node that represents a partial path.",
+ !MatchExpression::isInternalNodeWithPath(node->matchType()));
// Only leaf and array match expressions have a path.
if (node->getCategory() != MatchExpression::MatchCategory::kLeaf &&
node->getCategory() != MatchExpression::MatchCategory::kArrayMatching) {
@@ -478,7 +475,10 @@ boost::intrusive_ptr<DocumentSourceMatch> DocumentSourceMatch::descendMatchOnPat
}
auto leafPath = node->path();
- invariant(expression::isPathPrefixOf(descendOn, leafPath));
+ tassert(9224701,
+ str::stream() << "Expected '" << redact(descendOn) << "' to be a prefix of '"
+ << redact(leafPath) << "', but it is not.",
+ expression::isPathPrefixOf(descendOn, leafPath));
auto newPath = leafPath.substr(descendOn.size() + 1);
if (node->getCategory() == MatchExpression::MatchCategory::kLeaf) {
@@ -490,9 +490,7 @@ boost::intrusive_ptr<DocumentSourceMatch> DocumentSourceMatch::descendMatchOnPat
}
});
- BSONObjBuilder query;
- matchExpr->serialize(&query);
- return new DocumentSourceMatch(query.obj(), expCtx);
+ return new DocumentSourceMatch(matchExpr->serialize(), expCtx);
}
std::pair<boost::intrusive_ptr<DocumentSourceMatch>, boost::intrusive_ptr<DocumentSourceMatch>>
@@ -579,4 +577,22 @@ void DocumentSourceMatch::rebuild(BSONObj filter) {
getDependencies(&_dependencies);
}
+Value DocumentSourceInternalChangeStreamMatch::serialize(const SerializationOptions& opts) const {
+ if (opts.literalPolicy != LiteralSerializationPolicy::kUnchanged || opts.transformIdentifiers) {
+ // Stages made internally by 'DocumentSourceChangeStream' should not be serialized for
+ // query stats. For query stats we will serialize only the user specified $changeStream
+ // stage.
+ return Value();
+ }
+ return doSerialize(opts);
+}
+
+intrusive_ptr<DocumentSourceInternalChangeStreamMatch>
+DocumentSourceInternalChangeStreamMatch::create(BSONObj filter,
+ const intrusive_ptr<ExpressionContext>& expCtx) {
+ intrusive_ptr<DocumentSourceInternalChangeStreamMatch> internalMatch(
+ new DocumentSourceInternalChangeStreamMatch(filter, expCtx));
+ return internalMatch;
+}
+
} // namespace mongo