summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Tarzia <steve.tarzia@mongodb.com>2022-03-07 23:01:01 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-03-09 16:58:22 +0000
commitfe13637b2bf0ed26970d1103c6e9254c0887c48a (patch)
tree66966d29e6451470da196b24789afa05906b96da
parentf0d4ecfc370bbeebe2a81d63736649069600e380 (diff)
downloadmongo-fe13637b2bf0ed26970d1103c6e9254c0887c48a.tar.gz
SERVER-62242 fixed $indexOfArray handling of duplicate vals in const arraysr5.2.2-rc0
-rw-r--r--jstests/aggregation/bugs/server62242.js32
-rw-r--r--src/mongo/db/pipeline/expression.cpp6
2 files changed, 35 insertions, 3 deletions
diff --git a/jstests/aggregation/bugs/server62242.js b/jstests/aggregation/bugs/server62242.js
new file mode 100644
index 00000000000..273dddbf16d
--- /dev/null
+++ b/jstests/aggregation/bugs/server62242.js
@@ -0,0 +1,32 @@
+// SERVER-62242
+// $indexOfArray does not work with duplicate values in array
+(function() {
+"use strict";
+
+const c = db[jsTest.name()];
+c.drop();
+
+c.save({_id: 0, number: 222});
+
+// before SERVER-62242, this incorrectly returned {_id: 0, number: 222, idx: -1}
+assert.eq(
+ [{_id: 0, number: 222, idx: 2}],
+ c.aggregate([{$addFields: {idx: {$indexOfArray: [[111, 111, 222], "$number"]}}}]).toArray());
+
+// this query was OK
+assert.eq([{_id: 0, number: 222, idx: 2}],
+ c.aggregate([
+ {$addFields: {idx: {$indexOfArray: [[111, 111, 222, 333], "$number"]}}}
+ ]).toArray());
+
+// also test for cases where a range is specified
+assert.eq([{_id: 0, number: 222, idx: -1}],
+ c.aggregate([
+ {$addFields: {idx: {$indexOfArray: [[111, 111, 222, 333], "$number", 0, 1]}}}
+ ]).toArray());
+
+assert.eq([{_id: 0, number: 222, idx: 3}],
+ c.aggregate([
+ {$addFields: {idx: {$indexOfArray: [[111, 111, 222, 222, 333], "$number", 3, 5]}}}
+ ]).toArray());
+})();
diff --git a/src/mongo/db/pipeline/expression.cpp b/src/mongo/db/pipeline/expression.cpp
index a1b99d4d307..0fce881ba18 100644
--- a/src/mongo/db/pipeline/expression.cpp
+++ b/src/mongo/db/pipeline/expression.cpp
@@ -3443,14 +3443,14 @@ public:
}
virtual Value evaluate(const Document& root, Variables* variables) const {
-
- auto args = evaluateAndValidateArguments(root, _children, _indexMap.size(), variables);
+ int arraySize = _children[0]->evaluate(root, variables).getArrayLength();
+ auto args = evaluateAndValidateArguments(root, _children, arraySize, variables);
auto indexVec = _indexMap.find(args.targetOfSearch);
if (indexVec == _indexMap.end())
return Value(-1);
- // Search through the vector of indecies for first index in our range.
+ // Search through the vector of indexes for first index in our range.
for (auto index : indexVec->second) {
if (index >= args.startIndex && index < args.endIndex) {
return Value(index);