diff options
author | Xiangyu Yao <xiangyu.yao@mongodb.com> | 2018-09-13 11:03:19 -0400 |
---|---|---|
committer | Xiangyu Yao <xiangyu.yao@mongodb.com> | 2018-09-14 11:04:50 -0400 |
commit | 2072abc1824e633bb0b0fdf330fb40fe410d5092 (patch) | |
tree | f51ea6d28a62f5ab9886a2d0448a6049ebf2e1d3 | |
parent | 913f15287664b8513876735f6f6198e212ad4e17 (diff) | |
download | mongo-2072abc1824e633bb0b0fdf330fb40fe410d5092.tar.gz |
SERVER-14801 Add field names to duplicate key error messages
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; }; |