summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUladzimir Makouski <uladzimir.makouski@mongodb.com>2021-04-22 06:22:08 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-04-22 09:18:21 +0000
commitaa2bbde8810ae9de83d6d0f1adbd364ed52cde32 (patch)
tree1024b095f0e0b5b8302d83c60242a25b93ce7f5c
parent1bc449e8d7626639900cfddb19df4d974bdb7532 (diff)
downloadmongo-aa2bbde8810ae9de83d6d0f1adbd364ed52cde32.tar.gz
Revert "SERVER-43964 UUID etc need not befriend IDL types"
This reverts commit 8f4dbd6889eb9534da7af27729aa0c2edea532f0.
-rw-r--r--buildscripts/idl/idl/cpp_types.py18
-rw-r--r--buildscripts/idl/idl/generator.py24
-rw-r--r--src/mongo/db/s/migration_destination_manager.cpp32
-rw-r--r--src/mongo/db/s/migration_destination_manager.h2
-rw-r--r--src/mongo/idl/idl_parser.h64
-rw-r--r--src/mongo/s/catalog/type_chunk.h12
-rw-r--r--src/mongo/util/uuid.h84
7 files changed, 128 insertions, 108 deletions
diff --git a/buildscripts/idl/idl/cpp_types.py b/buildscripts/idl/idl/cpp_types.py
index bb7ec7d0a22..d4066af197f 100644
--- a/buildscripts/idl/idl/cpp_types.py
+++ b/buildscripts/idl/idl/cpp_types.py
@@ -56,6 +56,24 @@ def is_primitive_scalar_type(cpp_type):
]
+def get_primitive_scalar_type_default_value(cpp_type):
+ # type: (str) -> str
+ """
+ Return a default value for a primitive scalar type.
+
+ Assumes the IDL generated code verifies the user sets the value before serialization.
+ """
+ # pylint: disable=invalid-name
+ assert is_primitive_scalar_type(cpp_type)
+ if cpp_type == 'bool':
+ return 'false'
+ # TODO (SERVER-50101): Remove 'FeatureCompatibility::Version' once IDL supports a command
+ # cpp_type of C++ enum.
+ if cpp_type == 'ServerGlobalParams::FeatureCompatibility::Version':
+ return 'ServerGlobalParams::FeatureCompatibility::Version::kUnsetDefault44Behavior'
+ return '-1'
+
+
def is_primitive_type(cpp_type):
# type: (str) -> bool
"""Return True if a cpp_type is a primitive type and should not be returned as reference."""
diff --git a/buildscripts/idl/idl/generator.py b/buildscripts/idl/idl/generator.py
index 3dc643b5075..34747fd6d24 100644
--- a/buildscripts/idl/idl/generator.py
+++ b/buildscripts/idl/idl/generator.py
@@ -1580,12 +1580,13 @@ class _CppSourceFileWriter(_CppFileWriterBase):
if default_init:
for field in struct.fields:
needs_init = (field.type and field.type.cpp_type and not field.type.is_array
- and _is_required_serializer_field(field)
- and field.cpp_name != 'dbName')
- if needs_init:
+ and cpp_types.is_primitive_scalar_type(field.type.cpp_type))
+
+ if _is_required_serializer_field(field) and needs_init:
initializers.append(
- '%s(mongo::idl::preparsedValue<decltype(%s)>())' %
- (_get_field_member_name(field), _get_field_member_name(field)))
+ '%s(%s)' % (_get_field_member_name(field),
+ cpp_types.get_primitive_scalar_type_default_value(
+ field.type.cpp_type)))
# Serialize the _dbName field second
initializes_db_name = False
@@ -1759,13 +1760,13 @@ class _CppSourceFileWriter(_CppFileWriterBase):
if struct.command_field.type.cpp_type and cpp_types.is_primitive_scalar_type(
struct.command_field.type.cpp_type):
- self._writer.write_line(
- 'auto localCmdType = mongo::idl::preparsedValue<%s>();' %
- (cpp_type_info.get_storage_type()))
+ self._writer.write_line('%s localCmdType(%s);' %
+ (cpp_type_info.get_storage_type(),
+ cpp_types.get_primitive_scalar_type_default_value(
+ struct.command_field.type.cpp_type)))
else:
self._writer.write_line(
- 'auto localCmdType = mongo::idl::preparsedValue<%s>();' %
- (cpp_type_info.get_storage_type()))
+ '%s localCmdType;' % (cpp_type_info.get_storage_type()))
self._writer.write_line(
'%s object(localCmdType);' % (common.title_case(struct.cpp_name)))
elif struct.namespace in (common.COMMAND_NAMESPACE_CONCATENATE_WITH_DB,
@@ -1776,8 +1777,7 @@ class _CppSourceFileWriter(_CppFileWriterBase):
else:
assert False, "Missing case"
else:
- self._writer.write_line('auto object = mongo::idl::preparsedValue<%s>();' %
- common.title_case(struct.cpp_name))
+ self._writer.write_line('%s object;' % common.title_case(struct.cpp_name))
self._writer.write_line(method_info.get_call('object'))
self._writer.write_line('return object;')
diff --git a/src/mongo/db/s/migration_destination_manager.cpp b/src/mongo/db/s/migration_destination_manager.cpp
index 3c62eaa932d..7e5a9fbe72f 100644
--- a/src/mongo/db/s/migration_destination_manager.cpp
+++ b/src/mongo/db/s/migration_destination_manager.cpp
@@ -701,7 +701,7 @@ MigrationDestinationManager::getCollectionOptions(OperationContext* opCtx,
fromOptionsBob.append(info["uuid"]);
fromOptions = fromOptionsBob.obj();
- return {fromOptions, UUID::fromCDR(fromUUID)};
+ return {fromOptions, fromUUID};
}
void MigrationDestinationManager::_dropLocalIndexesIfNecessary(
@@ -918,7 +918,7 @@ void MigrationDestinationManager::_migrateDriver(OperationContext* outerOpCtx) {
"fromShard"_attr = _fromShard,
"epoch"_attr = _epoch,
"sessionId"_attr = *_sessionId,
- "migrationId"_attr = _migrationId->toBSON());
+ "migrationId"_attr = _migrationId.toBSON());
MoveTimingHelper timing(
outerOpCtx, "to", _nss.ns(), _min, _max, 6 /* steps */, &_errmsg, _toShard, _fromShard);
@@ -928,7 +928,7 @@ void MigrationDestinationManager::_migrateDriver(OperationContext* outerOpCtx) {
if (initialState == ABORT) {
LOGV2_ERROR(22013,
"Migration abort requested before the migration started",
- "migrationId"_attr = _migrationId->toBSON());
+ "migrationId"_attr = _migrationId.toBSON());
return;
}
@@ -965,7 +965,7 @@ void MigrationDestinationManager::_migrateDriver(OperationContext* outerOpCtx) {
"scheduled for deletion",
"namespace"_attr = _nss.ns(),
"range"_attr = redact(range.toString()),
- "migrationId"_attr = _migrationId->toBSON());
+ "migrationId"_attr = _migrationId.toBSON());
auto status = CollectionShardingRuntime::waitForClean(
outerOpCtx, _nss, donorCollectionOptionsAndIndexes.uuid, range);
@@ -979,7 +979,7 @@ void MigrationDestinationManager::_migrateDriver(OperationContext* outerOpCtx) {
}
// Insert a pending range deletion task for the incoming range.
- RangeDeletionTask recipientDeletionTask(*_migrationId,
+ RangeDeletionTask recipientDeletionTask(_migrationId,
_nss,
donorCollectionOptionsAndIndexes.uuid,
_fromShard,
@@ -1099,7 +1099,7 @@ void MigrationDestinationManager::_migrateDriver(OperationContext* outerOpCtx) {
LOGV2_WARNING(
22011,
"secondaryThrottle on, but doc insert timed out; continuing",
- "migrationId"_attr = _migrationId->toBSON());
+ "migrationId"_attr = _migrationId.toBSON());
} else {
uassertStatusOK(replStatus.status);
}
@@ -1177,7 +1177,7 @@ void MigrationDestinationManager::_migrateDriver(OperationContext* outerOpCtx) {
if (getState() == ABORT) {
LOGV2(22002,
"Migration aborted while waiting for replication at catch up stage",
- "migrationId"_attr = _migrationId->toBSON());
+ "migrationId"_attr = _migrationId.toBSON());
return;
}
@@ -1190,7 +1190,7 @@ void MigrationDestinationManager::_migrateDriver(OperationContext* outerOpCtx) {
if (i > 100) {
LOGV2(22003,
"secondaries having hard time keeping up with migrate",
- "migrationId"_attr = _migrationId->toBSON());
+ "migrationId"_attr = _migrationId.toBSON());
}
sleepmillis(20);
@@ -1212,12 +1212,12 @@ void MigrationDestinationManager::_migrateDriver(OperationContext* outerOpCtx) {
LOGV2(22004,
"Waiting for replication to catch up before entering critical section",
- "migrationId"_attr = _migrationId->toBSON());
+ "migrationId"_attr = _migrationId.toBSON());
LOGV2_DEBUG_OPTIONS(4817411,
2,
{logv2::LogComponent::kShardMigrationPerf},
"Starting majority commit wait on recipient",
- "migrationId"_attr = _migrationId->toBSON());
+ "migrationId"_attr = _migrationId.toBSON());
runWithoutSession(outerOpCtx, [&] {
auto awaitReplicationResult =
@@ -1229,12 +1229,12 @@ void MigrationDestinationManager::_migrateDriver(OperationContext* outerOpCtx) {
LOGV2(22005,
"Chunk data replicated successfully.",
- "migrationId"_attr = _migrationId->toBSON());
+ "migrationId"_attr = _migrationId.toBSON());
LOGV2_DEBUG_OPTIONS(4817412,
2,
{logv2::LogComponent::kShardMigrationPerf},
"Finished majority commit wait on recipient",
- "migrationId"_attr = _migrationId->toBSON());
+ "migrationId"_attr = _migrationId.toBSON());
}
{
@@ -1274,7 +1274,7 @@ void MigrationDestinationManager::_migrateDriver(OperationContext* outerOpCtx) {
if (getState() == ABORT) {
LOGV2(22006,
"Migration aborted while transferring mods",
- "migrationId"_attr = _migrationId->toBSON());
+ "migrationId"_attr = _migrationId.toBSON());
return;
}
@@ -1407,7 +1407,7 @@ bool MigrationDestinationManager::_applyMigrateOp(OperationContext* opCtx,
"reloaded remote document",
"localDoc"_attr = redact(localDoc),
"remoteDoc"_attr = redact(updatedDoc),
- "migrationId"_attr = _migrationId->toBSON());
+ "migrationId"_attr = _migrationId.toBSON());
}
// We are in write lock here, so sure we aren't killing
@@ -1438,7 +1438,7 @@ bool MigrationDestinationManager::_flushPendingWrites(OperationContext* opCtx,
"chunkMin"_attr = redact(_min),
"chunkMax"_attr = redact(_max),
"lastOpApplied"_attr = op,
- "migrationId"_attr = _migrationId->toBSON());
+ "migrationId"_attr = _migrationId.toBSON());
}
return false;
}
@@ -1449,7 +1449,7 @@ bool MigrationDestinationManager::_flushPendingWrites(OperationContext* opCtx,
"namespace"_attr = _nss.ns(),
"chunkMin"_attr = redact(_min),
"chunkMax"_attr = redact(_max),
- "migrationId"_attr = _migrationId->toBSON());
+ "migrationId"_attr = _migrationId.toBSON());
return true;
}
diff --git a/src/mongo/db/s/migration_destination_manager.h b/src/mongo/db/s/migration_destination_manager.h
index b90a56f52f1..761f8c9c4ef 100644
--- a/src/mongo/db/s/migration_destination_manager.h
+++ b/src/mongo/db/s/migration_destination_manager.h
@@ -234,7 +234,7 @@ private:
stdx::thread _migrateThreadHandle;
- boost::optional<UUID> _migrationId;
+ UUID _migrationId;
LogicalSessionId _lsid;
TxnNumber _txnNumber{kUninitializedTxnNumber};
NamespaceString _nss;
diff --git a/src/mongo/idl/idl_parser.h b/src/mongo/idl/idl_parser.h
index 17d7c803586..316ccd06c7e 100644
--- a/src/mongo/idl/idl_parser.h
+++ b/src/mongo/idl/idl_parser.h
@@ -37,7 +37,6 @@
#include "mongo/bson/bsonobjbuilder.h"
#include "mongo/bson/bsontypes.h"
#include "mongo/db/namespace_string.h"
-#include "mongo/stdx/type_traits.h"
namespace mongo {
@@ -71,69 +70,6 @@ void idlSerialize(BSONObjBuilder* builder, StringData fieldName, std::vector<T>
}
}
-/**
- * A few overloads of `idlPreparsedValue` are built into IDL. See
- * `preparsedValue` below. They are placed into a tiny private
- * namespace which defines no types to isolate them.
- */
-namespace preparsed_value_adl_barrier {
-
-/**
- * This is the fallback for `idlPreparsedValue`. It value-initializes a `T`
- * with a forwarded argument list in the usual way.
- */
-template <typename T, typename... A>
-auto idlPreparsedValue(stdx::type_identity<T>, A&&... a) {
- return T(std::forward<A>(a)...);
-}
-
-/**
- * The value -1 is a conspicuous "uninitialized" value for integers.
- * The integral type `bool` is exempt from this convention, however.
- */
-template <typename T, std::enable_if_t<std::is_integral_v<T> && !std::is_same_v<bool, T>, int> = 0>
-auto idlPreparsedValue(stdx::type_identity<T>) {
- return static_cast<T>(-1);
-}
-
-/**
- * Define a default Feature Compatibility Version enum value for use in parsed
- * ServerGlobalParams.
- * TODO(SERVER-50101): Remove 'FeatureCompatibility::Version' once IDL supports
- * a command cpp_type of C++ enum.
- */
-inline auto idlPreparsedValue(
- stdx::type_identity<ServerGlobalParams::FeatureCompatibility::Version>) {
- return ServerGlobalParams::FeatureCompatibility::Version::kUnsetDefault44Behavior;
-}
-
-} // namespace preparsed_value_adl_barrier
-
-/**
- * Constructs an instance of `T(args...)` for use in idl parsing. The way the
- * IDL generator currently writes C++ parse functions, it makes an instance of
- * a field of type `T` and then mutates it. `preparsedValue<T>()` is used to
- * construct those objects. This convention allows an extension hook whereby a
- * type can select a custom initializer for such pre-parsed objects,
- * particularly for types that shouldn't have a public default constructor.
- *
- * The extension hook is implemented via ADL on the name `idlPreparsedValue`.
- *
- * `idlPreparsedValue` takes a `type_identity<T>` and then some forwarded
- * constructor arguments optionally (the IDL generator doesn't currently
- * provide any such arguments but could conceivably do so in the future). A
- * type `T` is deduced from this `type_identity<T>` argument.
- *
- * There are other ways to implement this extension mechanism, but this
- * phrasing allows argument-dependent lookup to search the namespaces
- * associated with `T`, since `T` is a template parameter of the
- * `type_identity<T>` argument.
- */
-template <typename T, typename... A>
-T preparsedValue(A&&... args) {
- using preparsed_value_adl_barrier::idlPreparsedValue;
- return idlPreparsedValue(stdx::type_identity<T>{}, std::forward<A>(args)...);
-}
} // namespace idl
diff --git a/src/mongo/s/catalog/type_chunk.h b/src/mongo/s/catalog/type_chunk.h
index 1de86691f20..425edb9c4e2 100644
--- a/src/mongo/s/catalog/type_chunk.h
+++ b/src/mongo/s/catalog/type_chunk.h
@@ -39,7 +39,6 @@
#include "mongo/s/chunk_version.h"
#include "mongo/s/shard_id.h"
#include "mongo/s/shard_key_pattern.h"
-#include "mongo/stdx/type_traits.h"
namespace mongo {
@@ -124,14 +123,17 @@ public:
ChunkRange unionWith(ChunkRange const& other) const;
private:
+ // For use with IDL parsing - limited to friend access only.
+ ChunkRange() = default;
+
+ // Make the IDL generated parser a friend
+ friend class RangeDeletionTask;
+ friend class MigrationCoordinatorDocument;
+
BSONObj _minKey;
BSONObj _maxKey;
};
-inline ChunkRange idlPreparsedValue(stdx::type_identity<ChunkRange>) {
- return ChunkRange{{}, {}};
-}
-
class ChunkHistory : public ChunkHistoryBase {
public:
ChunkHistory() : ChunkHistoryBase() {}
diff --git a/src/mongo/util/uuid.h b/src/mongo/util/uuid.h
index eade27480d6..a5e259a3c9a 100644
--- a/src/mongo/util/uuid.h
+++ b/src/mongo/util/uuid.h
@@ -40,20 +40,83 @@
#include "mongo/bson/bsonmisc.h"
#include "mongo/bson/bsonobj.h"
#include "mongo/logv2/log_attr.h"
-#include "mongo/stdx/type_traits.h"
namespace mongo {
+namespace repl {
+class CollectionInfo;
+class OplogEntryBase;
+class DurableReplOperation;
+class InitialSyncIdDocument;
+} // namespace repl
+
+namespace idl {
+namespace import {
+class One_UUID;
+} // namespace import
+} // namespace idl
+
/**
* A UUID is a 128-bit unique identifier, per RFC 4122, v4, using
* a secure random number generator.
*/
class UUID {
+ using UUIDStorage = std::array<unsigned char, 16>;
+
+ // Make the IDL generated parser a friend
+ friend class ConfigsvrShardCollectionResponse;
+ friend class CommonReshardingMetadata;
+ friend class DonorAbortMigration;
+ friend class DonorStartMigration;
+ friend class DonorWaitForMigrationToCommit;
+ friend class DonorForgetMigration;
+ friend class DonorStateMachine;
+ friend class DatabaseVersion;
+ friend class DbCheckOplogCollection;
+ friend class EncryptionPlaceholder;
+ friend class ExternalKeysCollectionDocument;
+ friend class idl::import::One_UUID;
+ friend class IndexBuildEntry;
+ friend class KeyStoreRecord;
+ friend class ListCollectionsReplyInfo;
+ friend class LogicalSessionId;
+ friend class LogicalSessionToClient;
+ friend class LogicalSessionIdToClient;
+ friend class LogicalSessionFromClient;
+ friend class MigrationCoordinatorDocument;
+ friend class MigrationDestinationManager;
+ friend class MigrationRecipientCommonData;
+ friend class RangeDeletionTask;
+ friend class ResolvedKeyId;
+ friend class repl::CollectionInfo;
+ friend class repl::OplogEntryBase;
+ friend class repl::DurableReplOperation;
+ friend class repl::InitialSyncIdDocument;
+ friend class RecipientForgetMigration;
+ friend class RecipientSyncData;
+ friend class ReshardingDonorDocument;
+ friend class ReshardingSourceId;
+ friend class ResumeIndexInfo;
+ friend class ResumeTokenInternal;
+ friend class ShardCollectionTypeBase;
+ friend class ShardsvrCleanupReshardCollection;
+ friend class ShardsvrShardCollectionResponse;
+ friend class ShardsvrRenameCollection;
+ friend class TenantMigrationDonorDocument;
+ friend class TenantMigrationRecipientDocument;
+ friend class TestReshardCloneCollection;
+ friend class TypeCollectionRecipientFields;
+ friend class TypeCollectionReshardingFields;
+ friend class VoteCommitIndexBuild;
+ friend class ImportCollectionOplogEntry;
+ friend class VoteCommitImportCollection;
+
+
public:
/**
* The number of bytes contained in a UUID.
*/
- static constexpr int kNumBytes = 16;
+ static constexpr int kNumBytes = sizeof(UUIDStorage);
/**
* Generate a new random v4 UUID per RFC 4122.
@@ -80,7 +143,7 @@ public:
static UUID parse(const BSONObj& obj);
static UUID fromCDR(ConstDataRange cdr) {
- UUID uuid{UUIDStorage{}};
+ UUID uuid;
invariant(cdr.length() == uuid._uuid.size());
memcpy(uuid._uuid.data(), cdr.data(), uuid._uuid.size());
return uuid;
@@ -179,18 +242,19 @@ public:
}
private:
- using UUIDStorage = std::array<unsigned char, kNumBytes>;
-
UUID(const UUIDStorage& uuid) : _uuid(uuid) {}
+ /**
+ * Should never be used, as the resulting UUID will not be unique.
+ * The exception is in code generated by the IDL compiler, which itself ensures
+ * such an invalid value cannot propagate.
+ */
+ friend class LogicalSessionId;
+ UUID() = default;
+
UUIDStorage _uuid{}; // UUID in network byte order
};
-/** Allow IDL-generated parsers to define uninitialized UUID objects. */
-inline auto idlPreparsedValue(stdx::type_identity<UUID>) {
- return UUID::fromCDR(std::array<unsigned char, 16>{});
-}
-
inline std::ostream& operator<<(std::ostream& s, const UUID& uuid) {
return (s << uuid.toString());
}