summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/bson/bsonobjbuilder.h75
-rw-r--r--src/mongo/bson/bsonobjbuilder_test.cpp41
-rw-r--r--src/mongo/bson/bsontypes.cpp64
-rw-r--r--src/mongo/bson/bsontypes.h86
-rw-r--r--src/mongo/client/remote_command_targeter_mock.h2
-rw-r--r--src/mongo/db/commands/generic_servers.cpp12
-rw-r--r--src/mongo/db/commands/lock_info.cpp2
-rw-r--r--src/mongo/db/curop.cpp2
-rw-r--r--src/mongo/db/ftdc/controller_test.cpp2
-rw-r--r--src/mongo/db/ftdc/ftdc_system_stats_linux.cpp2
-rw-r--r--src/mongo/db/index_builds_coordinator.h1
-rw-r--r--src/mongo/db/index_names.cpp1
-rw-r--r--src/mongo/db/matcher/expression_leaf.cpp2
-rw-r--r--src/mongo/db/matcher/expression_parser.cpp3
-rw-r--r--src/mongo/db/matcher/matcher_type_set.cpp37
-rw-r--r--src/mongo/db/matcher/matcher_type_set.h10
-rw-r--r--src/mongo/db/matcher/matcher_type_set_test.cpp61
-rw-r--r--src/mongo/db/matcher/schema/json_schema_parser.cpp32
-rw-r--r--src/mongo/db/matcher/schema/json_schema_parser.h7
-rw-r--r--src/mongo/db/pipeline/document.h1
-rw-r--r--src/mongo/db/repl/repl_set_commands.cpp5
-rw-r--r--src/mongo/db/repl/replication_info.cpp2
-rw-r--r--src/mongo/db/repl/split_horizon.h1
-rw-r--r--src/mongo/db/repl/topology_coordinator.cpp6
-rw-r--r--src/mongo/db/s/active_shard_collection_registry.h1
-rw-r--r--src/mongo/db/s/config/initial_split_policy.h1
-rw-r--r--src/mongo/db/s/config/namespace_serializer.h1
-rw-r--r--src/mongo/db/stats/server_write_concern_metrics.h1
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_util.cpp2
-rw-r--r--src/mongo/dbtests/storage_timestamp_tests.cpp16
-rw-r--r--src/mongo/s/query/router_stage_remove_metadata_fields.h1
-rw-r--r--src/mongo/shell/shell_utils_extended.cpp2
-rw-r--r--src/mongo/util/future_impl.h1
-rw-r--r--src/mongo/util/net/http_client_curl.cpp2
-rw-r--r--src/mongo/util/stacktrace_posix.cpp2
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;