summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorAndrii Dobroshynskyi <andrii.dobroshynskyi@mongodb.com>2020-08-03 05:22:01 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-08-07 18:01:25 +0000
commita7a9fa2b01104780e9c0e83f26621317fa7254b6 (patch)
tree1bbd431bd83552a45bbd9f913206321b46794ad4 /src/mongo
parentd0fb0f3a888f2ce8923ab03fc5d88266af7d444e (diff)
downloadmongo-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.cpp2
-rw-r--r--src/mongo/db/exec/sbe/sbe_key_string_test.cpp2
-rw-r--r--src/mongo/db/exec/sbe/stages/check_bounds.cpp5
-rw-r--r--src/mongo/db/exec/sbe/stages/ix_scan.cpp15
-rw-r--r--src/mongo/db/exec/sbe/stages/scan.cpp3
-rw-r--r--src/mongo/db/exec/sbe/values/value.cpp157
-rw-r--r--src/mongo/db/exec/sbe/values/value.h11
-rw-r--r--src/mongo/db/query/plan_executor_sbe.cpp10
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));
}