diff options
author | Alya Berciu <alya.berciu@mongodb.com> | 2019-06-07 10:26:48 -0400 |
---|---|---|
committer | Alya Berciu <alya.berciu@mongodb.com> | 2019-07-03 12:53:07 -0400 |
commit | 990b2ef30d7b8fa4db6af6d79da80e3664df9c21 (patch) | |
tree | 6af2f09e7271d41e86f4228dd54f35aeade71171 | |
parent | 5813046272efb614ac78beb68885f1cb0ec58425 (diff) | |
download | mongo-990b2ef30d7b8fa4db6af6d79da80e3664df9c21.tar.gz |
SERVER-9763 Remove BSONObjBuilder append unsigned method
35 files changed, 279 insertions, 208 deletions
diff --git a/src/mongo/bson/bsonobjbuilder.h b/src/mongo/bson/bsonobjbuilder.h index fe8c0a5b555..083d7580998 100644 --- a/src/mongo/bson/bsonobjbuilder.h +++ b/src/mongo/bson/bsonobjbuilder.h @@ -39,6 +39,7 @@ #include <cstdint> #include <limits> #include <map> +#include <type_traits> #include "mongo/base/data_view.h" #include "mongo/base/parse_number.h" @@ -48,8 +49,8 @@ #include "mongo/bson/bsonobj.h" #include "mongo/bson/util/builder.h" #include "mongo/platform/decimal128.h" -#include "mongo/stdx/type_traits.h" #include "mongo/util/decimal_counter.h" +#include "mongo/util/if_constexpr.h" namespace mongo { @@ -268,56 +269,28 @@ public: return *this; } - /** Append a boolean element */ - BSONObjBuilder& append(StringData fieldName, bool val) { - _b.appendNum((char)Bool); - _b.appendStr(fieldName); - _b.appendNum((char)(val ? 1 : 0)); - return *this; - } - - /** Append a 32 bit integer element */ - BSONObjBuilder& append(StringData fieldName, int n) { - _b.appendNum((char)NumberInt); - _b.appendStr(fieldName); - _b.appendNum(n); - return *this; - } - - /** Append a 32 bit unsigned element - cast to a signed int. */ - BSONObjBuilder& append(StringData fieldName, unsigned n) { - return append(fieldName, (int)n); - } - - /** Append a NumberDecimal */ - BSONObjBuilder& append(StringData fieldName, Decimal128 n) { - _b.appendNum(static_cast<char>(NumberDecimal)); - _b.appendStr(fieldName); - // Make sure we write data in a Little Endian conforming manner - _b.appendNum(n); - return *this; - } - - /** Append a NumberLong */ - BSONObjBuilder& append(StringData fieldName, long long n) { - _b.appendNum((char)NumberLong); + /** Append elements that have the BSONObjAppendFormat trait */ + template <typename T, typename = std::enable_if_t<IsBSONObjAppendable<T>::value>> + BSONObjBuilder& append(StringData fieldName, const T& n) { + constexpr BSONType type = BSONObjAppendFormat<T>::value; + _b.appendNum(static_cast<char>(type)); _b.appendStr(fieldName); - _b.appendNum(n); + IF_CONSTEXPR(type == Bool) { + _b.appendNum(static_cast<char>(n)); + } + else IF_CONSTEXPR(type == NumberInt) { + _b.appendNum(static_cast<int>(n)); + } + else { + _b.appendNum(n); + } return *this; } - /** - * Append a NumberLong (if int64_t isn't the same as long long) - */ - template <typename Int64_t, - typename = stdx::enable_if_t<std::is_same<Int64_t, int64_t>::value && - !std::is_same<int64_t, long long>::value>> - BSONObjBuilder& append(StringData fieldName, Int64_t n) { - _b.appendNum((char)NumberLong); - _b.appendStr(fieldName); - _b.appendNum(n); - return *this; - } + template <typename T, + typename = std::enable_if_t<!IsBSONObjAppendable<T>::value && std::is_integral_v<T>>, + typename = void> + BSONObjBuilder& append(StringData fieldName, const T& n) = delete; /** appends a number. if n < max(int)/2 then uses int, otherwise long long */ BSONObjBuilder& appendIntOrLL(StringData fieldName, long long n) { @@ -374,14 +347,6 @@ public: return *this; } - /** Append a double element */ - BSONObjBuilder& append(StringData fieldName, double n) { - _b.appendNum((char)NumberDouble); - _b.appendStr(fieldName); - _b.appendNum(n); - return *this; - } - /** Append a BSON Object ID (OID type). @deprecated Generally, it is preferred to use the append append(name, oid) method for this. diff --git a/src/mongo/bson/bsonobjbuilder_test.cpp b/src/mongo/bson/bsonobjbuilder_test.cpp index a2522d04b58..c5854c38681 100644 --- a/src/mongo/bson/bsonobjbuilder_test.cpp +++ b/src/mongo/bson/bsonobjbuilder_test.cpp @@ -29,6 +29,8 @@ #include "mongo/platform/basic.h" +#include <type_traits> + #include "mongo/db/jsobj.h" #include "mongo/db/json.h" #include "mongo/unittest/unittest.h" @@ -73,35 +75,18 @@ TEST(BSONObjBuilderTest, AppendInt64T) { ASSERT_EQ(obj["b"].Long(), 1ll << 40); } -/** - * current conversion ranges in append(unsigned n) - * dbl/int max/min in comments refer to max/min encodable constants - * 0 <= n <= uint_max -----> int - */ +template <typename T, typename = void> +struct isUnsignedAppendable : std::false_type {}; -TEST(BSONObjBuilderTest, AppendUnsignedInt) { - struct { - unsigned int v; - BSONType t; - } data[] = {{0, mongo::NumberInt}, - {100, mongo::NumberInt}, - {maxEncodableInt, mongo::NumberInt}, - {maxEncodableInt + 1, mongo::NumberInt}, - {static_cast<unsigned int>(maxInt), mongo::NumberInt}, - {static_cast<unsigned int>(maxInt) + 1U, mongo::NumberInt}, - {(std::numeric_limits<unsigned int>::max)(), mongo::NumberInt}, - {0, mongo::Undefined}}; - for (int i = 0; data[i].t != mongo::Undefined; i++) { - unsigned int v = data[i].v; - BSONObjBuilder b; - b.append("a", v); - BSONObj o = b.obj(); - ASSERT_EQUALS(o.nFields(), 1); - BSONElement e = o.getField("a"); - unsigned int n = e.numberLong(); - ASSERT_EQUALS(n, v); - assertBSONTypeEquals(e.type(), data[i].t, v, i); - } +template <typename T> +struct isUnsignedAppendable<T, std::void_t<decltype(BSONObjAppendFormat<T>::value)>> + : std::true_type {}; + +TEST(BSONObjBuilderTest, AppendUnsignedIsForbidden) { + MONGO_STATIC_ASSERT(!isUnsignedAppendable<unsigned>::value); + MONGO_STATIC_ASSERT(!isUnsignedAppendable<unsigned long>::value); + MONGO_STATIC_ASSERT(!isUnsignedAppendable<unsigned long long>::value); + MONGO_STATIC_ASSERT(!isUnsignedAppendable<uint64_t>::value); } /** diff --git a/src/mongo/bson/bsontypes.cpp b/src/mongo/bson/bsontypes.cpp index 817dcee9ecf..8bfe513aa20 100644 --- a/src/mongo/bson/bsontypes.cpp +++ b/src/mongo/bson/bsontypes.cpp @@ -27,12 +27,16 @@ * it in the license file. */ +#include <fmt/format.h> + #include "mongo/bson/bsontypes.h" #include "mongo/config.h" #include "mongo/db/jsobj.h" +#include "mongo/util/string_map.h" namespace mongo { +using namespace fmt::literals; const char kMaxKeyData[] = {7, 0, 0, 0, static_cast<char>(MaxKey), 0, 0}; const BSONObj kMaxBSONKey(kMaxKeyData); @@ -93,35 +97,41 @@ const char* typeName(BSONType type) { } } -const StringMap<BSONType> kTypeAliasMap = { - {typeName(BSONType::NumberDouble), BSONType::NumberDouble}, - {typeName(BSONType::String), BSONType::String}, - {typeName(BSONType::Object), BSONType::Object}, - {typeName(BSONType::Array), BSONType::Array}, - {typeName(BSONType::BinData), BSONType::BinData}, - {typeName(BSONType::Undefined), BSONType::Undefined}, - {typeName(BSONType::jstOID), BSONType::jstOID}, - {typeName(BSONType::Bool), BSONType::Bool}, - {typeName(BSONType::Date), BSONType::Date}, - {typeName(BSONType::jstNULL), BSONType::jstNULL}, - {typeName(BSONType::RegEx), BSONType::RegEx}, - {typeName(BSONType::DBRef), BSONType::DBRef}, - {typeName(BSONType::Code), BSONType::Code}, - {typeName(BSONType::Symbol), BSONType::Symbol}, - {typeName(BSONType::CodeWScope), BSONType::CodeWScope}, - {typeName(BSONType::NumberInt), BSONType::NumberInt}, - {typeName(BSONType::bsonTimestamp), BSONType::bsonTimestamp}, - {typeName(BSONType::NumberLong), BSONType::NumberLong}, - {typeName(BSONType::NumberDecimal), BSONType::NumberDecimal}, - {typeName(BSONType::MaxKey), BSONType::MaxKey}, - {typeName(BSONType::MinKey), BSONType::MinKey}}; +boost::optional<BSONType> findBSONTypeAlias(StringData key) { + // intentionally leaked + static const auto& typeAliasMap = + *new StringMap<BSONType>{{typeName(BSONType::NumberDouble), BSONType::NumberDouble}, + {typeName(BSONType::String), BSONType::String}, + {typeName(BSONType::Object), BSONType::Object}, + {typeName(BSONType::Array), BSONType::Array}, + {typeName(BSONType::BinData), BSONType::BinData}, + {typeName(BSONType::Undefined), BSONType::Undefined}, + {typeName(BSONType::jstOID), BSONType::jstOID}, + {typeName(BSONType::Bool), BSONType::Bool}, + {typeName(BSONType::Date), BSONType::Date}, + {typeName(BSONType::jstNULL), BSONType::jstNULL}, + {typeName(BSONType::RegEx), BSONType::RegEx}, + {typeName(BSONType::DBRef), BSONType::DBRef}, + {typeName(BSONType::Code), BSONType::Code}, + {typeName(BSONType::Symbol), BSONType::Symbol}, + {typeName(BSONType::CodeWScope), BSONType::CodeWScope}, + {typeName(BSONType::NumberInt), BSONType::NumberInt}, + {typeName(BSONType::bsonTimestamp), BSONType::bsonTimestamp}, + {typeName(BSONType::NumberLong), BSONType::NumberLong}, + {typeName(BSONType::NumberDecimal), BSONType::NumberDecimal}, + {typeName(BSONType::MaxKey), BSONType::MaxKey}, + {typeName(BSONType::MinKey), BSONType::MinKey}}; + + auto it = typeAliasMap.find(key); + if (it == typeAliasMap.end()) + return boost::none; + return it->second; +} BSONType typeFromName(StringData name) { - auto typeIt = kTypeAliasMap.find(name); - uassert(ErrorCodes::BadValue, - str::stream() << "Unknown type name: " << name, - typeIt != kTypeAliasMap.end()); - return typeIt->second; + auto typeAlias = findBSONTypeAlias(name); + uassert(ErrorCodes::BadValue, "Unknown type name: {}"_format(name), typeAlias); + return *typeAlias; } std::ostream& operator<<(std::ostream& stream, BSONType type) { diff --git a/src/mongo/bson/bsontypes.h b/src/mongo/bson/bsontypes.h index b77a536742b..43cf66369dd 100644 --- a/src/mongo/bson/bsontypes.h +++ b/src/mongo/bson/bsontypes.h @@ -29,12 +29,16 @@ #pragma once +#include <boost/optional.hpp> +#include <cstdint> #include <iosfwd> +#include <type_traits> +#include "mongo/base/counter.h" +#include "mongo/base/string_data.h" #include "mongo/config.h" #include "mongo/platform/decimal128.h" #include "mongo/util/assert_util.h" -#include "mongo/util/string_map.h" namespace mongo { @@ -113,7 +117,7 @@ enum BSONType { * Maps from the set of type aliases accepted by the $type query operator to the corresponding BSON * types. Excludes "number", since this alias maps to a set of BSON types. */ -extern const StringMap<BSONType> kTypeAliasMap; +boost::optional<BSONType> findBSONTypeAlias(StringData key); /** * returns the name of the argument's type @@ -223,4 +227,80 @@ inline int canonicalizeBSONType(BSONType type) { return -1; } } -} + +template <BSONType value> +struct FormatKind : std::integral_constant<BSONType, value> {}; + +template <typename T> +struct BSONObjAppendFormat; + +namespace bsontype_detail { + +/* BSONObjFallbackFormat is the trait that BSONObjAppendFormat falls back to in case there is + no explicit specialization for a type. It has a second templated parameter so it can be enabled + for groups of types, e.g. enums. */ +template <typename T, typename = void> +struct BSONObjFallbackFormat {}; + +template <typename T> +struct BSONObjFallbackFormat<T, std::enable_if_t<std::is_enum_v<T>>> : FormatKind<NumberInt> {}; + +/** This is a special case because long long and int64_t are the same on some platforms but + * different on others. If they are the same, the long long partial specialization of + * BSONObjAppendFormat is accepted, otherwise the int64_t partial specialization of + * BSONObjFallbackFormat is chosen. */ +template <> +struct BSONObjFallbackFormat<std::int64_t> : FormatKind<NumberLong> {}; + +/** Determine if T is appendable based on whether or not BSONOBjAppendFormat<T> has a value. */ +template <typename T, typename = void> +struct IsBSONObjAppendable : std::false_type {}; + +template <typename T> +struct IsBSONObjAppendable<T, std::void_t<decltype(BSONObjAppendFormat<T>::value)>> + : std::true_type {}; + +} // namespace bsontype_detail + +template <typename T> +using IsBSONObjAppendable = bsontype_detail::IsBSONObjAppendable<T>; + +template <typename T> +struct BSONObjAppendFormat : bsontype_detail::BSONObjFallbackFormat<T> {}; + +template <> +struct BSONObjAppendFormat<bool> : FormatKind<Bool> {}; + +template <> +struct BSONObjAppendFormat<char> : FormatKind<NumberInt> {}; + +template <> +struct BSONObjAppendFormat<unsigned char> : FormatKind<NumberInt> {}; + +template <> +struct BSONObjAppendFormat<short> : FormatKind<NumberInt> {}; + +template <> +struct BSONObjAppendFormat<unsigned short> : FormatKind<NumberInt> {}; + +template <> +struct BSONObjAppendFormat<int> : FormatKind<NumberInt> {}; + +/* For platforms where long long and int64_t are the same, this partial specialization will be + used for both. Otherwise, int64_t will use the specialization above. */ +template <> +struct BSONObjAppendFormat<long long> : FormatKind<NumberLong> {}; + +template <> +struct BSONObjAppendFormat<Counter64> : FormatKind<NumberLong> {}; + +template <> +struct BSONObjAppendFormat<Decimal128> : FormatKind<NumberDecimal> {}; + +template <> +struct BSONObjAppendFormat<double> : FormatKind<NumberDouble> {}; + +template <> +struct BSONObjAppendFormat<float> : FormatKind<NumberDouble> {}; + +} // namespace mongo diff --git a/src/mongo/client/remote_command_targeter_mock.h b/src/mongo/client/remote_command_targeter_mock.h index 3ea39b80d22..5bb0a486987 100644 --- a/src/mongo/client/remote_command_targeter_mock.h +++ b/src/mongo/client/remote_command_targeter_mock.h @@ -29,6 +29,8 @@ #pragma once +#include <set> + #include "mongo/client/connection_string.h" #include "mongo/client/remote_command_targeter.h" #include "mongo/util/net/hostandport.h" diff --git a/src/mongo/db/commands/generic_servers.cpp b/src/mongo/db/commands/generic_servers.cpp index 39f1b7cd225..6106c465537 100644 --- a/src/mongo/db/commands/generic_servers.cpp +++ b/src/mongo/db/commands/generic_servers.cpp @@ -81,10 +81,10 @@ public: bb.done(); } if (cmdObj["oidReset"].trueValue()) { - result.append("oidMachineOld", OID::getMachineId()); + result.append("oidMachineOld", static_cast<int>(OID::getMachineId())); OID::regenMachineId(); } - result.append("oidMachine", OID::getMachineId()); + result.append("oidMachine", static_cast<int>(OID::getMachineId())); return true; } @@ -121,10 +121,10 @@ public: bSys.appendDate("currentTime", jsTime()); bSys.append("hostname", prettyHostName()); - bSys.append("cpuAddrSize", p.getAddrSize()); - bSys.append("memSizeMB", static_cast<unsigned>(p.getSystemMemSizeMB())); - bSys.append("memLimitMB", static_cast<unsigned>(p.getMemSizeMB())); - bSys.append("numCores", p.getNumCores()); + bSys.append("cpuAddrSize", static_cast<int>(p.getAddrSize())); + bSys.append("memSizeMB", static_cast<long long>(p.getSystemMemSizeMB())); + bSys.append("memLimitMB", static_cast<long long>(p.getMemSizeMB())); + bSys.append("numCores", static_cast<int>(p.getNumCores())); bSys.append("cpuArch", p.getArch()); bSys.append("numaEnabled", p.hasNumaEnabled()); bOs.append("type", p.getOsType()); diff --git a/src/mongo/db/commands/lock_info.cpp b/src/mongo/db/commands/lock_info.cpp index d3250df05b1..da2538006dd 100644 --- a/src/mongo/db/commands/lock_info.cpp +++ b/src/mongo/db/commands/lock_info.cpp @@ -95,7 +95,7 @@ public: // The client information client->reportState(infoBuilder); - infoBuilder.append("opid", clientOpCtx->getOpID()); + infoBuilder.append("opid", static_cast<int>(clientOpCtx->getOpID())); LockerId lockerId = clientOpCtx->lockState()->getId(); lockToClientMap.insert({lockerId, infoBuilder.obj()}); } diff --git a/src/mongo/db/curop.cpp b/src/mongo/db/curop.cpp index aef663364b0..c55c2c75efb 100644 --- a/src/mongo/db/curop.cpp +++ b/src/mongo/db/curop.cpp @@ -282,7 +282,7 @@ void CurOp::reportCurrentOpForClient(OperationContext* opCtx, } if (clientOpCtx) { - infoBuilder->append("opid", clientOpCtx->getOpID()); + infoBuilder->append("opid", static_cast<int>(clientOpCtx->getOpID())); if (clientOpCtx->isKillPending()) { infoBuilder->append("killPending", true); } diff --git a/src/mongo/db/ftdc/controller_test.cpp b/src/mongo/db/ftdc/controller_test.cpp index d4f87f38c79..a2a4c9b8abc 100644 --- a/src/mongo/db/ftdc/controller_test.cpp +++ b/src/mongo/db/ftdc/controller_test.cpp @@ -142,7 +142,7 @@ class FTDCMetricsCollectorMock2 : public FTDCMetricsCollectorMockTee { public: void generateDocument(BSONObjBuilder& builder, std::uint32_t counter) final { builder.append("name", "joe"); - builder.append("key1", (counter * 37)); + builder.append("key1", static_cast<int32_t>(counter * 37)); builder.append("key2", static_cast<double>(counter * static_cast<int>(log10f(counter)))); } }; diff --git a/src/mongo/db/ftdc/ftdc_system_stats_linux.cpp b/src/mongo/db/ftdc/ftdc_system_stats_linux.cpp index e9334987795..0338f5b7f17 100644 --- a/src/mongo/db/ftdc/ftdc_system_stats_linux.cpp +++ b/src/mongo/db/ftdc/ftdc_system_stats_linux.cpp @@ -88,7 +88,7 @@ public: // Include the number of cpus to simplify client calculations ProcessInfo p; - subObjBuilder.append("num_cpus", p.getNumCores()); + subObjBuilder.append("num_cpus", static_cast<int>(p.getNumCores())); processStatusErrors( procparser::parseProcStatFile("/proc/stat"_sd, kCpuKeys, &subObjBuilder), diff --git a/src/mongo/db/index_builds_coordinator.h b/src/mongo/db/index_builds_coordinator.h index 39e6b690cda..da93f4a8092 100644 --- a/src/mongo/db/index_builds_coordinator.h +++ b/src/mongo/db/index_builds_coordinator.h @@ -49,6 +49,7 @@ #include "mongo/util/fail_point_service.h" #include "mongo/util/future.h" #include "mongo/util/net/hostandport.h" +#include "mongo/util/string_map.h" #include "mongo/util/uuid.h" namespace mongo { diff --git a/src/mongo/db/index_names.cpp b/src/mongo/db/index_names.cpp index e0602ceb433..bde87203d36 100644 --- a/src/mongo/db/index_names.cpp +++ b/src/mongo/db/index_names.cpp @@ -30,6 +30,7 @@ #include "mongo/db/index_names.h" #include "mongo/db/jsobj.h" +#include "mongo/util/string_map.h" namespace mongo { diff --git a/src/mongo/db/matcher/expression_leaf.cpp b/src/mongo/db/matcher/expression_leaf.cpp index 3001eb59ba8..ffb18cfc71b 100644 --- a/src/mongo/db/matcher/expression_leaf.cpp +++ b/src/mongo/db/matcher/expression_leaf.cpp @@ -785,7 +785,7 @@ BSONObj BitTestMatchExpression::getSerializedRightHandSide() const { BSONArrayBuilder arrBob; for (auto bitPosition : _bitPositions) { - arrBob.append(bitPosition); + arrBob.append(static_cast<int32_t>(bitPosition)); } arrBob.doneFast(); diff --git a/src/mongo/db/matcher/expression_parser.cpp b/src/mongo/db/matcher/expression_parser.cpp index c92ae07f18a..811c0f323ed 100644 --- a/src/mongo/db/matcher/expression_parser.cpp +++ b/src/mongo/db/matcher/expression_parser.cpp @@ -38,6 +38,7 @@ #include "mongo/bson/bsonmisc.h" #include "mongo/bson/bsonobj.h" #include "mongo/bson/bsonobjbuilder.h" +#include "mongo/bson/bsontypes.h" #include "mongo/db/matcher/expression_always_boolean.h" #include "mongo/db/matcher/expression_array.h" #include "mongo/db/matcher/expression_expr.h" @@ -528,7 +529,7 @@ Status parseInExpression(InMatchExpression* inExpression, template <class T> StatusWithMatchExpression parseType(StringData name, BSONElement elt) { - auto typeSet = MatcherTypeSet::parse(elt, kTypeAliasMap); + auto typeSet = MatcherTypeSet::parse(elt); if (!typeSet.isOK()) { return typeSet.getStatus(); } diff --git a/src/mongo/db/matcher/matcher_type_set.cpp b/src/mongo/db/matcher/matcher_type_set.cpp index ae29cb53080..17681045243 100644 --- a/src/mongo/db/matcher/matcher_type_set.cpp +++ b/src/mongo/db/matcher/matcher_type_set.cpp @@ -44,7 +44,7 @@ namespace { * Returns a non-OK status if 'typeAlias' does not represent a valid type. */ Status addAliasToTypeSet(StringData typeAlias, - const StringMap<BSONType>& aliasMap, + const findBSONTypeAliasFun& aliasMapFind, MatcherTypeSet* typeSet) { invariant(typeSet); @@ -53,8 +53,8 @@ Status addAliasToTypeSet(StringData typeAlias, return Status::OK(); } - auto it = aliasMap.find(typeAlias.toString()); - if (it == aliasMap.end()) { + auto optValue = aliasMapFind(typeAlias.toString()); + if (!optValue) { // The string "missing" can be returned from the $type agg expression, but is not valid for // use in the $type match expression predicate. Return a special error message for this // case. @@ -68,25 +68,25 @@ Status addAliasToTypeSet(StringData typeAlias, str::stream() << "Unknown type name alias: " << typeAlias); } - typeSet->bsonTypes.insert(it->second); + typeSet->bsonTypes.insert(*optValue); return Status::OK(); } /** * Parses an element containing either a numerical type code or a string type alias and adds the - * resulting type to 'typeSet'. The 'aliasMap' is used to map strings to BSON types. + * resulting type to 'typeSet'. The 'aliasMapFind' function is used to map strings to BSON types. * * Returns a non-OK status if 'elt' does not represent a valid type. */ Status parseSingleType(BSONElement elt, - const StringMap<BSONType>& aliasMap, + const findBSONTypeAliasFun& aliasMapFind, MatcherTypeSet* typeSet) { if (!elt.isNumber() && elt.type() != BSONType::String) { return Status(ErrorCodes::TypeMismatch, "type must be represented as a number or a string"); } if (elt.type() == BSONType::String) { - return addAliasToTypeSet(elt.valueStringData(), aliasMap, typeSet); + return addAliasToTypeSet(elt.valueStringData(), aliasMapFind, typeSet); } auto valueAsInt = elt.parseIntegerElementToInt(); @@ -122,11 +122,19 @@ const StringMap<BSONType> MatcherTypeSet::kJsonSchemaTypeAliasMap = { {std::string(JSONSchemaParser::kSchemaTypeString), BSONType::String}, }; -StatusWith<MatcherTypeSet> MatcherTypeSet::fromStringAliases(std::set<StringData> typeAliases, - const StringMap<BSONType>& aliasMap) { +boost::optional<BSONType> MatcherTypeSet::findJsonSchemaTypeAlias(StringData key) { + const auto& aliasMap = kJsonSchemaTypeAliasMap; + auto it = aliasMap.find(key); + if (it == aliasMap.end()) + return boost::none; + return it->second; +} + +StatusWith<MatcherTypeSet> MatcherTypeSet::fromStringAliases( + std::set<StringData> typeAliases, const findBSONTypeAliasFun& aliasMapFind) { MatcherTypeSet typeSet; for (auto&& alias : typeAliases) { - auto status = addAliasToTypeSet(alias, aliasMap, &typeSet); + auto status = addAliasToTypeSet(alias, aliasMapFind, &typeSet); if (!status.isOK()) { return status; } @@ -134,12 +142,11 @@ StatusWith<MatcherTypeSet> MatcherTypeSet::fromStringAliases(std::set<StringData return typeSet; } -StatusWith<MatcherTypeSet> MatcherTypeSet::parse(BSONElement elt, - const StringMap<BSONType>& aliasMap) { +StatusWith<MatcherTypeSet> MatcherTypeSet::parse(BSONElement elt) { MatcherTypeSet typeSet; if (elt.type() != BSONType::Array) { - auto status = parseSingleType(elt, aliasMap, &typeSet); + auto status = parseSingleType(elt, findBSONTypeAlias, &typeSet); if (!status.isOK()) { return status; } @@ -147,7 +154,7 @@ StatusWith<MatcherTypeSet> MatcherTypeSet::parse(BSONElement elt, } for (auto&& typeArrayElt : elt.embeddedObject()) { - auto status = parseSingleType(typeArrayElt, aliasMap, &typeSet); + auto status = parseSingleType(typeArrayElt, findBSONTypeAlias, &typeSet); if (!status.isOK()) { return status; } @@ -168,7 +175,7 @@ void MatcherTypeSet::toBSONArray(BSONArrayBuilder* builder) const { BSONTypeSet BSONTypeSet::parseFromBSON(const BSONElement& element) { // BSON type can be specified with a type alias, other values will be rejected. - auto typeSet = uassertStatusOK(JSONSchemaParser::parseTypeSet(element, kTypeAliasMap)); + auto typeSet = uassertStatusOK(JSONSchemaParser::parseTypeSet(element, findBSONTypeAlias)); return BSONTypeSet(typeSet); } diff --git a/src/mongo/db/matcher/matcher_type_set.h b/src/mongo/db/matcher/matcher_type_set.h index a5b02efc477..a217b96129b 100644 --- a/src/mongo/db/matcher/matcher_type_set.h +++ b/src/mongo/db/matcher/matcher_type_set.h @@ -29,6 +29,7 @@ #pragma once +#include <functional> #include <set> #include <string> @@ -37,9 +38,12 @@ #include "mongo/bson/bsonobjbuilder.h" #include "mongo/bson/bsontypes.h" #include "mongo/stdx/unordered_map.h" +#include "mongo/util/string_map.h" namespace mongo { +using findBSONTypeAliasFun = std::function<boost::optional<BSONType>(StringData)>; + /** * Represents a set of types or of type aliases in the match language. The set consists of the BSON * types as well as "number", which is an alias for all numeric BSON types (NumberInt, NumberLong, @@ -53,6 +57,8 @@ struct MatcherTypeSet { // supported. static const StringMap<BSONType> kJsonSchemaTypeAliasMap; + static boost::optional<BSONType> findJsonSchemaTypeAlias(StringData key); + /** * Given a mapping from string alias to BSON type, creates a MatcherTypeSet from a * BSONElement. This BSON alias may either represent a single type (via numerical type code or @@ -60,7 +66,7 @@ struct MatcherTypeSet { * * Returns an error if the element cannot be parsed to a set of types. */ - static StatusWith<MatcherTypeSet> parse(BSONElement, const StringMap<BSONType>& aliasMap); + static StatusWith<MatcherTypeSet> parse(BSONElement); /** * Given a set of string type alias and a mapping from string alias to BSON type, returns the @@ -69,7 +75,7 @@ struct MatcherTypeSet { * Returns an error if any of the string aliases are unknown. */ static StatusWith<MatcherTypeSet> fromStringAliases(std::set<StringData> typeAliases, - const StringMap<BSONType>& aliasMap); + const findBSONTypeAliasFun& aliasMapFind); /** * Constructs an empty type set. diff --git a/src/mongo/db/matcher/matcher_type_set_test.cpp b/src/mongo/db/matcher/matcher_type_set_test.cpp index af949c297c5..c8f06fdab70 100644 --- a/src/mongo/db/matcher/matcher_type_set_test.cpp +++ b/src/mongo/db/matcher/matcher_type_set_test.cpp @@ -40,14 +40,14 @@ namespace mongo { namespace { TEST(MatcherTypeSetTest, ParseFromStringAliasesCanParseNumberAlias) { - auto result = MatcherTypeSet::fromStringAliases({"number"}, kTypeAliasMap); + auto result = MatcherTypeSet::fromStringAliases({"number"}, findBSONTypeAlias); ASSERT_OK(result.getStatus()); ASSERT_TRUE(result.getValue().allNumbers); ASSERT_EQ(result.getValue().bsonTypes.size(), 0u); } TEST(MatcherTypeSetTest, ParseFromStringAliasesCanParseLongAlias) { - auto result = MatcherTypeSet::fromStringAliases({"long"}, kTypeAliasMap); + auto result = MatcherTypeSet::fromStringAliases({"long"}, findBSONTypeAlias); ASSERT_OK(result.getStatus()); ASSERT_FALSE(result.getValue().allNumbers); ASSERT_EQ(result.getValue().bsonTypes.size(), 1u); @@ -55,7 +55,8 @@ TEST(MatcherTypeSetTest, ParseFromStringAliasesCanParseLongAlias) { } TEST(MatcherTypeSetTest, ParseFromStringAliasesCanParseMultipleTypes) { - auto result = MatcherTypeSet::fromStringAliases({"number", "object", "string"}, kTypeAliasMap); + auto result = + MatcherTypeSet::fromStringAliases({"number", "object", "string"}, findBSONTypeAlias); ASSERT_OK(result.getStatus()); ASSERT_TRUE(result.getValue().allNumbers); ASSERT_EQ(result.getValue().bsonTypes.size(), 2u); @@ -64,20 +65,20 @@ TEST(MatcherTypeSetTest, ParseFromStringAliasesCanParseMultipleTypes) { } TEST(MatcherTypeSetTest, ParseFromStringAliasesCanParseEmptySet) { - auto result = MatcherTypeSet::fromStringAliases({}, kTypeAliasMap); + auto result = MatcherTypeSet::fromStringAliases({}, findBSONTypeAlias); ASSERT_OK(result.getStatus()); ASSERT_TRUE(result.getValue().isEmpty()); } TEST(MatcherTypeSetTest, ParseFromStringFailsToParseUnknownAlias) { - auto result = MatcherTypeSet::fromStringAliases({"long", "unknown"}, kTypeAliasMap); + auto result = MatcherTypeSet::fromStringAliases({"long", "unknown"}, findBSONTypeAlias); ASSERT_NOT_OK(result.getStatus()); } TEST(MatcherTypeSetTest, ParseFromElementCanParseNumberAlias) { auto obj = BSON("" << "number"); - auto result = MatcherTypeSet::parse(obj.firstElement(), kTypeAliasMap); + auto result = MatcherTypeSet::parse(obj.firstElement()); ASSERT_OK(result.getStatus()); ASSERT_TRUE(result.getValue().allNumbers); ASSERT_TRUE(result.getValue().bsonTypes.empty()); @@ -86,7 +87,7 @@ TEST(MatcherTypeSetTest, ParseFromElementCanParseNumberAlias) { TEST(MatcherTypeSetTest, ParseFromElementCanParseLongAlias) { auto obj = BSON("" << "long"); - auto result = MatcherTypeSet::parse(obj.firstElement(), kTypeAliasMap); + auto result = MatcherTypeSet::parse(obj.firstElement()); ASSERT_OK(result.getStatus()); ASSERT_FALSE(result.getValue().allNumbers); ASSERT_EQ(result.getValue().bsonTypes.size(), 1u); @@ -96,30 +97,30 @@ TEST(MatcherTypeSetTest, ParseFromElementCanParseLongAlias) { TEST(MatcherTypeSetTest, ParseFromElementFailsToParseUnknownAlias) { auto obj = BSON("" << "unknown"); - auto result = MatcherTypeSet::parse(obj.firstElement(), kTypeAliasMap); + auto result = MatcherTypeSet::parse(obj.firstElement()); ASSERT_NOT_OK(result.getStatus()); } TEST(MatcherTypeSetTest, ParseFromElementFailsToParseWrongElementType) { auto obj = BSON("" << BSON("" << "")); - auto result = MatcherTypeSet::parse(obj.firstElement(), kTypeAliasMap); + auto result = MatcherTypeSet::parse(obj.firstElement()); ASSERT_NOT_OK(result.getStatus()); obj = fromjson("{'': null}"); - result = MatcherTypeSet::parse(obj.firstElement(), kTypeAliasMap); + result = MatcherTypeSet::parse(obj.firstElement()); ASSERT_NOT_OK(result.getStatus()); } TEST(MatcherTypeSetTest, ParseFromElementFailsToParseUnknownBSONType) { auto obj = BSON("" << 99); - auto result = MatcherTypeSet::parse(obj.firstElement(), kTypeAliasMap); + auto result = MatcherTypeSet::parse(obj.firstElement()); ASSERT_NOT_OK(result.getStatus()); } TEST(MatcherTypeSetTest, ParseFromElementFailsToParseEOOTypeCode) { auto obj = BSON("" << 0); - auto result = MatcherTypeSet::parse(obj.firstElement(), kTypeAliasMap); + auto result = MatcherTypeSet::parse(obj.firstElement()); ASSERT_NOT_OK(result.getStatus()); ASSERT_EQ(result.getStatus().code(), ErrorCodes::BadValue); ASSERT_EQ(result.getStatus().reason(), @@ -129,7 +130,7 @@ TEST(MatcherTypeSetTest, ParseFromElementFailsToParseEOOTypeCode) { TEST(MatcherTypeSetTest, ParseFromElementFailsToParseEOOTypeName) { auto obj = BSON("" << "missing"); - auto result = MatcherTypeSet::parse(obj.firstElement(), kTypeAliasMap); + auto result = MatcherTypeSet::parse(obj.firstElement()); ASSERT_NOT_OK(result.getStatus()); ASSERT_EQ(result.getStatus().code(), ErrorCodes::BadValue); ASSERT_EQ(result.getStatus().reason(), @@ -139,7 +140,7 @@ TEST(MatcherTypeSetTest, ParseFromElementFailsToParseEOOTypeName) { TEST(MatcherTypeSetTest, ParseFromElementCanParseRoundDoubleTypeCode) { auto obj = BSON("" << 2.0); - auto result = MatcherTypeSet::parse(obj.firstElement(), kTypeAliasMap); + auto result = MatcherTypeSet::parse(obj.firstElement()); ASSERT_OK(result.getStatus()); ASSERT_FALSE(result.getValue().allNumbers); ASSERT_EQ(result.getValue().bsonTypes.size(), 1u); @@ -148,13 +149,13 @@ TEST(MatcherTypeSetTest, ParseFromElementCanParseRoundDoubleTypeCode) { TEST(MatcherTypeSetTest, ParseFailsWhenElementIsNonRoundDoubleTypeCode) { auto obj = BSON("" << 2.5); - auto result = MatcherTypeSet::parse(obj.firstElement(), kTypeAliasMap); + auto result = MatcherTypeSet::parse(obj.firstElement()); ASSERT_NOT_OK(result.getStatus()); } TEST(MatcherTypeSetTest, ParseFromElementCanParseRoundDecimalTypeCode) { auto obj = BSON("" << Decimal128(2)); - auto result = MatcherTypeSet::parse(obj.firstElement(), kTypeAliasMap); + auto result = MatcherTypeSet::parse(obj.firstElement()); ASSERT_OK(result.getStatus()); ASSERT_FALSE(result.getValue().allNumbers); ASSERT_EQ(result.getValue().bsonTypes.size(), 1U); @@ -163,83 +164,83 @@ TEST(MatcherTypeSetTest, ParseFromElementCanParseRoundDecimalTypeCode) { TEST(MatcherTypeSetTest, ParseFailsWhenElementIsNonRoundDecimalTypeCode) { auto obj = BSON("" << Decimal128(2.5)); - auto result = MatcherTypeSet::parse(obj.firstElement(), kTypeAliasMap); + auto result = MatcherTypeSet::parse(obj.firstElement()); ASSERT_NOT_OK(result.getStatus()); } TEST(MatcherTypeSetTest, ParseFailsWhenDoubleElementIsTooPositiveForInteger) { double doubleTooLarge = scalbn(1, std::numeric_limits<long long>::digits); auto obj = BSON("" << doubleTooLarge); - auto result = MatcherTypeSet::parse(obj.firstElement(), kTypeAliasMap); + auto result = MatcherTypeSet::parse(obj.firstElement()); ASSERT_NOT_OK(result.getStatus()); } TEST(MatcherTypeSetTest, ParseFailsWhenDoubleElementIsTooNegativeForInteger) { double doubleTooNegative = std::numeric_limits<double>::lowest(); auto obj = BSON("" << doubleTooNegative); - auto result = MatcherTypeSet::parse(obj.firstElement(), kTypeAliasMap); + auto result = MatcherTypeSet::parse(obj.firstElement()); ASSERT_NOT_OK(result.getStatus()); } TEST(MatcherTypeSetTest, ParseFailsWhenDoubleElementIsNaN) { auto obj = BSON("" << std::nan("")); - auto result = MatcherTypeSet::parse(obj.firstElement(), kTypeAliasMap); + auto result = MatcherTypeSet::parse(obj.firstElement()); ASSERT_NOT_OK(result.getStatus()); } TEST(MatcherTypeSetTest, ParseFailsWhenDoubleElementIsInfinite) { auto obj = BSON("" << std::numeric_limits<double>::infinity()); - auto result = MatcherTypeSet::parse(obj.firstElement(), kTypeAliasMap); + auto result = MatcherTypeSet::parse(obj.firstElement()); ASSERT_NOT_OK(result.getStatus()); } TEST(MatcherTypeSetTest, ParseFailsWhenDecimalElementIsTooPositiveForInteger) { auto obj = BSON("" << Decimal128(static_cast<int64_t>(std::numeric_limits<int>::max()) + 1)); - auto result = MatcherTypeSet::parse(obj.firstElement(), kTypeAliasMap); + auto result = MatcherTypeSet::parse(obj.firstElement()); ASSERT_NOT_OK(result.getStatus()); } TEST(MatcherTypeSetTest, ParseFailsWhenDecimalElementIsTooNegativeForInteger) { auto obj = BSON("" << Decimal128(static_cast<int64_t>(std::numeric_limits<int>::min()) - 1)); - auto result = MatcherTypeSet::parse(obj.firstElement(), kTypeAliasMap); + auto result = MatcherTypeSet::parse(obj.firstElement()); ASSERT_NOT_OK(result.getStatus()); } TEST(MatcherTypeSetTest, ParseFailsWhenDecimalElementIsNaN) { auto obj = BSON("" << Decimal128::kPositiveNaN); - auto result = MatcherTypeSet::parse(obj.firstElement(), kTypeAliasMap); + auto result = MatcherTypeSet::parse(obj.firstElement()); ASSERT_NOT_OK(result.getStatus()); } TEST(MatcherTypeSetTest, ParseFailsWhenDecimalElementIsInfinite) { auto obj = BSON("" << Decimal128::kPositiveInfinity); - auto result = MatcherTypeSet::parse(obj.firstElement(), kTypeAliasMap); + auto result = MatcherTypeSet::parse(obj.firstElement()); ASSERT_NOT_OK(result.getStatus()); } TEST(MatcherTypeSetTest, ParseFromElementFailsWhenArrayHasUnknownType) { auto obj = BSON("" << BSON_ARRAY("long" << "unknown")); - auto result = MatcherTypeSet::parse(obj.firstElement(), kTypeAliasMap); + auto result = MatcherTypeSet::parse(obj.firstElement()); ASSERT_NOT_OK(result.getStatus()); } TEST(MatcherTypeSetTest, ParseFailsWhenArrayElementIsNotStringOrNumber) { auto obj = BSON("" << BSON_ARRAY("long" << BSONObj())); - auto result = MatcherTypeSet::parse(obj.firstElement(), kTypeAliasMap); + auto result = MatcherTypeSet::parse(obj.firstElement()); ASSERT_NOT_OK(result.getStatus()); } TEST(MatcherTypeSetTest, ParseFromElementCanParseEmptyArray) { auto obj = BSON("" << BSONArray()); - auto result = MatcherTypeSet::parse(obj.firstElement(), kTypeAliasMap); + auto result = MatcherTypeSet::parse(obj.firstElement()); ASSERT_OK(result.getStatus()); ASSERT_TRUE(result.getValue().isEmpty()); } TEST(MatcherTypeSetTest, ParseFromElementCanParseArrayWithSingleType) { auto obj = BSON("" << BSON_ARRAY("string")); - auto result = MatcherTypeSet::parse(obj.firstElement(), kTypeAliasMap); + auto result = MatcherTypeSet::parse(obj.firstElement()); ASSERT_OK(result.getStatus()); ASSERT_FALSE(result.getValue().allNumbers); ASSERT_EQ(result.getValue().bsonTypes.size(), 1u); @@ -248,7 +249,7 @@ TEST(MatcherTypeSetTest, ParseFromElementCanParseArrayWithSingleType) { TEST(MatcherTypeSetTest, ParseFromElementCanParseArrayWithMultipleTypes) { auto obj = BSON("" << BSON_ARRAY("string" << 3 << "number")); - auto result = MatcherTypeSet::parse(obj.firstElement(), kTypeAliasMap); + auto result = MatcherTypeSet::parse(obj.firstElement()); ASSERT_OK(result.getStatus()); ASSERT_TRUE(result.getValue().allNumbers); ASSERT_EQ(result.getValue().bsonTypes.size(), 2u); diff --git a/src/mongo/db/matcher/schema/json_schema_parser.cpp b/src/mongo/db/matcher/schema/json_schema_parser.cpp index cf258da98d6..dd51115e276 100644 --- a/src/mongo/db/matcher/schema/json_schema_parser.cpp +++ b/src/mongo/db/matcher/schema/json_schema_parser.cpp @@ -70,6 +70,8 @@ using Pattern = InternalSchemaAllowedPropertiesMatchExpression::Pattern; namespace { +using findBSONTypeAliasFun = std::function<boost::optional<BSONType>(StringData)>; + // Explicitly unsupported JSON Schema keywords. const std::set<StringData> unsupportedKeywords{ "$ref"_sd, "$schema"_sd, "default"_sd, "definitions"_sd, "format"_sd, "id"_sd, @@ -149,9 +151,9 @@ StatusWith<std::unique_ptr<InternalSchemaTypeExpression>> parseType( StringData path, StringData keywordName, BSONElement typeElt, - const StringMap<BSONType>& aliasMap) { + const findBSONTypeAliasFun& aliasMapFind) { - auto typeSet = JSONSchemaParser::parseTypeSet(typeElt, aliasMap); + auto typeSet = JSONSchemaParser::parseTypeSet(typeElt, aliasMapFind); if (!typeSet.isOK()) { return typeSet.getStatus(); } @@ -1496,17 +1498,17 @@ StatusWithMatchExpression _parse(const boost::intrusive_ptr<ExpressionContext>& std::unique_ptr<InternalSchemaTypeExpression> typeExpr; if (typeElem) { - auto parseTypeResult = parseType(path, - JSONSchemaParser::kSchemaTypeKeyword, - typeElem, - MatcherTypeSet::kJsonSchemaTypeAliasMap); - if (!parseTypeResult.isOK()) { - return parseTypeResult.getStatus(); - } - typeExpr = std::move(parseTypeResult.getValue()); + auto parsed = parseType(path, + JSONSchemaParser::kSchemaTypeKeyword, + typeElem, + MatcherTypeSet::findJsonSchemaTypeAlias); + if (!parsed.isOK()) { + return parsed.getStatus(); + } + typeExpr = std::move(parsed.getValue()); } else if (bsonTypeElem) { - auto parseBsonTypeResult = - parseType(path, JSONSchemaParser::kSchemaBsonTypeKeyword, bsonTypeElem, kTypeAliasMap); + auto parseBsonTypeResult = parseType( + path, JSONSchemaParser::kSchemaBsonTypeKeyword, bsonTypeElem, findBSONTypeAlias); if (!parseBsonTypeResult.isOK()) { return parseBsonTypeResult.getStatus(); } @@ -1562,8 +1564,8 @@ StatusWithMatchExpression _parse(const boost::intrusive_ptr<ExpressionContext>& } } // namespace -StatusWith<MatcherTypeSet> JSONSchemaParser::parseTypeSet(BSONElement typeElt, - const StringMap<BSONType>& aliasMap) { +StatusWith<MatcherTypeSet> JSONSchemaParser::parseTypeSet( + BSONElement typeElt, const findBSONTypeAliasFun& aliasMapFind) { if (typeElt.type() != BSONType::String && typeElt.type() != BSONType::Array) { return {Status(ErrorCodes::TypeMismatch, str::stream() << "$jsonSchema keyword '" << typeElt.fieldNameStringData() @@ -1605,7 +1607,7 @@ StatusWith<MatcherTypeSet> JSONSchemaParser::parseTypeSet(BSONElement typeElt, } } - return MatcherTypeSet::fromStringAliases(std::move(aliases), aliasMap); + return MatcherTypeSet::fromStringAliases(std::move(aliases), aliasMapFind); } StatusWithMatchExpression JSONSchemaParser::parse( diff --git a/src/mongo/db/matcher/schema/json_schema_parser.h b/src/mongo/db/matcher/schema/json_schema_parser.h index 463b15d72af..378b093ba09 100644 --- a/src/mongo/db/matcher/schema/json_schema_parser.h +++ b/src/mongo/db/matcher/schema/json_schema_parser.h @@ -92,11 +92,12 @@ public: bool ignoreUnknownKeywords = false); /** - * Builds a set of type aliases from the given type element using 'aliasMap'. Returns a non-OK - * status if 'typeElt' is invalid or does not contain an entry in the 'aliasMap'. + * Builds a set of type aliases from the given type element using 'aliasMapFind'. Returns a + * non-OK status if 'typeElt' is invalid or does not contain an entry in the 'aliasMap' by + * calling 'aliasMapFind'. */ static StatusWith<MatcherTypeSet> parseTypeSet(BSONElement typeElt, - const StringMap<BSONType>& aliasMap); + const findBSONTypeAliasFun& aliasMapFind); }; } // namespace mongo diff --git a/src/mongo/db/pipeline/document.h b/src/mongo/db/pipeline/document.h index 387a4485b2e..4f63a9fd47e 100644 --- a/src/mongo/db/pipeline/document.h +++ b/src/mongo/db/pipeline/document.h @@ -37,6 +37,7 @@ #include "mongo/base/string_data.h" #include "mongo/base/string_data_comparator_interface.h" #include "mongo/bson/util/builder.h" +#include "mongo/util/string_map.h" namespace mongo { class BSONObj; diff --git a/src/mongo/db/repl/repl_set_commands.cpp b/src/mongo/db/repl/repl_set_commands.cpp index c7b3c3ec3d2..137e583612c 100644 --- a/src/mongo/db/repl/repl_set_commands.cpp +++ b/src/mongo/db/repl/repl_set_commands.cpp @@ -330,8 +330,9 @@ public: members.append("0", BSON("_id" << 0 << "host" << me.toString())); result.append("me", me.toString()); for (unsigned i = 0; i < seeds.size(); i++) { - members.append(BSONObjBuilder::numStr(i + 1), - BSON("_id" << i + 1 << "host" << seeds[i].toString())); + members.append( + BSONObjBuilder::numStr(i + 1), + BSON("_id" << static_cast<int>(i + 1) << "host" << seeds[i].toString())); } b.appendArray("members", members.obj()); configObj = b.obj(); diff --git a/src/mongo/db/repl/replication_info.cpp b/src/mongo/db/repl/replication_info.cpp index 701b6411d6a..677ec1ee4e9 100644 --- a/src/mongo/db/repl/replication_info.cpp +++ b/src/mongo/db/repl/replication_info.cpp @@ -120,7 +120,7 @@ void appendReplicationInfo(OperationContext* opCtx, BSONObjBuilder& result, int BSONElement e = s["syncedTo"]; BSONObjBuilder t(bb.subobjStart("syncedTo")); t.appendDate("time", e.timestampTime()); - t.append("inc", e.timestampInc()); + t.append("inc", static_cast<int>(e.timestampInc())); t.done(); } diff --git a/src/mongo/db/repl/split_horizon.h b/src/mongo/db/repl/split_horizon.h index 8728a6a173e..da74f65f2ec 100644 --- a/src/mongo/db/repl/split_horizon.h +++ b/src/mongo/db/repl/split_horizon.h @@ -38,6 +38,7 @@ #include "mongo/db/client.h" #include "mongo/db/repl/repl_set_tag.h" #include "mongo/util/net/hostandport.h" +#include "mongo/util/string_map.h" namespace mongo { namespace repl { diff --git a/src/mongo/db/repl/topology_coordinator.cpp b/src/mongo/db/repl/topology_coordinator.cpp index 9abe0dbb76d..ec5c4a7c7bb 100644 --- a/src/mongo/db/repl/topology_coordinator.cpp +++ b/src/mongo/db/repl/topology_coordinator.cpp @@ -1445,7 +1445,7 @@ void TopologyCoordinator::prepareStatusResponse(const ReplSetStatusArgs& rsStatu // We're REMOVED or have an invalid config response->append("state", static_cast<int>(myState.s)); response->append("stateStr", myState.toString()); - response->append("uptime", rsStatusArgs.selfUptime); + response->append("uptime", static_cast<int>(rsStatusArgs.selfUptime)); appendOpTime(response, "optime", lastOpApplied); @@ -1477,7 +1477,7 @@ void TopologyCoordinator::prepareStatusResponse(const ReplSetStatusArgs& rsStatu bb.append("health", 1.0); bb.append("state", static_cast<int>(myState.s)); bb.append("stateStr", myState.toString()); - bb.append("uptime", rsStatusArgs.selfUptime); + bb.append("uptime", static_cast<int>(rsStatusArgs.selfUptime)); if (!_selfConfig().isArbiter()) { appendOpTime(&bb, "optime", lastOpApplied); bb.appendDate("optimeDate", @@ -1529,7 +1529,7 @@ void TopologyCoordinator::prepareStatusResponse(const ReplSetStatusArgs& rsStatu bb.append("stateStr", it->getState().toString()); } - const unsigned int uptime = static_cast<unsigned int>(( + const int uptime = static_cast<int>(( it->getUpSince() != Date_t() ? durationCount<Seconds>(now - it->getUpSince()) : 0)); bb.append("uptime", uptime); if (!itConfig.isArbiter()) { diff --git a/src/mongo/db/s/active_shard_collection_registry.h b/src/mongo/db/s/active_shard_collection_registry.h index 06f7f69d906..da734aee1c9 100644 --- a/src/mongo/db/s/active_shard_collection_registry.h +++ b/src/mongo/db/s/active_shard_collection_registry.h @@ -35,6 +35,7 @@ #include "mongo/s/request_types/shard_collection_gen.h" #include "mongo/stdx/mutex.h" #include "mongo/util/concurrency/notification.h" +#include "mongo/util/string_map.h" namespace mongo { diff --git a/src/mongo/db/s/config/initial_split_policy.h b/src/mongo/db/s/config/initial_split_policy.h index 5dea6e15c5f..beb034e5468 100644 --- a/src/mongo/db/s/config/initial_split_policy.h +++ b/src/mongo/db/s/config/initial_split_policy.h @@ -40,6 +40,7 @@ #include "mongo/s/request_types/shard_collection_gen.h" #include "mongo/s/shard_id.h" #include "mongo/s/shard_key_pattern.h" +#include "mongo/util/string_map.h" namespace mongo { diff --git a/src/mongo/db/s/config/namespace_serializer.h b/src/mongo/db/s/config/namespace_serializer.h index 7b7832ebbe7..912171dcdbc 100644 --- a/src/mongo/db/s/config/namespace_serializer.h +++ b/src/mongo/db/s/config/namespace_serializer.h @@ -38,6 +38,7 @@ #include "mongo/db/namespace_string.h" #include "mongo/stdx/condition_variable.h" #include "mongo/stdx/mutex.h" +#include "mongo/util/string_map.h" namespace mongo { diff --git a/src/mongo/db/stats/server_write_concern_metrics.h b/src/mongo/db/stats/server_write_concern_metrics.h index e6faaaf1641..524c4fce917 100644 --- a/src/mongo/db/stats/server_write_concern_metrics.h +++ b/src/mongo/db/stats/server_write_concern_metrics.h @@ -32,6 +32,7 @@ #include "mongo/db/operation_context.h" #include "mongo/db/service_context.h" #include "mongo/db/write_concern_options.h" +#include "mongo/util/string_map.h" namespace mongo { diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_util.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_util.cpp index e12f55e639d..b00bb678eef 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_util.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_util.cpp @@ -703,7 +703,7 @@ void WiredTigerUtil::appendSnapshotWindowSettings(WiredTigerKVEngine* engine, settings.append("target available snapshots window size in seconds", snapshotWindowParams.targetSnapshotHistoryWindowInSeconds.load()); settings.append("current available snapshots window size in seconds", - currentAvailableSnapshotWindow); + static_cast<int>(currentAvailableSnapshotWindow)); settings.append("latest majority snapshot timestamp available", stableTimestamp.toStringPretty()); settings.append("oldest majority snapshot timestamp available", diff --git a/src/mongo/dbtests/storage_timestamp_tests.cpp b/src/mongo/dbtests/storage_timestamp_tests.cpp index 37824936a81..76e74a1d6e0 100644 --- a/src/mongo/dbtests/storage_timestamp_tests.cpp +++ b/src/mongo/dbtests/storage_timestamp_tests.cpp @@ -697,9 +697,9 @@ public: AutoGetCollection autoColl(_opCtx, nss, LockMode::MODE_IX); - const std::uint32_t docsToInsert = 10; + const std::int32_t docsToInsert = 10; const LogicalTime firstInsertTime = _clock->reserveTicks(docsToInsert); - for (std::uint32_t idx = 0; idx < docsToInsert; ++idx) { + for (std::int32_t idx = 0; idx < docsToInsert; ++idx) { BSONObjBuilder result; ASSERT_OK(applyOps( _opCtx, @@ -727,7 +727,7 @@ public: &result)); } - for (std::uint32_t idx = 0; idx < docsToInsert; ++idx) { + for (std::int32_t idx = 0; idx < docsToInsert; ++idx) { OneOffRead oor(_opCtx, firstInsertTime.addTicks(idx).asTimestamp()); BSONObj result; @@ -750,28 +750,28 @@ public: AutoGetCollection autoColl(_opCtx, nss, LockMode::MODE_IX); - const std::uint32_t docsToInsert = 10; + const std::int32_t docsToInsert = 10; const LogicalTime firstInsertTime = _clock->reserveTicks(docsToInsert); BSONObjBuilder oplogEntryBuilder; // Populate the "ts" field with an array of all the grouped inserts' timestamps. BSONArrayBuilder tsArrayBuilder(oplogEntryBuilder.subarrayStart("ts")); - for (std::uint32_t idx = 0; idx < docsToInsert; ++idx) { + for (std::int32_t idx = 0; idx < docsToInsert; ++idx) { tsArrayBuilder.append(firstInsertTime.addTicks(idx).asTimestamp()); } tsArrayBuilder.done(); // Populate the "t" (term) field with an array of all the grouped inserts' terms. BSONArrayBuilder tArrayBuilder(oplogEntryBuilder.subarrayStart("t")); - for (std::uint32_t idx = 0; idx < docsToInsert; ++idx) { + for (std::int32_t idx = 0; idx < docsToInsert; ++idx) { tArrayBuilder.append(1LL); } tArrayBuilder.done(); // Populate the "o" field with an array of all the grouped inserts. BSONArrayBuilder oArrayBuilder(oplogEntryBuilder.subarrayStart("o")); - for (std::uint32_t idx = 0; idx < docsToInsert; ++idx) { + for (std::int32_t idx = 0; idx < docsToInsert; ++idx) { oArrayBuilder.append(BSON("_id" << idx)); } oArrayBuilder.done(); @@ -784,7 +784,7 @@ public: ASSERT_OK(repl::SyncTail::syncApply( _opCtx, oplogEntry, repl::OplogApplication::Mode::kSecondary, boost::none)); - for (std::uint32_t idx = 0; idx < docsToInsert; ++idx) { + for (std::int32_t idx = 0; idx < docsToInsert; ++idx) { OneOffRead oor(_opCtx, firstInsertTime.addTicks(idx).asTimestamp()); BSONObj result; diff --git a/src/mongo/s/query/router_stage_remove_metadata_fields.h b/src/mongo/s/query/router_stage_remove_metadata_fields.h index 4f49537b2f9..3a43a028b18 100644 --- a/src/mongo/s/query/router_stage_remove_metadata_fields.h +++ b/src/mongo/s/query/router_stage_remove_metadata_fields.h @@ -32,6 +32,7 @@ #include <vector> #include "mongo/s/query/router_exec_stage.h" +#include "mongo/util/string_map.h" namespace mongo { diff --git a/src/mongo/shell/shell_utils_extended.cpp b/src/mongo/shell/shell_utils_extended.cpp index d45f2823030..6a756911f3d 100644 --- a/src/mongo/shell/shell_utils_extended.cpp +++ b/src/mongo/shell/shell_utils_extended.cpp @@ -351,7 +351,7 @@ BSONObj changeUmask(const BSONObj& a, void* data) { "umask takes 1 argument, the octal mode of the umask", a.nFields() == 1 && isNumericBSONType(a.firstElementType())); auto val = a.firstElement().Number(); - return BSON("" << umask(static_cast<mode_t>(val))); + return BSON("" << static_cast<int>(umask(static_cast<mode_t>(val)))); #endif } diff --git a/src/mongo/util/future_impl.h b/src/mongo/util/future_impl.h index e8e8be1ad5c..e9c2690d499 100644 --- a/src/mongo/util/future_impl.h +++ b/src/mongo/util/future_impl.h @@ -31,6 +31,7 @@ #include <boost/intrusive_ptr.hpp> #include <boost/optional.hpp> +#include <forward_list> #include <type_traits> #include "mongo/base/checked_cast.h" diff --git a/src/mongo/util/net/http_client_curl.cpp b/src/mongo/util/net/http_client_curl.cpp index 1f3e6534dbe..fc5307bcb45 100644 --- a/src/mongo/util/net/http_client_curl.cpp +++ b/src/mongo/util/net/http_client_curl.cpp @@ -355,7 +355,7 @@ BSONObj HttpClient::getServerStatus() { BSONObjBuilder v(info.subobjStart("running")); v.append("version", curl_info->version); - v.append("version_num", curl_info->version_num); + v.append("version_num", static_cast<int>(curl_info->version_num)); } return info.obj(); diff --git a/src/mongo/util/stacktrace_posix.cpp b/src/mongo/util/stacktrace_posix.cpp index 996cdb52b16..116065533f8 100644 --- a/src/mongo/util/stacktrace_posix.cpp +++ b/src/mongo/util/stacktrace_posix.cpp @@ -502,7 +502,7 @@ void addOSComponentsToSoMap(BSONObjBuilder* soMap) { } else { continue; } - soInfo << "machType" << header->filetype; + soInfo << "machType" << static_cast<int32_t>(header->filetype); soInfo << "b" << integerToHex(reinterpret_cast<intptr_t>(header)); const char* const loadCommandsBegin = reinterpret_cast<const char*>(header) + headerSize; const char* const loadCommandsEnd = loadCommandsBegin + header->sizeofcmds; |