summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMickey. J Winters <mickey.winters@mongodb.com>2021-03-10 15:02:44 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-03-10 15:57:27 +0000
commit10fcf336a0759ef5cee54576dafb1f19e4e125b5 (patch)
tree2324a3c6776348c4be3ea6b43370cc937c11982d /src
parent3d3a8cb06e9103e7269938331daf513e9cdb4c33 (diff)
downloadmongo-10fcf336a0759ef5cee54576dafb1f19e4e125b5.tar.gz
SERVER-54552 [SBE] Reverse index scan may produce wrong results
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/query/sbe_stage_builder_index_scan.cpp23
-rw-r--r--src/mongo/db/storage/index_entry_comparison.cpp18
-rw-r--r--src/mongo/db/storage/index_entry_comparison.h13
3 files changed, 40 insertions, 14 deletions
diff --git a/src/mongo/db/query/sbe_stage_builder_index_scan.cpp b/src/mongo/db/query/sbe_stage_builder_index_scan.cpp
index 863a2824ed8..1eee1a968f7 100644
--- a/src/mongo/db/query/sbe_stage_builder_index_scan.cpp
+++ b/src/mongo/db/query/sbe_stage_builder_index_scan.cpp
@@ -233,15 +233,20 @@ makeIntervalsFromIndexBounds(const IndexBounds& bounds,
"Generated interval [lowKey, highKey]",
"lowKey"_attr = lowKey,
"highKey"_attr = highKey);
- // For high keys use the opposite rule as a normal seek because a forward scan should end
- // after the key if inclusive, and before if exclusive.
- const auto inclusive = forward != highKeyInclusive;
- result.push_back({std::make_unique<KeyString::Value>(
- IndexEntryComparison::makeKeyStringFromBSONKeyForSeek(
- lowKey, version, ordering, forward, lowKeyInclusive)),
- std::make_unique<KeyString::Value>(
- IndexEntryComparison::makeKeyStringFromBSONKeyForSeek(
- highKey, version, ordering, forward, inclusive))});
+ // Note that 'makeKeyFromBSONKeyForSeek()' is intended to compute the "start" key for an
+ // index scan. The logic for computing a "discriminator" for an "end" key is reversed, which
+ // is why we use 'makeKeyStringFromBSONKey()' to manually specify the discriminator for the
+ // end key.
+ result.push_back(
+ {std::make_unique<KeyString::Value>(
+ IndexEntryComparison::makeKeyStringFromBSONKeyForSeek(
+ lowKey, version, ordering, forward, lowKeyInclusive)),
+ std::make_unique<KeyString::Value>(IndexEntryComparison::makeKeyStringFromBSONKey(
+ highKey,
+ version,
+ ordering,
+ forward != highKeyInclusive ? KeyString::Discriminator::kExclusiveBefore
+ : KeyString::Discriminator::kExclusiveAfter))});
}
return result;
}
diff --git a/src/mongo/db/storage/index_entry_comparison.cpp b/src/mongo/db/storage/index_entry_comparison.cpp
index a1b42051f15..965a4e8d796 100644
--- a/src/mongo/db/storage/index_entry_comparison.cpp
+++ b/src/mongo/db/storage/index_entry_comparison.cpp
@@ -167,12 +167,20 @@ KeyString::Value IndexEntryComparison::makeKeyStringFromBSONKeyForSeek(const BSO
Ordering ord,
bool isForward,
bool inclusive) {
+ return makeKeyStringFromBSONKey(bsonKey,
+ version,
+ ord,
+ isForward == inclusive
+ ? KeyString::Discriminator::kExclusiveBefore
+ : KeyString::Discriminator::kExclusiveAfter);
+}
+
+KeyString::Value IndexEntryComparison::makeKeyStringFromBSONKey(const BSONObj& bsonKey,
+ KeyString::Version version,
+ Ordering ord,
+ KeyString::Discriminator discrim) {
BSONObj finalKey = BSONObj::stripFieldNames(bsonKey);
- KeyString::Builder builder(version,
- finalKey,
- ord,
- isForward == inclusive ? KeyString::Discriminator::kExclusiveBefore
- : KeyString::Discriminator::kExclusiveAfter);
+ KeyString::Builder builder(version, finalKey, ord, discrim);
return builder.getValueCopy();
}
diff --git a/src/mongo/db/storage/index_entry_comparison.h b/src/mongo/db/storage/index_entry_comparison.h
index 6a1574c7360..767385283cf 100644
--- a/src/mongo/db/storage/index_entry_comparison.h
+++ b/src/mongo/db/storage/index_entry_comparison.h
@@ -257,6 +257,19 @@ public:
bool isForward,
bool inclusive);
+ /**
+ * Encodes the BSON Key into a KeyString object to pass in to SortedDataInterface::seek()
+ * or SortedDataInterface::setEndPosition().
+ *
+ * This funcition is similar to IndexEntryComparison::makeKeyStringFromBSONKeyForSeek()
+ * but allows you to pick your own KeyString::Discriminator based on wether or not the
+ * resulting KeyString is for the start key or end key of a seek.
+ */
+ static KeyString::Value makeKeyStringFromBSONKey(const BSONObj& bsonKey,
+ KeyString::Version version,
+ Ordering ord,
+ KeyString::Discriminator discrim);
+
private:
// Ordering is used in comparison() to compare BSONElements
const Ordering _order;