summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharlie Swanson <charlie.swanson@mongodb.com>2019-12-20 23:31:41 +0000
committerevergreen <evergreen@mongodb.com>2019-12-20 23:31:41 +0000
commit74e2b22bcd9803532755eb0582e533fb9a12bce8 (patch)
tree789b53bdf42895b13386157b5fbf0a34ae0adf95
parent950c58b9b5449e6207fa8c80da202f789a70e29d (diff)
downloadmongo-74e2b22bcd9803532755eb0582e533fb9a12bce8.tar.gz
SERVER-45177 Avoid using getChildVector() to traverse MatchExpression
-rw-r--r--jstests/core/mr_not_equals_predicate.js22
-rw-r--r--src/mongo/db/commands/mr.cpp4
2 files changed, 24 insertions, 2 deletions
diff --git a/jstests/core/mr_not_equals_predicate.js b/jstests/core/mr_not_equals_predicate.js
new file mode 100644
index 00000000000..5e5426732ff
--- /dev/null
+++ b/jstests/core/mr_not_equals_predicate.js
@@ -0,0 +1,22 @@
+// Tests that a mapReduce command can succeed when given a not equals predicate. This test was
+// designed to reproduce SERVER-45177.
+// @tags: [
+// # mapReduce does not support afterClusterTime.
+// does_not_support_causal_consistency,
+// does_not_support_stepdowns,
+// ]
+(function() {
+"use strict";
+const coll = db.mr_ne_query;
+assert.commandWorked(coll.insert([{key: 'one', val: 1}, {key: 'two', val: 2}]));
+assert.doesNotThrow(() => coll.find({key: {$ne: 'one'}}));
+const mapper = function() {
+ emit(this._id, this.val);
+};
+const reducer = function(k, v) {
+ return Array.sum(v);
+};
+assert.doesNotThrow(() => coll.mapReduce(mapper, reducer, {out: {inline: 1}, query: {}}));
+assert.doesNotThrow(
+ () => coll.mapReduce(mapper, reducer, {out: {inline: 1}, query: {key: {$ne: 'one'}}}));
+}());
diff --git a/src/mongo/db/commands/mr.cpp b/src/mongo/db/commands/mr.cpp
index 5edc6a426aa..f11ed660b9f 100644
--- a/src/mongo/db/commands/mr.cpp
+++ b/src/mongo/db/commands/mr.cpp
@@ -236,8 +236,8 @@ bool queryContainsMatchType(MatchExpression* root, MatchExpression::MatchType ma
if (root->matchType() == match) {
return false;
} else if (root->numChildren() > 0) {
- for (auto&& child : *(root->getChildVector())) {
- if (!queryContainsMatchType(child, match)) {
+ for (size_t i = 0; i < root->numChildren(); i++) {
+ if (!queryContainsMatchType(root->getChild(i), match)) {
return false;
}
}