summaryrefslogtreecommitdiff
path: root/jstests
diff options
context:
space:
mode:
authorTed Tuckman <ted.tuckman@mongodb.com>2020-06-09 10:08:29 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-09-03 15:39:37 +0000
commit1be4f1b11d932a7799a6b08385c650bb61867e50 (patch)
tree4f0ffd0f6a98027cb8d1927cf8bf1f3637776722 /jstests
parent13a49321277a5b9fcc180594964a801b9136f6f2 (diff)
downloadmongo-1be4f1b11d932a7799a6b08385c650bb61867e50.tar.gz
SERVER-47382 Support inequalities on arrays with $not on indexed collection
Diffstat (limited to 'jstests')
-rw-r--r--jstests/aggregation/extras/utils.js37
-rw-r--r--jstests/core/array_index_and_nonIndex_consistent.js79
2 files changed, 94 insertions, 22 deletions
diff --git a/jstests/aggregation/extras/utils.js b/jstests/aggregation/extras/utils.js
index 1d5f5dee228..088ffa786e7 100644
--- a/jstests/aggregation/extras/utils.js
+++ b/jstests/aggregation/extras/utils.js
@@ -174,6 +174,43 @@ function arrayEq(al, ar, verbose = false, valueComparator, fieldsToSkip = []) {
return true;
}
+function arrayDiff(al, ar, verbose = false, valueComparator) {
+ // Check that these are both arrays.
+ if (!(al instanceof Array)) {
+ debug('arrayDiff: al is not an array: ' + tojson(al));
+ return false;
+ }
+
+ if (!(ar instanceof Array)) {
+ debug('arrayDiff: ar is not an array: ' + tojson(ar));
+ return false;
+ }
+
+ // Keep a set of which indexes we've already used to avoid considering [1,1] as equal to [1,2].
+ const matchedIndexesInRight = new Set();
+ let unmatchedElementsInLeft = [];
+ for (let leftElem of al) {
+ let foundMatch = false;
+ for (let i = 0; i < ar.length; ++i) {
+ if (!matchedIndexesInRight.has(i) && anyEq(leftElem, ar[i], verbose, valueComparator)) {
+ matchedIndexesInRight.add(i); // Don't use the same value each time.
+ foundMatch = true;
+ break;
+ }
+ }
+ if (!foundMatch) {
+ unmatchedElementsInLeft.push(leftElem);
+ }
+ }
+ let unmatchedElementsInRight = [];
+ for (let i = 0; i < ar.length; ++i) {
+ if (!matchedIndexesInRight.has(i)) {
+ unmatchedElementsInRight.push(ar[i]);
+ }
+ }
+ return {left: unmatchedElementsInLeft, right: unmatchedElementsInRight};
+}
+
/**
* Makes a shallow copy of 'a'.
*/
diff --git a/jstests/core/array_index_and_nonIndex_consistent.js b/jstests/core/array_index_and_nonIndex_consistent.js
index 7846032c21a..71657238d91 100644
--- a/jstests/core/array_index_and_nonIndex_consistent.js
+++ b/jstests/core/array_index_and_nonIndex_consistent.js
@@ -2,6 +2,7 @@
* Make sure that $gt and $lt queries return the same results regardless of whether there is a
* multikey index.
* @tags: [
+ * requires_fcv_47,
* sbe_incompatible,
* ]
*/
@@ -9,6 +10,18 @@
(function() {
"use strict";
load("jstests/aggregation/extras/utils.js"); // arrayEq
+
+function buildErrorString(q, indexed, nonIndexed) {
+ const arrDiff = arrayDiff(indexed, nonIndexed);
+ if (arrDiff === false) {
+ return "";
+ }
+ let errStr = "Ran query " + tojson(q) +
+ " and got mismatched results.\nUnmatched from indexed collection (" + arrDiff.left.length +
+ "/" + indexed.length + "): " + tojson(arrDiff.left) + "\nUnmatched from nonIndexed (" +
+ arrDiff.right.length + "/" + nonIndexed.length + "): " + tojson(arrDiff.right);
+ return errStr;
+}
const indexColl = db.indexColl;
const nonIndexedColl = db.nonIndexedColl;
indexColl.drop();
@@ -35,6 +48,8 @@ collList.forEach(function(collObj) {
{val: [true, 1]},
{val: [1, 4]},
{val: [null]},
+ // TODO SERVER-49766 Enable this test once the bug is found and fixed.
+ // {val: null},
{val: MinKey},
{val: [MinKey]},
{val: [MinKey, 3]},
@@ -48,31 +63,51 @@ collList.forEach(function(collObj) {
});
const queryList = [
- [2, 2], [0, 3], [3, 0], [1, 3], [3, 1], [1, 5], [5, 1], [1],
- [3], [5], {"test": 2}, {"test": 6}, [true, true], [true], true, 1,
- 3, 5, null, [null], [], [MinKey], [MinKey, 2], [MinKey, 4],
- MinKey, [MaxKey], [MaxKey, 2], [MaxKey, 4], MaxKey, [],
+ [2, 2], [0, 3], [3, 0], [1, 3], [3, 1], [1, 5], [5, 1], [1],
+ [3], [5], {"test": 2}, {"test": 6}, [true, true], [true], true, 1,
+ 3, 5, [], [MinKey], [MinKey, 2], [MinKey, 4], MinKey, [MaxKey],
+ [MaxKey, 2], [MaxKey, 4], MaxKey, [], false,
+ // TODO: SERVER-49766 Enable these queries.
+ // null, [null],
];
-let failedLT = [];
-let failedGT = [];
-
queryList.forEach(function(q) {
- const queryLT = {val: {"$lt": q}};
- const queryGT = {val: {"$gt": q}};
+ const queryPreds = [
+ {$lt: q},
+ {$lte: q},
+ {$gt: q},
+ {$gte: q},
+ {$eq: q},
+ {$not: {$lt: q}},
+ {$not: {$lte: q}},
+ {$not: {$gt: q}},
+ {$not: {$gte: q}},
+ {$not: {$eq: q}},
+ ];
const projOutId = {_id: 0, val: 1};
-
- let indexRes = indexColl.find(queryLT, projOutId).sort({val: 1}).toArray();
- let nonIndexedRes = nonIndexedColl.find(queryLT, projOutId).sort({val: 1}).toArray();
-
- assert(arrayEq(indexRes, nonIndexedRes),
- "Ran query " + tojson(queryLT) + " and got mismatched results.\n Indexed: " +
- tojson(indexRes) + "\n NonIndexed: " + tojson(nonIndexedRes));
-
- indexRes = indexColl.find(queryGT, projOutId).sort({val: 1}).toArray();
- nonIndexedRes = nonIndexedColl.find(queryGT, projOutId).sort({val: 1}).toArray();
- assert(arrayEq(indexRes, nonIndexedRes),
- "Ran query " + tojson(queryGT) + " and got mismatched results.\n Indexed: " +
- tojson(indexRes) + "\n NonIndexed: " + tojson(nonIndexedRes));
+ queryPreds.forEach(function(pred) {
+ const query = {val: pred};
+ const indexRes = indexColl.find(query, projOutId).sort({val: 1}).toArray();
+ const nonIndexedRes = nonIndexedColl.find(query, projOutId).sort({val: 1}).toArray();
+ assert(arrayEq(indexRes, nonIndexedRes), buildErrorString(query, indexRes, nonIndexedRes));
+ });
+});
+// Test queries with multiple intervals.
+const multiIntQueryList = [
+ {val: {$gt: 1, $lt: 3}},
+ {val: {$gt: [1], $lt: [3]}},
+ {val: {$not: {$gt: 3, $lt: 1}}},
+ {val: {$not: {$gt: [3], $lt: [1]}}},
+ {val: {$not: {$gt: [3], $lt: 1}}},
+ {val: {$not: {$not: {$lt: 3}}}},
+ {val: {$not: {$not: {$lt: true}}}},
+ {val: {$not: {$not: {$lt: [true]}}}},
+ {val: {$not: {$not: {$lt: [3]}}}},
+];
+multiIntQueryList.forEach(function(q) {
+ const projOutId = {_id: 0, val: 1};
+ const indexRes = indexColl.find(q, projOutId).sort({val: 1}).toArray();
+ const nonIndexedRes = nonIndexedColl.find(q, projOutId).sort({val: 1}).toArray();
+ assert(arrayEq(indexRes, nonIndexedRes), buildErrorString(q, indexRes, nonIndexedRes));
});
})();