Permalink
Browse files

SERVER-37643 IndexCatalog::removeExistingIndexes() optionally throws …

…on invalid non-duplicate indexes
  • Loading branch information...
benety committed Jan 12, 2019
1 parent 73686f7 commit 19f8455248c54159339fbb07b4ffb8da8795e770
@@ -1,4 +1,3 @@

/**
* Copyright (C) 2018-present MongoDB, Inc.
*
@@ -325,11 +324,17 @@ class IndexCatalog {
const BSONObj& original) const = 0;

/**
* Removes pre-existing indexes from 'indexSpecsToBuild'. If this isn't done, an index build
* using 'indexSpecsToBuild' may fail with error code IndexAlreadyExists.
* Returns a copy of 'indexSpecsToBuild' that does not contain index specifications already
* existing in this index catalog. If this isn't done, an index build using 'indexSpecsToBuild'
* may fail with error code IndexAlreadyExists.
*
* If 'throwOnErrors' is set to true, any validation errors on a non-duplicate index
* will result in this function throwing an exception.
*/
virtual std::vector<BSONObj> removeExistingIndexes(
OperationContext* const opCtx, const std::vector<BSONObj>& indexSpecsToBuild) const = 0;
OperationContext* const opCtx,
const std::vector<BSONObj>& indexSpecsToBuild,
bool throwOnErrors = false) const = 0;

/**
* Drops all indexes in the index catalog, optionally dropping the id index depending on the
@@ -1,4 +1,3 @@

/**
* Copyright (C) 2018-present MongoDB, Inc.
*
@@ -271,14 +270,19 @@ StatusWith<BSONObj> IndexCatalogImpl::prepareSpecForCreate(OperationContext* opC
}

std::vector<BSONObj> IndexCatalogImpl::removeExistingIndexes(
OperationContext* const opCtx, const std::vector<BSONObj>& indexSpecsToBuild) const {
OperationContext* const opCtx,
const std::vector<BSONObj>& indexSpecsToBuild,
bool throwOnErrors) const {
std::vector<BSONObj> result;
for (const auto& spec : indexSpecsToBuild) {
auto status = prepareSpecForCreate(opCtx, spec).getStatus();
if (status.code() == ErrorCodes::IndexAlreadyExists) {
auto prepareResult = prepareSpecForCreate(opCtx, spec);
if (prepareResult == ErrorCodes::IndexAlreadyExists) {
continue;
}
// Intentionally ignoring other error codes.
// Intentionally ignoring other error codes unless 'throwOnErrors' is true.
if (throwOnErrors) {
uassertStatusOK(prepareResult);
}
result.push_back(spec);
}
return result;
@@ -1,4 +1,3 @@

/**
* Copyright (C) 2018-present MongoDB, Inc.
*
@@ -190,9 +189,9 @@ class IndexCatalogImpl : public IndexCatalog {
StatusWith<BSONObj> prepareSpecForCreate(OperationContext* opCtx,
const BSONObj& original) const override;

std::vector<BSONObj> removeExistingIndexes(
OperationContext* const opCtx,
const std::vector<BSONObj>& indexSpecsToBuild) const override;
std::vector<BSONObj> removeExistingIndexes(OperationContext* const opCtx,
const std::vector<BSONObj>& indexSpecsToBuild,
bool throwOnErrors) const override;

/**
* Drops all indexes in the index catalog, optionally dropping the id index depending on the
@@ -144,9 +144,9 @@ class IndexCatalogNoop : public IndexCatalog {
return original;
}

std::vector<BSONObj> removeExistingIndexes(
OperationContext* const opCtx,
const std::vector<BSONObj>& indexSpecsToBuild) const override {
std::vector<BSONObj> removeExistingIndexes(OperationContext* const opCtx,
const std::vector<BSONObj>& indexSpecsToBuild,
bool throwOnErrors) const override {
return {};
}

@@ -67,10 +67,6 @@

namespace mongo {

using std::string;

using IndexVersion = IndexDescriptor::IndexVersion;

MONGO_FAIL_POINT_DEFINE(hangAfterIndexBuildFirstDrain);
MONGO_FAIL_POINT_DEFINE(hangAfterIndexBuildSecondDrain);
MONGO_FAIL_POINT_DEFINE(hangAfterIndexBuildDumpsInsertsFromBulk);
@@ -230,18 +226,8 @@ std::vector<BSONObj> resolveDefaultsAndRemoveExistingIndexes(OperationContext* o
resolveCollectionDefaultProperties(opCtx, collection, std::move(validatedSpecs));
uassertStatusOK(swDefaults.getStatus());

auto specs = std::move(swDefaults.getValue());
for (size_t i = 0; i < specs.size(); i++) {
Status status =
collection->getIndexCatalog()->prepareSpecForCreate(opCtx, specs.at(i)).getStatus();
if (status.code() == ErrorCodes::IndexAlreadyExists) {
specs.erase(specs.begin() + i);
i--;
continue;
}
uassertStatusOK(status);
}
return specs;
auto indexCatalog = collection->getIndexCatalog();
return indexCatalog->removeExistingIndexes(opCtx, swDefaults.getValue(), /*throwOnError=*/true);
}

void checkUniqueIndexConstraints(OperationContext* opCtx,
@@ -262,9 +248,9 @@ void checkUniqueIndexConstraints(OperationContext* opCtx,
}

bool runCreateIndexes(OperationContext* opCtx,
const string& dbname,
const std::string& dbname,
const BSONObj& cmdObj,
string& errmsg,
std::string& errmsg,
BSONObjBuilder& result,
bool runTwoPhaseBuild) {
const NamespaceString ns(CommandHelpers::parseNsCollectionRequired(dbname, cmdObj));
@@ -509,9 +495,9 @@ class CmdCreateIndex : public ErrmsgCommandDeprecated {
}

bool errmsgRun(OperationContext* opCtx,
const string& dbname,
const std::string& dbname,
const BSONObj& cmdObj,
string& errmsg,
std::string& errmsg,
BSONObjBuilder& result) override {
return runCreateIndexes(opCtx, dbname, cmdObj, errmsg, result, false /*two phase build*/);
}
@@ -550,9 +536,9 @@ class CmdTwoPhaseCreateIndex : public ErrmsgCommandDeprecated {
}

bool errmsgRun(OperationContext* opCtx,
const string& dbname,
const std::string& dbname,
const BSONObj& cmdObj,
string& errmsg,
std::string& errmsg,
BSONObjBuilder& result) override {
return runCreateIndexes(opCtx, dbname, cmdObj, errmsg, result, true /*two phase build*/);
}

0 comments on commit 19f8455

Please sign in to comment.