diff options
Diffstat (limited to 'src/mongo/db/exec')
-rw-r--r-- | src/mongo/db/exec/document_value/document.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/exec/document_value/document_metadata_fields.cpp | 33 | ||||
-rw-r--r-- | src/mongo/db/exec/document_value/document_metadata_fields.h | 14 | ||||
-rw-r--r-- | src/mongo/db/exec/working_set_common.cpp | 26 | ||||
-rw-r--r-- | src/mongo/db/exec/working_set_common.h | 6 |
5 files changed, 71 insertions, 12 deletions
diff --git a/src/mongo/db/exec/document_value/document.cpp b/src/mongo/db/exec/document_value/document.cpp index 245d58f5a40..2f6660bd568 100644 --- a/src/mongo/db/exec/document_value/document.cpp +++ b/src/mongo/db/exec/document_value/document.cpp @@ -493,6 +493,10 @@ constexpr StringData Document::metaFieldSearchHighlights; BSONObj Document::toBsonWithMetaData(bool use42ChangeStreamSortKeys) const { BSONObjBuilder bb; toBson(&bb); + if (!metadata()) { + return bb.obj(); + } + if (metadata().hasTextScore()) bb.append(metaFieldTextScore, metadata().getTextScore()); if (metadata().hasRandVal()) diff --git a/src/mongo/db/exec/document_value/document_metadata_fields.cpp b/src/mongo/db/exec/document_value/document_metadata_fields.cpp index 68b0a0da0d0..c7c2e4d202d 100644 --- a/src/mongo/db/exec/document_value/document_metadata_fields.cpp +++ b/src/mongo/db/exec/document_value/document_metadata_fields.cpp @@ -234,4 +234,37 @@ Value DocumentMetadataFields::deserializeSortKey(bool isSingleElementKey, return Value{std::move(keys)}; } +const char* DocumentMetadataFields::typeNameToDebugString(DocumentMetadataFields::MetaType type) { + switch (type) { + case DocumentMetadataFields::kGeoNearDist: + return "$geoNear distance"; + case DocumentMetadataFields::kGeoNearPoint: + return "$geoNear point"; + case DocumentMetadataFields::kIndexKey: + return "index key"; + case DocumentMetadataFields::kRandVal: + return "rand val"; + case DocumentMetadataFields::kRecordId: + return "record ID"; + case DocumentMetadataFields::kSearchHighlights: + return "$searchBeta highlights"; + case DocumentMetadataFields::kSearchScore: + return "$searchBeta score"; + case DocumentMetadataFields::kSortKey: + return "sort key"; + case DocumentMetadataFields::kTextScore: + return "text score"; + default: + MONGO_UNREACHABLE; + } +} // namespace + + +std::ostream& operator<<(std::ostream& stream, DocumentMetadataFields::MetaType type) { + return stream << DocumentMetadataFields::typeNameToDebugString(type); +} + +StringBuilder& operator<<(StringBuilder& stream, DocumentMetadataFields::MetaType type) { + return stream << DocumentMetadataFields::typeNameToDebugString(type); +} } // namespace mongo diff --git a/src/mongo/db/exec/document_value/document_metadata_fields.h b/src/mongo/db/exec/document_value/document_metadata_fields.h index f5104c847de..ef4627b14c6 100644 --- a/src/mongo/db/exec/document_value/document_metadata_fields.h +++ b/src/mongo/db/exec/document_value/document_metadata_fields.h @@ -36,7 +36,6 @@ #include "mongo/db/record_id.h" namespace mongo { - /** * This class represents the metadata that the query execution engine can associate with a * particular intermediate result (either index key or document) passing between execution stages. @@ -55,7 +54,8 @@ namespace mongo { class DocumentMetadataFields { public: enum MetaType : char { - kGeoNearDist, + // Start from 1 so that these values can be stored in a bitset. + kGeoNearDist = 1, kGeoNearPoint, kIndexKey, kRandVal, @@ -91,6 +91,11 @@ public: static Value deserializeSortKey(bool isSingleElementKey, const BSONObj& bsonSortKey); /** + * Given a metadata type, return a (debug) string representation. + */ + static const char* typeNameToDebugString(DocumentMetadataFields::MetaType type); + + /** * Constructs a new DocumentMetadataFields in an uninitialized state. */ DocumentMetadataFields() = default; @@ -324,4 +329,9 @@ private: std::unique_ptr<MetadataHolder> _holder; }; +using QueryMetadataBitSet = std::bitset<DocumentMetadataFields::MetaType::kNumFields>; + +// Prints the metadata's name to the given stream. +std::ostream& operator<<(std::ostream& stream, DocumentMetadataFields::MetaType type); +StringBuilder& operator<<(StringBuilder& sb, DocumentMetadataFields::MetaType type); } // namespace mongo diff --git a/src/mongo/db/exec/working_set_common.cpp b/src/mongo/db/exec/working_set_common.cpp index ef1fa322c42..571e7a25b4f 100644 --- a/src/mongo/db/exec/working_set_common.cpp +++ b/src/mongo/db/exec/working_set_common.cpp @@ -100,7 +100,7 @@ bool WorkingSetCommon::fetch(OperationContext* opCtx, return true; } -BSONObj WorkingSetCommon::buildMemberStatusObject(const Status& status) { +Document WorkingSetCommon::buildMemberStatusObject(const Status& status) { BSONObjBuilder bob; bob.append("ok", status.isOK() ? 1.0 : 0.0); bob.append("code", status.code()); @@ -109,7 +109,7 @@ BSONObj WorkingSetCommon::buildMemberStatusObject(const Status& status) { extraInfo->serialize(&bob); } - return bob.obj(); + return Document{bob.obj()}; } WorkingSetID WorkingSetCommon::allocateStatusMember(WorkingSet* ws, const Status& status) { @@ -117,14 +117,19 @@ WorkingSetID WorkingSetCommon::allocateStatusMember(WorkingSet* ws, const Status WorkingSetID wsid = ws->allocate(); WorkingSetMember* member = ws->get(wsid); - member->resetDocument(SnapshotId(), buildMemberStatusObject(status)); + member->doc = {SnapshotId(), buildMemberStatusObject(status)}; member->transitionToOwnedObj(); return wsid; } +bool WorkingSetCommon::isValidStatusMemberObject(const Document& obj) { + return !obj["ok"].missing() && obj["code"].getType() == BSONType::NumberInt && + obj["errmsg"].getType() == BSONType::String; +} + bool WorkingSetCommon::isValidStatusMemberObject(const BSONObj& obj) { - return obj.hasField("ok") && obj["code"].type() == NumberInt && obj["errmsg"].type() == String; + return isValidStatusMemberObject(Document{obj}); } boost::optional<Document> WorkingSetCommon::getStatusMemberDocument(const WorkingSet& ws, @@ -136,8 +141,8 @@ boost::optional<Document> WorkingSetCommon::getStatusMemberDocument(const Workin if (!member->hasOwnedObj()) { return boost::none; } - BSONObj obj = member->doc.value().toBson(); - if (!isValidStatusMemberObject(obj)) { + + if (!isValidStatusMemberObject(member->doc.value())) { return boost::none; } return member->doc.value(); @@ -150,17 +155,22 @@ Status WorkingSetCommon::getMemberObjectStatus(const BSONObj& memberObj) { memberObj); } +Status WorkingSetCommon::getMemberObjectStatus(const Document& doc) { + return getMemberObjectStatus(doc.toBson()); +} + Status WorkingSetCommon::getMemberStatus(const WorkingSetMember& member) { invariant(member.hasObj()); return getMemberObjectStatus(member.doc.value().toBson()); } std::string WorkingSetCommon::toStatusString(const BSONObj& obj) { - if (!isValidStatusMemberObject(obj)) { + Document doc{obj}; + if (!isValidStatusMemberObject(doc)) { Status unknownStatus(ErrorCodes::UnknownError, "no details available"); return unknownStatus.toString(); } - return getMemberObjectStatus(obj).toString(); + return getMemberObjectStatus(doc).toString(); } } // namespace mongo diff --git a/src/mongo/db/exec/working_set_common.h b/src/mongo/db/exec/working_set_common.h index 15657a87725..0ebeb2ae65c 100644 --- a/src/mongo/db/exec/working_set_common.h +++ b/src/mongo/db/exec/working_set_common.h @@ -56,9 +56,9 @@ public: unowned_ptr<SeekableRecordCursor> cursor); /** - * Build a BSONObj which represents a Status to return in a WorkingSet. + * Build a Document which represents a Status to return in a WorkingSet. */ - static BSONObj buildMemberStatusObject(const Status& status); + static Document buildMemberStatusObject(const Status& status); /** * Allocate a new WSM and initialize it with @@ -75,6 +75,7 @@ public: /** * Returns true if object was created by allocateStatusMember(). */ + static bool isValidStatusMemberObject(const Document& obj); static bool isValidStatusMemberObject(const BSONObj& obj); /** @@ -89,6 +90,7 @@ public: * Assumes isValidStatusMemberObject(). */ static Status getMemberObjectStatus(const BSONObj& memberObj); + static Status getMemberObjectStatus(const Document& memberObj); /** * Returns status from working set member created with allocateStatusMember(). |