summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXiangyu Yao <xiangyu.yao@mongodb.com>2018-09-13 11:03:19 -0400
committerXiangyu Yao <xiangyu.yao@mongodb.com>2018-09-14 11:04:50 -0400
commit2072abc1824e633bb0b0fdf330fb40fe410d5092 (patch)
treef51ea6d28a62f5ab9886a2d0448a6049ebf2e1d3
parent913f15287664b8513876735f6f6198e212ad4e17 (diff)
downloadmongo-2072abc1824e633bb0b0fdf330fb40fe410d5092.tar.gz
SERVER-14801 Add field names to duplicate key error messages
-rw-r--r--src/mongo/db/storage/biggie/biggie_kv_engine.cpp3
-rw-r--r--src/mongo/db/storage/biggie/biggie_sorted_impl.cpp24
-rw-r--r--src/mongo/db/storage/biggie/biggie_sorted_impl.h8
-rw-r--r--src/mongo/db/storage/biggie/biggie_sorted_impl_test.cpp2
-rw-r--r--src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_btree_impl.cpp30
-rw-r--r--src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_btree_impl.h1
-rw-r--r--src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_btree_impl_test.cpp2
-rw-r--r--src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_engine.cpp1
-rw-r--r--src/mongo/db/storage/index_entry_comparison.cpp30
-rw-r--r--src/mongo/db/storage/index_entry_comparison.h8
-rw-r--r--src/mongo/db/storage/mobile/mobile_index.cpp32
-rw-r--r--src/mongo/db/storage/mobile/mobile_index.h3
-rw-r--r--src/mongo/db/storage/sorted_data_interface.h14
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp15
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_index.h9
15 files changed, 124 insertions, 58 deletions
diff --git a/src/mongo/db/storage/biggie/biggie_kv_engine.cpp b/src/mongo/db/storage/biggie/biggie_kv_engine.cpp
index 7c79a822d03..fc6ae96ec59 100644
--- a/src/mongo/db/storage/biggie/biggie_kv_engine.cpp
+++ b/src/mongo/db/storage/biggie/biggie_kv_engine.cpp
@@ -98,7 +98,8 @@ mongo::SortedDataInterface* KVEngine::getSortedDataInterface(OperationContext* o
desc->unique(),
ident,
desc->parentNS(),
- desc->indexName());
+ desc->indexName(),
+ desc->keyPattern());
}
diff --git a/src/mongo/db/storage/biggie/biggie_sorted_impl.cpp b/src/mongo/db/storage/biggie/biggie_sorted_impl.cpp
index e7ce7750c79..4737922ca92 100644
--- a/src/mongo/db/storage/biggie/biggie_sorted_impl.cpp
+++ b/src/mongo/db/storage/biggie/biggie_sorted_impl.cpp
@@ -216,7 +216,8 @@ SortedDataBuilderInterface::SortedDataBuilderInterface(OperationContext* opCtx,
const std::string& prefix,
const std::string& identEnd,
const std::string& collectionNamespace,
- const std::string& indexName)
+ const std::string& indexName,
+ const BSONObj& keyPattern)
: _opCtx(opCtx),
_dupsAllowed(dupsAllowed),
_order(order),
@@ -224,6 +225,7 @@ SortedDataBuilderInterface::SortedDataBuilderInterface(OperationContext* opCtx,
_identEnd(identEnd),
_collectionNamespace(collectionNamespace),
_indexName(indexName),
+ _keyPattern(keyPattern),
_hasLast(false),
_lastKeyToString(""),
_lastRID(-1) {}
@@ -258,7 +260,7 @@ StatusWith<SpecialFormatInserted> SortedDataBuilderInterface::addKey(const BSONO
"expected ascending (key, RecordId) order in bulk builder");
}
if (!_dupsAllowed && twoKeyCmp == 0 && twoRIDCmp != 0) {
- return dupKeyError(key, _collectionNamespace, _indexName);
+ return buildDupKeyErrorStatus(key, _collectionNamespace, _indexName, _keyPattern);
}
std::string workingCopyInsertKey = combineKeyAndRID(key, loc, _prefix, _order);
@@ -280,8 +282,14 @@ StatusWith<SpecialFormatInserted> SortedDataBuilderInterface::addKey(const BSONO
SortedDataBuilderInterface* SortedDataInterface::getBulkBuilder(OperationContext* opCtx,
bool dupsAllowed) {
- return new SortedDataBuilderInterface(
- opCtx, dupsAllowed, _order, _prefix, _identEnd, _collectionNamespace, _indexName);
+ return new SortedDataBuilderInterface(opCtx,
+ dupsAllowed,
+ _order,
+ _prefix,
+ _identEnd,
+ _collectionNamespace,
+ _indexName,
+ _keyPattern);
}
// We append \1 to all idents we get, and therefore the KeyString with ident + \0 will only be
@@ -291,7 +299,8 @@ SortedDataInterface::SortedDataInterface(const Ordering& ordering,
bool isUnique,
StringData ident,
const std::string& collectionNamespace,
- const std::string& indexName)
+ const std::string& indexName,
+ const BSONObj& keyPattern)
: _order(ordering),
// All entries in this ident will have a prefix of ident + \1.
_prefix(ident.toString().append(1, '\1')),
@@ -299,6 +308,7 @@ SortedDataInterface::SortedDataInterface(const Ordering& ordering,
_identEnd(ident.toString().append(1, '\2')),
_collectionNamespace(collectionNamespace),
_indexName(indexName),
+ _keyPattern(keyPattern),
_isUnique(isUnique) {
// This is the string representation of the KeyString before elements in this ident, which is
// ident + \0. This is before all elements in this ident.
@@ -344,7 +354,7 @@ StatusWith<SpecialFormatInserted> SortedDataInterface::insert(OperationContext*
auto ks1 = keyToKeyString(ike.key, _order);
auto ks2 = keyToKeyString(key, _order);
if (ks1->compare(*ks2) == 0 && ike.loc.repr() != loc.repr()) {
- return dupKeyError(key, _collectionNamespace, _indexName);
+ return buildDupKeyErrorStatus(key, _collectionNamespace, _indexName, _keyPattern);
}
}
}
@@ -402,7 +412,7 @@ Status SortedDataInterface::dupKeyCheck(OperationContext* opCtx,
lowerBoundIterator->first.compare(_KSForIdentEnd) < 0 &&
lowerBoundIterator->first.compare(
combineKeyAndRID(key, RecordId::max(), _prefix, _order)) <= 0) {
- return dupKeyError(key, _collectionNamespace, _indexName);
+ return buildDupKeyErrorStatus(key, _collectionNamespace, _indexName, _keyPattern);
}
return Status::OK();
}
diff --git a/src/mongo/db/storage/biggie/biggie_sorted_impl.h b/src/mongo/db/storage/biggie/biggie_sorted_impl.h
index 09a049981c4..a75f117fe11 100644
--- a/src/mongo/db/storage/biggie/biggie_sorted_impl.h
+++ b/src/mongo/db/storage/biggie/biggie_sorted_impl.h
@@ -44,7 +44,8 @@ public:
const std::string& prefix,
const std::string& identEnd,
const std::string& collectionNamespace,
- const std::string& indexName);
+ const std::string& indexName,
+ const BSONObj& keyPattern);
SpecialFormatInserted commit(bool mayInterrupt) override;
virtual StatusWith<SpecialFormatInserted> addKey(const BSONObj& key, const RecordId& loc);
@@ -59,6 +60,7 @@ private:
// Index metadata.
const std::string _collectionNamespace;
const std::string _indexName;
+ const BSONObj _keyPattern;
// Whether or not we've already added something before.
bool _hasLast;
// This is the KeyString of the last key added.
@@ -76,7 +78,8 @@ public:
bool isUnique,
StringData ident,
const std::string& collectionNamespace,
- const std::string& indexName);
+ const std::string& indexName,
+ const BSONObj& keyPattern);
virtual SortedDataBuilderInterface* getBulkBuilder(OperationContext* opCtx,
bool dupsAllowed) override;
virtual StatusWith<SpecialFormatInserted> insert(OperationContext* opCtx,
@@ -180,6 +183,7 @@ private:
// Index metadata.
const std::string _collectionNamespace;
const std::string _indexName;
+ const BSONObj _keyPattern;
// These are the keystring representations of the _prefix and the _identEnd.
std::string _KSForIdentStart;
std::string _KSForIdentEnd;
diff --git a/src/mongo/db/storage/biggie/biggie_sorted_impl_test.cpp b/src/mongo/db/storage/biggie/biggie_sorted_impl_test.cpp
index 68a82231ddd..38cd4adfa32 100644
--- a/src/mongo/db/storage/biggie/biggie_sorted_impl_test.cpp
+++ b/src/mongo/db/storage/biggie/biggie_sorted_impl_test.cpp
@@ -48,7 +48,7 @@ public:
SortedDataInterfaceTestHarnessHelper() : _order(Ordering::make(BSONObj())) {}
std::unique_ptr<mongo::SortedDataInterface> newSortedDataInterface(bool unique) final {
return std::make_unique<SortedDataInterface>(
- _order, unique, "ident"_sd, "test.biggie", "indexName");
+ _order, unique, "ident"_sd, "test.biggie", "indexName", BSONObj());
}
std::unique_ptr<mongo::RecoveryUnit> newRecoveryUnit() final {
//! not correct lol
diff --git a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_btree_impl.cpp b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_btree_impl.cpp
index aafbf42a148..401fc1f1fac 100644
--- a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_btree_impl.cpp
+++ b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_btree_impl.cpp
@@ -85,13 +85,15 @@ public:
long long* currentKeySize,
bool dupsAllowed,
const std::string& collectionNamespace,
- const std::string& indexName)
+ const std::string& indexName,
+ const BSONObj& keyPattern)
: _data(data),
_currentKeySize(currentKeySize),
_dupsAllowed(dupsAllowed),
_comparator(_data->key_comp()),
_collectionNamespace(collectionNamespace),
- _indexName(indexName) {
+ _indexName(indexName),
+ _keyPattern(keyPattern) {
invariant(_data->empty());
}
@@ -108,7 +110,7 @@ public:
return Status(ErrorCodes::InternalError,
"expected ascending (key, RecordId) order in bulk builder");
} else if (!_dupsAllowed && cmp == 0 && loc != _last->loc) {
- return dupKeyError(key, _collectionNamespace, _indexName);
+ return buildDupKeyErrorStatus(key, _collectionNamespace, _indexName, _keyPattern);
}
}
@@ -129,6 +131,7 @@ private:
const std::string _collectionNamespace;
const std::string _indexName;
+ const BSONObj _keyPattern;
};
class EphemeralForTestBtreeImpl : public SortedDataInterface {
@@ -136,17 +139,19 @@ public:
EphemeralForTestBtreeImpl(IndexSet* data,
bool isUnique,
const std::string& collectionNamespace,
- const std::string& indexName)
+ const std::string& indexName,
+ const BSONObj& keyPattern)
: _data(data),
_isUnique(isUnique),
_collectionNamespace(collectionNamespace),
- _indexName(indexName) {
+ _indexName(indexName),
+ _keyPattern(keyPattern) {
_currentKeySize = 0;
}
virtual SortedDataBuilderInterface* getBulkBuilder(OperationContext* opCtx, bool dupsAllowed) {
return new EphemeralForTestBtreeBuilderImpl(
- _data, &_currentKeySize, dupsAllowed, _collectionNamespace, _indexName);
+ _data, &_currentKeySize, dupsAllowed, _collectionNamespace, _indexName, _keyPattern);
}
virtual StatusWith<SpecialFormatInserted> insert(OperationContext* opCtx,
@@ -159,7 +164,7 @@ public:
// TODO optimization: save the iterator from the dup-check to speed up insert
if (!dupsAllowed && isDup(*_data, key, loc))
- return dupKeyError(key, _collectionNamespace, _indexName);
+ return buildDupKeyErrorStatus(key, _collectionNamespace, _indexName, _keyPattern);
IndexKeyEntry entry(key.getOwned(), loc);
if (_data->insert(entry).second) {
@@ -205,7 +210,7 @@ public:
virtual Status dupKeyCheck(OperationContext* opCtx, const BSONObj& key, const RecordId& loc) {
invariant(!hasFieldNames(key));
if (isDup(*_data, key, loc))
- return dupKeyError(key, _collectionNamespace, _indexName);
+ return buildDupKeyErrorStatus(key, _collectionNamespace, _indexName, _keyPattern);
return Status::OK();
}
@@ -503,6 +508,7 @@ private:
const std::string _collectionNamespace;
const std::string _indexName;
+ const BSONObj _keyPattern;
};
} // namespace
@@ -512,13 +518,17 @@ SortedDataInterface* getEphemeralForTestBtreeImpl(const Ordering& ordering,
bool isUnique,
const std::string& collectionNamespace,
const std::string& indexName,
+ const BSONObj& keyPattern,
std::shared_ptr<void>* dataInOut) {
invariant(dataInOut);
if (!*dataInOut) {
*dataInOut = std::make_shared<IndexSet>(IndexEntryComparison(ordering));
}
- return new EphemeralForTestBtreeImpl(
- static_cast<IndexSet*>(dataInOut->get()), isUnique, collectionNamespace, indexName);
+ return new EphemeralForTestBtreeImpl(static_cast<IndexSet*>(dataInOut->get()),
+ isUnique,
+ collectionNamespace,
+ indexName,
+ keyPattern);
}
} // namespace mongo
diff --git a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_btree_impl.h b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_btree_impl.h
index 57432888662..faff5127c24 100644
--- a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_btree_impl.h
+++ b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_btree_impl.h
@@ -45,6 +45,7 @@ SortedDataInterface* getEphemeralForTestBtreeImpl(const Ordering& ordering,
bool isUnique,
const std::string& collectionNamespace,
const std::string& indexName,
+ const BSONObj& keyPattern,
std::shared_ptr<void>* dataInOut);
} // namespace mongo
diff --git a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_btree_impl_test.cpp b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_btree_impl_test.cpp
index 21c943a2fd9..5afc8c6cd1c 100644
--- a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_btree_impl_test.cpp
+++ b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_btree_impl_test.cpp
@@ -45,7 +45,7 @@ public:
std::unique_ptr<SortedDataInterface> newSortedDataInterface(bool unique) final {
return std::unique_ptr<SortedDataInterface>(getEphemeralForTestBtreeImpl(
- _order, unique, "test.EphemeralForTest", "indexName", &_data));
+ _order, unique, "test.EphemeralForTest", "indexName", BSONObj(), &_data));
}
std::unique_ptr<RecoveryUnit> newRecoveryUnit() final {
diff --git a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_engine.cpp b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_engine.cpp
index b8814c3bdd0..53ae3afc4be 100644
--- a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_engine.cpp
+++ b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_engine.cpp
@@ -93,6 +93,7 @@ SortedDataInterface* EphemeralForTestEngine::getSortedDataInterface(OperationCon
desc->unique(),
desc->parentNS(),
desc->indexName(),
+ desc->keyPattern(),
&_dataMap[ident]);
}
diff --git a/src/mongo/db/storage/index_entry_comparison.cpp b/src/mongo/db/storage/index_entry_comparison.cpp
index 41a1ae709e9..b87fcf4f354 100644
--- a/src/mongo/db/storage/index_entry_comparison.cpp
+++ b/src/mongo/db/storage/index_entry_comparison.cpp
@@ -164,4 +164,34 @@ BSONObj IndexEntryComparison::makeQueryObject(const BSONObj& keyPrefix,
return bb.obj();
}
+Status buildDupKeyErrorStatus(const BSONObj& key,
+ const std::string& collectionNamespace,
+ const std::string& indexName,
+ const BSONObj& keyPattern) {
+ StringBuilder sb;
+ sb << "E11000 duplicate key error";
+ sb << " collection: " << collectionNamespace;
+ sb << " index: " << indexName;
+ sb << " dup key: ";
+
+ BSONObjBuilder builder;
+ // key is a document with forms like: '{ : 123}', '{ : {num: 123} }', '{ : 123, : "str" }'
+ BSONObjIterator keyValueIt(key);
+ // keyPattern is a document with only one level. e.g. '{a : 1, b : -1}', '{a.b : 1}'
+ BSONObjIterator keyNameIt(keyPattern);
+ // Combine key and keyPattern into one document which represents a mapping from indexFieldName
+ // to indexKey.
+ while (1) {
+ BSONElement keyValueElem = keyValueIt.next();
+ BSONElement keyNameElem = keyNameIt.next();
+ if (keyNameElem.eoo())
+ break;
+
+ builder.appendAs(keyValueElem, keyNameElem.fieldName());
+ }
+
+ sb << builder.obj();
+ return Status(ErrorCodes::DuplicateKey, sb.str());
+}
+
} // namespace mongo
diff --git a/src/mongo/db/storage/index_entry_comparison.h b/src/mongo/db/storage/index_entry_comparison.h
index 692731b00ec..8d05e496009 100644
--- a/src/mongo/db/storage/index_entry_comparison.h
+++ b/src/mongo/db/storage/index_entry_comparison.h
@@ -204,4 +204,12 @@ private:
}; // struct IndexEntryComparison
+/**
+ * Returns the formatted error status about the duplicate key.
+ */
+Status buildDupKeyErrorStatus(const BSONObj& key,
+ const std::string& collectionNamespace,
+ const std::string& indexName,
+ const BSONObj& keyPattern);
+
} // namespace mongo
diff --git a/src/mongo/db/storage/mobile/mobile_index.cpp b/src/mongo/db/storage/mobile/mobile_index.cpp
index 3c5000c4929..b081931f87a 100644
--- a/src/mongo/db/storage/mobile/mobile_index.cpp
+++ b/src/mongo/db/storage/mobile/mobile_index.cpp
@@ -76,7 +76,8 @@ MobileIndex::MobileIndex(OperationContext* opCtx,
_ordering(Ordering::make(desc->keyPattern())),
_ident(ident),
_collectionNamespace(desc->parentNS()),
- _indexName(desc->indexName()) {}
+ _indexName(desc->indexName()),
+ _keyPattern(desc->keyPattern()) {}
StatusWith<SpecialFormatInserted> MobileIndex::insert(OperationContext* opCtx,
const BSONObj& key,
@@ -113,7 +114,7 @@ StatusWith<SpecialFormatInserted> MobileIndex::doInsert(OperationContext* opCtx,
// Return error if duplicate key inserted in a unique index.
BSONObj bson =
KeyString::toBson(key.getBuffer(), key.getSize(), _ordering, key.getTypeBits());
- return dupKeyError(bson, _collectionNamespace, _indexName);
+ return buildDupKeyErrorStatus(bson, _collectionNamespace, _indexName, _keyPattern);
} else {
// A record with same key could already be present in a standard index, that is OK. This
// can happen when building a background index while documents are being written in
@@ -243,7 +244,7 @@ Status MobileIndex::dupKeyCheck(OperationContext* opCtx,
invariant(_isUnique);
if (_isDup(opCtx, key, recId))
- return dupKeyError(key, _collectionNamespace, _indexName);
+ return buildDupKeyErrorStatus(key, _collectionNamespace, _indexName, _keyPattern);
return Status::OK();
}
@@ -283,12 +284,14 @@ public:
OperationContext* opCtx,
bool dupsAllowed,
const std::string& collectionNamespace,
- const std::string& indexName)
+ const std::string& indexName,
+ const BSONObj& keyPattern)
: _index(index),
_opCtx(opCtx),
_dupsAllowed(dupsAllowed),
_collectionNamespace(collectionNamespace),
- _indexName(indexName) {}
+ _indexName(indexName),
+ _keyPattern(keyPattern) {}
virtual ~BulkBuilderBase() {}
@@ -318,7 +321,7 @@ protected:
Status _checkNextKey(const BSONObj& key) {
const int cmp = key.woCompare(_lastKey, _index->getOrdering());
if (!_dupsAllowed && cmp == 0) {
- return dupKeyError(key, _collectionNamespace, _indexName);
+ return buildDupKeyErrorStatus(key, _collectionNamespace, _indexName, _keyPattern);
} else if (cmp < 0) {
return Status(ErrorCodes::InternalError, "expected higher RecordId in bulk builder");
}
@@ -334,6 +337,7 @@ protected:
const bool _dupsAllowed;
const std::string _collectionNamespace;
const std::string _indexName;
+ const BSONObj _keyPattern;
};
/**
@@ -345,8 +349,9 @@ public:
OperationContext* opCtx,
bool dupsAllowed,
const std::string& collectionNamespace,
- const std::string& indexName)
- : BulkBuilderBase(index, opCtx, dupsAllowed, collectionNamespace, indexName) {}
+ const std::string& indexName,
+ const BSONObj& keyPattern)
+ : BulkBuilderBase(index, opCtx, dupsAllowed, collectionNamespace, indexName, keyPattern) {}
protected:
StatusWith<SpecialFormatInserted> _addKey(const BSONObj& key, const RecordId& recId) override {
@@ -365,8 +370,9 @@ public:
OperationContext* opCtx,
bool dupsAllowed,
const std::string& collectionNamespace,
- const std::string& indexName)
- : BulkBuilderBase(index, opCtx, dupsAllowed, collectionNamespace, indexName) {
+ const std::string& indexName,
+ const BSONObj& keyPattern)
+ : BulkBuilderBase(index, opCtx, dupsAllowed, collectionNamespace, indexName, keyPattern) {
// Replication is not supported so dups are not allowed.
invariant(!dupsAllowed);
}
@@ -666,7 +672,8 @@ MobileIndexStandard::MobileIndexStandard(OperationContext* opCtx,
SortedDataBuilderInterface* MobileIndexStandard::getBulkBuilder(OperationContext* opCtx,
bool dupsAllowed) {
invariant(dupsAllowed);
- return new BulkBuilderStandard(this, opCtx, dupsAllowed, _collectionNamespace, _indexName);
+ return new BulkBuilderStandard(
+ this, opCtx, dupsAllowed, _collectionNamespace, _indexName, _keyPattern);
}
std::unique_ptr<SortedDataInterface::Cursor> MobileIndexStandard::newCursor(OperationContext* opCtx,
@@ -704,7 +711,8 @@ SortedDataBuilderInterface* MobileIndexUnique::getBulkBuilder(OperationContext*
bool dupsAllowed) {
// Replication is not supported so dups are not allowed.
invariant(!dupsAllowed);
- return new BulkBuilderUnique(this, opCtx, dupsAllowed, _collectionNamespace, _indexName);
+ return new BulkBuilderUnique(
+ this, opCtx, dupsAllowed, _collectionNamespace, _indexName, _keyPattern);
}
std::unique_ptr<SortedDataInterface::Cursor> MobileIndexUnique::newCursor(OperationContext* opCtx,
diff --git a/src/mongo/db/storage/mobile/mobile_index.h b/src/mongo/db/storage/mobile/mobile_index.h
index 69c3ee08bca..b5eea4f3c00 100644
--- a/src/mongo/db/storage/mobile/mobile_index.h
+++ b/src/mongo/db/storage/mobile/mobile_index.h
@@ -114,8 +114,6 @@ public:
protected:
bool _isDup(OperationContext* opCtx, const BSONObj& key, RecordId recId);
- Status _dupKeyError(const BSONObj& key);
-
/**
* Performs the deletion from the table matching the given key.
*/
@@ -141,6 +139,7 @@ protected:
const std::string _ident;
const std::string _collectionNamespace;
const std::string _indexName;
+ const BSONObj _keyPattern;
};
class MobileIndexStandard final : public MobileIndex {
diff --git a/src/mongo/db/storage/sorted_data_interface.h b/src/mongo/db/storage/sorted_data_interface.h
index 4b720468344..74355bc96f9 100644
--- a/src/mongo/db/storage/sorted_data_interface.h
+++ b/src/mongo/db/storage/sorted_data_interface.h
@@ -52,20 +52,6 @@ struct ValidateResults;
enum SpecialFormatInserted { NoSpecialFormatInserted = 0, LongTypeBitsInserted = 1 };
/**
- * Returns the formatted error status about the duplicate key.
- */
-inline Status dupKeyError(const BSONObj& key,
- const std::string& collectionNamespace,
- const std::string& indexName) {
- StringBuilder sb;
- sb << "E11000 duplicate key error";
- sb << " collection: " << collectionNamespace;
- sb << " index: " << indexName;
- sb << " dup key: " << key;
- return Status(ErrorCodes::DuplicateKey, sb.str());
-}
-
-/**
* This is the uniform interface for storing indexes and supporting point queries as well as range
* queries. The actual implementation is up to the storage engine. All the storage engines must
* support an index key size up to the maximum document size.
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp
index f260ffe13e0..a8bba508d82 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp
@@ -266,6 +266,7 @@ WiredTigerIndex::WiredTigerIndex(OperationContext* ctx,
_tableId(WiredTigerSession::genTableId()),
_collectionNamespace(desc->parentNS()),
_indexName(desc->indexName()),
+ _keyPattern(desc->keyPattern()),
_prefix(prefix),
_isIdIndex(desc->isIdIndex()) {
auto version = WiredTigerUtil::checkApplicationMetadataFormatVersion(
@@ -413,7 +414,7 @@ Status WiredTigerIndex::dupKeyCheck(OperationContext* opCtx,
WT_CURSOR* c = curwrap.get();
if (isDup(opCtx, c, key, id))
- return dupKeyError(key, _collectionNamespace, _indexName);
+ return buildDupKeyErrorStatus(key, _collectionNamespace, _indexName, _keyPattern);
return Status::OK();
}
@@ -681,7 +682,8 @@ private:
if (cmp == 0) {
// Duplicate found!
if (!_dupsAllowed) {
- return dupKeyError(newKey, _idx->collectionNamespace(), _idx->indexName());
+ return buildDupKeyErrorStatus(
+ newKey, _idx->collectionNamespace(), _idx->indexName(), _idx->keyPattern());
}
} else {
// _previousKey.isEmpty() is only true on the first call to addKey().
@@ -728,7 +730,8 @@ private:
} else {
// Dup found!
if (!_dupsAllowed) {
- return dupKeyError(newKey, _idx->collectionNamespace(), _idx->indexName());
+ return buildDupKeyErrorStatus(
+ newKey, _idx->collectionNamespace(), _idx->indexName(), _idx->keyPattern());
}
// If we get here, we are in the weird mode where dups are allowed on a unique
@@ -1397,7 +1400,7 @@ StatusWith<SpecialFormatInserted> WiredTigerIndexUnique::_insertTimestampUnsafe(
}
if (!dupsAllowed)
- return dupKeyError(key, _collectionNamespace, _indexName);
+ return buildDupKeyErrorStatus(key, _collectionNamespace, _indexName, _keyPattern);
if (!insertedId) {
// This id is higher than all currently in the index for this key
@@ -1443,7 +1446,7 @@ StatusWith<SpecialFormatInserted> WiredTigerIndexUnique::_insertTimestampSafe(
// An entry with prefix key already exists. This can happen only during rolling upgrade when
// both timestamp unsafe and timestamp safe index format keys could be present.
if (ret == WT_DUPLICATE_KEY) {
- return dupKeyError(key, _collectionNamespace, _indexName);
+ return buildDupKeyErrorStatus(key, _collectionNamespace, _indexName, _keyPattern);
}
invariantWTOK(ret);
@@ -1456,7 +1459,7 @@ StatusWith<SpecialFormatInserted> WiredTigerIndexUnique::_insertTimestampSafe(
// Second phase looks up for existence of key to avoid insertion of duplicate key
if (isDup(opCtx, c, key, id))
- return dupKeyError(key, _collectionNamespace, _indexName);
+ return buildDupKeyErrorStatus(key, _collectionNamespace, _indexName, _keyPattern);
}
// Now create the table key/value, the actual data record.
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_index.h b/src/mongo/db/storage/wiredtiger/wiredtiger_index.h
index 47f8aff0bb3..61b48a19247 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_index.h
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_index.h
@@ -148,6 +148,10 @@ public:
return _indexName;
}
+ const BSONObj& keyPattern() const {
+ return _keyPattern;
+ }
+
bool isIdIndex() const {
return _isIdIndex;
}
@@ -182,8 +186,9 @@ protected:
int _dataFormatVersion;
std::string _uri;
uint64_t _tableId;
- std::string _collectionNamespace;
- std::string _indexName;
+ const std::string _collectionNamespace;
+ const std::string _indexName;
+ const BSONObj _keyPattern;
KVPrefix _prefix;
bool _isIdIndex;
};