summaryrefslogtreecommitdiff
path: root/src/mongo/db/query/index_bounds_builder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/query/index_bounds_builder.cpp')
-rw-r--r--src/mongo/db/query/index_bounds_builder.cpp26
1 files changed, 26 insertions, 0 deletions
diff --git a/src/mongo/db/query/index_bounds_builder.cpp b/src/mongo/db/query/index_bounds_builder.cpp
index 1f8dcae97e9..742faf4f938 100644
--- a/src/mongo/db/query/index_bounds_builder.cpp
+++ b/src/mongo/db/query/index_bounds_builder.cpp
@@ -121,6 +121,7 @@ bool stringMayHaveUnescapedPipe(StringData str) {
const BSONObj kUndefinedElementObj = BSON("" << BSONUndefined);
const BSONObj kNullElementObj = BSON("" << BSONNULL);
+const BSONObj kEmptyArrayElementObj = BSON("" << BSONArray());
const Interval kHashedUndefinedInterval = IndexBoundsBuilder::makePointInterval(
ExpressionMapping::hash(kUndefinedElementObj.firstElement()));
@@ -558,6 +559,31 @@ void IndexBoundsBuilder::_translatePredicate(const MatchExpression* expr,
return;
}
+ if (MatchExpression::MATCH_IN == child->matchType()) {
+ auto ime = static_cast<const InMatchExpression*>(child);
+ if (QueryPlannerIXSelect::canUseIndexForNin(ime)) {
+ // Permit documents with an undefined value to be returned from $nin index scan. The
+ // empty array is represented as undefined in the index but the empty array values
+ // are filtered out. This is required to match the collection scan (no index)
+ // behavior. This was later changed by SERVER-21929.
+ BSONObjBuilder bob;
+ bob.appendMinKey("");
+ bob.appendUndefined("");
+ oilOut->intervals.push_back(makeRangeInterval(
+ bob.asTempObj().getOwned(), BoundInclusion::kIncludeBothStartAndEndKeys));
+ bob.resetToEmpty();
+ bob.appendNull("");
+ bob.appendMaxKey("");
+ oilOut->intervals.push_back(
+ makeRangeInterval(bob.done().getOwned(), BoundInclusion::kIncludeEndKeyOnly));
+ unionize(oilOut);
+ if (index.pathHasMultikeyComponent(elt.fieldNameStringData())) {
+ *tightnessOut = IndexBoundsBuilder::INEXACT_FETCH;
+ }
+ return;
+ }
+ }
+
_translatePredicate(child, elt, index, oilOut, tightnessOut);
oilOut->complement();