diff options
Diffstat (limited to 'src/mongo/db/pipeline/document_source_match.cpp')
| -rw-r--r-- | src/mongo/db/pipeline/document_source_match.cpp | 50 |
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 |
