summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenety Goh <benety@mongodb.com>2019-11-14 20:38:41 +0000
committerevergreen <evergreen@mongodb.com>2019-11-14 20:38:41 +0000
commit3f4312f26e1667826db51a0d2834eb417bb5de2d (patch)
treec745d9c6d63bd3637e2fda99fd4f9162c07db97f
parentd24bae5300d3f6a342f5981f26e4309264aa4cb0 (diff)
downloadmongo-3f4312f26e1667826db51a0d2834eb417bb5de2d.tar.gz
SERVER-44619 truncate message for error code 16746 if too long
-rw-r--r--jstests/core/indexu.js7
-rw-r--r--src/mongo/db/index/btree_key_generator.cpp15
2 files changed, 20 insertions, 2 deletions
diff --git a/jstests/core/indexu.js b/jstests/core/indexu.js
index f8b6af7f15d..0e68429eaf7 100644
--- a/jstests/core/indexu.js
+++ b/jstests/core/indexu.js
@@ -6,7 +6,7 @@
t = db.jstests_indexu;
t.drop();
-var dupDoc = {a: [{'0': 1}]}; // There are two 'a.0' fields in this doc.
+var dupDoc = {_id: 0, a: [{'0': 1}]}; // There are two 'a.0' fields in this doc.
var dupDoc2 = {a: [{'1': 1}, 'c']};
var noDupDoc = {a: [{'1': 1}]};
@@ -14,6 +14,11 @@ var noDupDoc = {a: [{'1': 1}]};
assert.commandWorked(t.save(dupDoc));
assert.commandFailed(t.ensureIndex({'a.0': 1}));
+// Test that we can fail gracefully when dupDoc has a large array padded with nulls.
+// Index is based on max padding constant in mongo/db/update/path_support.h
+assert.commandWorked(t.update({_id: 0}, {$set: {'a.1500001': 1}}));
+assert.commandFailedWithCode(t.ensureIndex({'a.0': 1}), 16746);
+
t.remove({});
assert.commandWorked(t.ensureIndex({'a.0': 1}));
assert.writeError(t.save(dupDoc));
diff --git a/src/mongo/db/index/btree_key_generator.cpp b/src/mongo/db/index/btree_key_generator.cpp
index c0daddfc3a5..b8dcb6f1024 100644
--- a/src/mongo/db/index/btree_key_generator.cpp
+++ b/src/mongo/db/index/btree_key_generator.cpp
@@ -94,11 +94,24 @@ BSONElement BtreeKeyGenerator::_extractNextElement(const BSONObj& obj,
// An index component field name cannot exist in both a document
// array and one of that array's children.
+ auto arrayObjAsString = [](const BSONObj& arrayObj) {
+ auto msg = arrayObj.toString();
+ const auto kMaxLength = 1024U;
+ if (msg.length() < kMaxLength) {
+ return msg;
+ }
+ str::stream ss;
+ ss << msg.substr(0, kMaxLength / 3);
+ ss << " .......... ";
+ ss << msg.substr(msg.size() - (kMaxLength / 3));
+ return std::string(ss);
+ };
uassert(
16746,
str::stream() << "Ambiguous field name found in array (do not use numeric field names in "
"embedded elements in an array), field: '"
- << arrField.fieldName() << "' for array: " << positionalInfo.arrayObj,
+ << arrField.fieldName()
+ << "' for array: " << arrayObjAsString(positionalInfo.arrayObj),
!haveObjField || !positionalInfo.hasPositionallyIndexedElt());
*arrayNestedArray = false;