diff options
author | Andrii Dobroshynskyi <andrii.dobroshynskyi@mongodb.com> | 2020-08-03 05:22:01 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-08-07 18:01:25 +0000 |
commit | a7a9fa2b01104780e9c0e83f26621317fa7254b6 (patch) | |
tree | 1bbd431bd83552a45bbd9f913206321b46794ad4 /src/mongo | |
parent | d0fb0f3a888f2ce8923ab03fc5d88266af7d444e (diff) | |
download | mongo-a7a9fa2b01104780e9c0e83f26621317fa7254b6.tar.gz |
SERVER-49727 Overload << for SBE tags and values into str::stream
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/db/exec/sbe/expressions/expression.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/exec/sbe/sbe_key_string_test.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/exec/sbe/stages/check_bounds.cpp | 5 | ||||
-rw-r--r-- | src/mongo/db/exec/sbe/stages/ix_scan.cpp | 15 | ||||
-rw-r--r-- | src/mongo/db/exec/sbe/stages/scan.cpp | 3 | ||||
-rw-r--r-- | src/mongo/db/exec/sbe/values/value.cpp | 157 | ||||
-rw-r--r-- | src/mongo/db/exec/sbe/values/value.h | 11 | ||||
-rw-r--r-- | src/mongo/db/query/plan_executor_sbe.cpp | 10 |
8 files changed, 125 insertions, 80 deletions
diff --git a/src/mongo/db/exec/sbe/expressions/expression.cpp b/src/mongo/db/exec/sbe/expressions/expression.cpp index b25936d2633..78c632c646b 100644 --- a/src/mongo/db/exec/sbe/expressions/expression.cpp +++ b/src/mongo/db/exec/sbe/expressions/expression.cpp @@ -77,7 +77,7 @@ std::unique_ptr<vm::CodeFragment> EConstant::compile(CompileCtx& ctx) const { std::vector<DebugPrinter::Block> EConstant::debugPrint() const { std::vector<DebugPrinter::Block> ret; std::stringstream ss; - value::printValue(ss, _tag, _val); + ss << std::make_pair(_tag, _val); ret.emplace_back(ss.str()); diff --git a/src/mongo/db/exec/sbe/sbe_key_string_test.cpp b/src/mongo/db/exec/sbe/sbe_key_string_test.cpp index 303cf6efef1..bdb4879821d 100644 --- a/src/mongo/db/exec/sbe/sbe_key_string_test.cpp +++ b/src/mongo/db/exec/sbe/sbe_key_string_test.cpp @@ -41,7 +41,7 @@ namespace mongo::sbe { namespace { std::string valueDebugString(std::pair<value::TypeTags, value::Value> value) { std::stringstream stream; - value::printValue(stream, value.first, value.second); + stream << std::make_pair(value.first, value.second); return stream.str(); }; } // namespace diff --git a/src/mongo/db/exec/sbe/stages/check_bounds.cpp b/src/mongo/db/exec/sbe/stages/check_bounds.cpp index 2caac57d879..bd932acbca2 100644 --- a/src/mongo/db/exec/sbe/stages/check_bounds.cpp +++ b/src/mongo/db/exec/sbe/stages/check_bounds.cpp @@ -81,7 +81,10 @@ PlanState CheckBoundsStage::getNext() { if (state == PlanState::ADVANCED) { auto [keyTag, keyVal] = _inKeyAccessor->getViewOfValue(); - uassert(ErrorCodes::BadValue, "Wrong index key type", keyTag == value::TypeTags::ksValue); + const auto msgKeyTag = keyTag; + uassert(ErrorCodes::BadValue, + str::stream() << "Wrong index key type: " << msgKeyTag, + keyTag == value::TypeTags::ksValue); auto key = value::getKeyStringView(keyVal); auto bsonKey = KeyString::toBson(*key, _params.ord); diff --git a/src/mongo/db/exec/sbe/stages/ix_scan.cpp b/src/mongo/db/exec/sbe/stages/ix_scan.cpp index f26dd1dbadb..84d9335412c 100644 --- a/src/mongo/db/exec/sbe/stages/ix_scan.cpp +++ b/src/mongo/db/exec/sbe/stages/ix_scan.cpp @@ -184,15 +184,24 @@ void IndexScanStage::open(bool reOpen) { if (_seekKeyLowAccessor && _seekKeyHiAccessor) { auto [tagLow, valLow] = _seekKeyLowAccessor->getViewOfValue(); - uassert(4822851, "seek key is wrong type", tagLow == value::TypeTags::ksValue); + const auto msgTagLow = tagLow; + uassert(4822851, + str::stream() << "seek key is wrong type: " << msgTagLow, + tagLow == value::TypeTags::ksValue); _seekKeyLow = value::getKeyStringView(valLow); auto [tagHi, valHi] = _seekKeyHiAccessor->getViewOfValue(); - uassert(4822852, "seek key is wrong type", tagHi == value::TypeTags::ksValue); + const auto msgTagHi = tagHi; + uassert(4822852, + str::stream() << "seek key is wrong type: " << msgTagHi, + tagHi == value::TypeTags::ksValue); _seekKeyHi = value::getKeyStringView(valHi); } else if (_seekKeyLowAccessor) { auto [tagLow, valLow] = _seekKeyLowAccessor->getViewOfValue(); - uassert(4822853, "seek key is wrong type", tagLow == value::TypeTags::ksValue); + const auto msgTagLow = tagLow; + uassert(4822853, + str::stream() << "seek key is wrong type: " << msgTagLow, + tagLow == value::TypeTags::ksValue); _seekKeyLow = value::getKeyStringView(valLow); _seekKeyHi = nullptr; } else { diff --git a/src/mongo/db/exec/sbe/stages/scan.cpp b/src/mongo/db/exec/sbe/stages/scan.cpp index 5778e34c3bd..d494e399f05 100644 --- a/src/mongo/db/exec/sbe/stages/scan.cpp +++ b/src/mongo/db/exec/sbe/stages/scan.cpp @@ -172,8 +172,9 @@ void ScanStage::open(bool reOpen) { if (auto collection = _coll->getCollection()) { if (_seekKeyAccessor) { auto [tag, val] = _seekKeyAccessor->getViewOfValue(); + const auto msgTag = tag; uassert(ErrorCodes::BadValue, - "seek key is wrong type", + str::stream() << "seek key is wrong type: " << msgTag, tag == value::TypeTags::NumberInt64); _key = RecordId{value::bitcastTo<int64_t>(val)}; diff --git a/src/mongo/db/exec/sbe/values/value.cpp b/src/mongo/db/exec/sbe/values/value.cpp index f281518ca16..99ac902b9f9 100644 --- a/src/mongo/db/exec/sbe/values/value.cpp +++ b/src/mongo/db/exec/sbe/values/value.cpp @@ -88,157 +88,160 @@ void releaseValue(TypeTags tag, Value val) noexcept { } } -std::ostream& operator<<(std::ostream& os, const TypeTags tag) { +template <typename T> +void writeTagToStream(T& stream, const TypeTags tag) { switch (tag) { case TypeTags::Nothing: - os << "Nothing"; + stream << "Nothing"; break; case TypeTags::NumberInt32: - os << "NumberInt32"; + stream << "NumberInt32"; break; case TypeTags::NumberInt64: - os << "NumberInt64"; + stream << "NumberInt64"; break; case TypeTags::NumberDouble: - os << "NumberDouble"; + stream << "NumberDouble"; break; case TypeTags::NumberDecimal: - os << "NumberDecimal"; + stream << "NumberDecimal"; break; case TypeTags::Date: - os << "Date"; + stream << "Date"; break; case TypeTags::Timestamp: - os << "Timestamp"; + stream << "Timestamp"; break; case TypeTags::Boolean: - os << "Boolean"; + stream << "Boolean"; break; case TypeTags::Null: - os << "Null"; + stream << "Null"; break; case TypeTags::StringSmall: - os << "StringSmall"; + stream << "StringSmall"; break; case TypeTags::StringBig: - os << "StringBig"; + stream << "StringBig"; break; case TypeTags::Array: - os << "Array"; + stream << "Array"; break; case TypeTags::ArraySet: - os << "ArraySet"; + stream << "ArraySet"; break; case TypeTags::Object: - os << "Object"; + stream << "Object"; break; case TypeTags::ObjectId: - os << "ObjectId"; + stream << "ObjectId"; break; case TypeTags::bsonObject: - os << "bsonObject"; + stream << "bsonObject"; break; case TypeTags::bsonArray: - os << "bsonArray"; + stream << "bsonArray"; break; case TypeTags::bsonString: - os << "bsonString"; + stream << "bsonString"; break; case TypeTags::bsonObjectId: - os << "bsonObjectId"; + stream << "bsonObjectId"; break; case TypeTags::ksValue: - os << "KeyString"; + stream << "KeyString"; + break; case TypeTags::pcreRegex: - os << "pcreRegex"; + stream << "pcreRegex"; + break; case TypeTags::timeZoneDB: - os << "timeZoneDB"; + stream << "timeZoneDB"; break; default: - os << "unknown tag"; + stream << "unknown tag"; break; } - return os; } -void printValue(std::ostream& os, TypeTags tag, Value val) { +template <typename T> +void writeValueToStream(T& stream, TypeTags tag, Value val) { switch (tag) { case value::TypeTags::NumberInt32: - os << bitcastTo<int32_t>(val); + stream << bitcastTo<int32_t>(val); break; case value::TypeTags::NumberInt64: - os << bitcastTo<int64_t>(val); + stream << bitcastTo<int64_t>(val); break; case value::TypeTags::NumberDouble: - os << bitcastTo<double>(val); + stream << bitcastTo<double>(val); break; case value::TypeTags::NumberDecimal: - os << bitcastTo<Decimal128>(val).toString(); + stream << bitcastTo<Decimal128>(val).toString(); break; case value::TypeTags::Date: - os << bitcastTo<int64_t>(val); + stream << bitcastTo<int64_t>(val); break; case value::TypeTags::Boolean: - os << ((val) ? "true" : "false"); + stream << ((val) ? "true" : "false"); break; case value::TypeTags::Null: - os << "null"; + stream << "null"; break; case value::TypeTags::StringSmall: - os << '"' << getSmallStringView(val) << '"'; + stream << '"' << getSmallStringView(val) << '"'; break; case value::TypeTags::StringBig: - os << '"' << getBigStringView(val) << '"'; + stream << '"' << getBigStringView(val) << '"'; break; case value::TypeTags::Array: { auto arr = getArrayView(val); - os << '['; + stream << '['; for (size_t idx = 0; idx < arr->size(); ++idx) { if (idx != 0) { - os << ", "; + stream << ", "; } auto [tag, val] = arr->getAt(idx); - printValue(os, tag, val); + writeValueToStream(stream, tag, val); } - os << ']'; + stream << ']'; break; } case value::TypeTags::ArraySet: { auto arr = getArraySetView(val); - os << '['; + stream << '['; bool first = true; for (const auto& v : arr->values()) { if (!first) { - os << ", "; + stream << ", "; } first = false; - printValue(os, v.first, v.second); + writeValueToStream(stream, v.first, v.second); } - os << ']'; + stream << ']'; break; } case value::TypeTags::Object: { auto obj = getObjectView(val); - os << '{'; + stream << '{'; for (size_t idx = 0; idx < obj->size(); ++idx) { if (idx != 0) { - os << ", "; + stream << ", "; } - os << '"' << obj->field(idx) << '"'; - os << " : "; + stream << '"' << obj->field(idx) << '"'; + stream << " : "; auto [tag, val] = obj->getAt(idx); - printValue(os, tag, val); + writeValueToStream(stream, tag, val); } - os << '}'; + stream << '}'; break; } case value::TypeTags::ObjectId: { auto objId = getObjectIdView(val); - os << "ObjectId(\"" << OID::from(objId->data()).toString() << "\")"; + stream << "ObjectId(\"" << OID::from(objId->data()).toString() << "\")"; break; } case value::TypeTags::Nothing: - os << "---===*** NOTHING ***===---"; + stream << "---===*** NOTHING ***===---"; break; case value::TypeTags::bsonArray: { const char* be = getRawPointerView(val); @@ -246,21 +249,21 @@ void printValue(std::ostream& os, TypeTags tag, Value val) { bool first = true; // Skip document length. be += 4; - os << '['; + stream << '['; while (*be != 0) { auto sv = bson::fieldNameView(be); if (!first) { - os << ", "; + stream << ", "; } first = false; auto [tag, val] = bson::convertFrom(true, be, end, sv.size()); - printValue(os, tag, val); + writeValueToStream(stream, tag, val); be = bson::advance(be, sv.size()); } - os << ']'; + stream << ']'; break; } case value::TypeTags::bsonObject: { @@ -269,51 +272,51 @@ void printValue(std::ostream& os, TypeTags tag, Value val) { bool first = true; // Skip document length. be += 4; - os << '{'; + stream << '{'; while (*be != 0) { auto sv = bson::fieldNameView(be); if (!first) { - os << ", "; + stream << ", "; } first = false; - os << '"' << sv << '"'; - os << " : "; + stream << '"' << std::string(sv) << '"'; + stream << " : "; auto [tag, val] = bson::convertFrom(true, be, end, sv.size()); - printValue(os, tag, val); + writeValueToStream(stream, tag, val); be = bson::advance(be, sv.size()); } - os << '}'; + stream << '}'; break; } case value::TypeTags::bsonString: - os << '"' << getStringView(value::TypeTags::bsonString, val) << '"'; + stream << '"' << std::string(getStringView(value::TypeTags::bsonString, val)) << '"'; break; case value::TypeTags::bsonObjectId: - os << "---===*** bsonObjectId ***===---"; + stream << "---===*** bsonObjectId ***===---"; break; case value::TypeTags::ksValue: { auto ks = getKeyStringView(val); - os << "KS(" << ks->toString() << ")"; + stream << "KS(" << ks->toString() << ")"; break; } case value::TypeTags::Timestamp: { Timestamp ts{bitcastTo<uint64_t>(val)}; - os << ts.toString(); + stream << ts.toString(); break; } case value::TypeTags::pcreRegex: { auto regex = getPcreRegexView(val); // TODO: Also include the regex flags. - os << "/" << regex->pattern() << "/"; + stream << "/" << regex->pattern() << "/"; break; } case value::TypeTags::timeZoneDB: { auto tzdb = getTimeZoneDBView(val); auto timeZones = tzdb->getTimeZoneStrings(); - os << "TimeZoneDatabase(" + timeZones.front() + "..." + timeZones.back() + ")"; + stream << "TimeZoneDatabase(" + timeZones.front() + "..." + timeZones.back() + ")"; break; } default: @@ -321,6 +324,26 @@ void printValue(std::ostream& os, TypeTags tag, Value val) { } } +std::ostream& operator<<(std::ostream& os, const TypeTags tag) { + writeTagToStream(os, tag); + return os; +} + +str::stream& operator<<(str::stream& str, const TypeTags tag) { + writeTagToStream(str, tag); + return str; +} + +std::ostream& operator<<(std::ostream& os, const std::pair<TypeTags, Value>& value) { + writeValueToStream(os, value.first, value.second); + return os; +} + +str::stream& operator<<(str::stream& str, const std::pair<TypeTags, Value>& value) { + writeValueToStream(str, value.first, value.second); + return str; +} + BSONType tagToType(TypeTags tag) noexcept { switch (tag) { case TypeTags::Nothing: diff --git a/src/mongo/db/exec/sbe/values/value.h b/src/mongo/db/exec/sbe/values/value.h index 2677e28df23..4bd929ad7ed 100644 --- a/src/mongo/db/exec/sbe/values/value.h +++ b/src/mongo/db/exec/sbe/values/value.h @@ -114,8 +114,6 @@ enum class TypeTags : uint8_t { timeZoneDB, }; -std::ostream& operator<<(std::ostream& os, const TypeTags tag); - inline constexpr bool isNumber(TypeTags tag) noexcept { return tag == TypeTags::NumberInt32 || tag == TypeTags::NumberInt64 || tag == TypeTags::NumberDouble || tag == TypeTags::NumberDecimal; @@ -166,10 +164,17 @@ enum class SortDirection : uint8_t { Descending, Ascending }; */ void releaseValue(TypeTags tag, Value val) noexcept; std::pair<TypeTags, Value> copyValue(TypeTags tag, Value val); -void printValue(std::ostream& os, TypeTags tag, Value val); std::size_t hashValue(TypeTags tag, Value val) noexcept; /** + * Overloads for writing values and tags to stream. + */ +std::ostream& operator<<(std::ostream& os, const TypeTags tag); +str::stream& operator<<(str::stream& str, const TypeTags tag); +std::ostream& operator<<(std::ostream& os, const std::pair<TypeTags, Value>& value); +str::stream& operator<<(str::stream& str, const std::pair<TypeTags, Value>& value); + +/** * Three ways value comparison (aka spaceship operator). */ std::pair<TypeTags, Value> compareValue(TypeTags lhsTag, diff --git a/src/mongo/db/query/plan_executor_sbe.cpp b/src/mongo/db/query/plan_executor_sbe.cpp index 9bd146d516f..c02828cc39c 100644 --- a/src/mongo/db/query/plan_executor_sbe.cpp +++ b/src/mongo/db/query/plan_executor_sbe.cpp @@ -245,9 +245,11 @@ Timestamp PlanExecutorSBE::getLatestOplogTimestamp() const { auto [tag, val] = _oplogTs->getViewOfValue(); if (tag != sbe::value::TypeTags::Nothing) { + const auto msgTag = tag; uassert(4822868, str::stream() << "Collection scan was asked to track latest operation time, " - "but found a result without a valid 'ts' field", + "but found a result without a valid 'ts' field: " + << msgTag, tag == sbe::value::TypeTags::Timestamp); return Timestamp{sbe::value::bitcastTo<uint64_t>(val)}; } @@ -261,9 +263,11 @@ BSONObj PlanExecutorSBE::getPostBatchResumeToken() const { auto [tag, val] = _resultRecordId->getViewOfValue(); if (tag != sbe::value::TypeTags::Nothing) { + const auto msgTag = tag; uassert(4822869, - "Collection scan was asked to track resume token, " - "but found a result without a valid RecordId", + str::stream() << "Collection scan was asked to track resume token, " + "but found a result without a valid RecordId: " + << msgTag, tag == sbe::value::TypeTags::NumberInt64); return BSON("$recordId" << sbe::value::bitcastTo<int64_t>(val)); } |