summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
authorJacob Evans <jacob.evans@10gen.com>2018-11-30 17:31:15 -0500
committerJacob Evans <jacob.evans@10gen.com>2018-12-14 15:27:42 -0500
commitac39ac47d776bbd0f442f945d4ae6091b73cfb03 (patch)
treeadfea7594dc25d87b76a6fb4b9db05dbfc38dbc3 /src/mongo/db
parent333b35057d35230ad5bc868bd0eaa7423d9aceb4 (diff)
downloadmongo-ac39ac47d776bbd0f442f945d4ae6091b73cfb03.tar.gz
SERVER-38069 Ensure WT transactions are not re-opened during plan updates
Diffstat (limited to 'src/mongo/db')
-rw-r--r--src/mongo/db/catalog/collection_info_cache_impl.cpp6
-rw-r--r--src/mongo/db/commands/index_filter_commands_test.cpp41
-rw-r--r--src/mongo/db/commands/plan_cache_commands_test.cpp28
-rw-r--r--src/mongo/db/query/get_executor.cpp20
-rw-r--r--src/mongo/db/query/get_executor.h10
-rw-r--r--src/mongo/db/query/get_executor_test.cpp122
-rw-r--r--src/mongo/db/query/index_bounds_builder_test.cpp354
-rw-r--r--src/mongo/db/query/index_entry.h126
-rw-r--r--src/mongo/db/query/index_entry_test.cpp22
-rw-r--r--src/mongo/db/query/plan_cache.cpp4
-rw-r--r--src/mongo/db/query/plan_cache.h2
-rw-r--r--src/mongo/db/query/plan_cache_indexability.cpp11
-rw-r--r--src/mongo/db/query/plan_cache_indexability.h8
-rw-r--r--src/mongo/db/query/plan_cache_indexability_test.cpp199
-rw-r--r--src/mongo/db/query/plan_cache_test.cpp140
-rw-r--r--src/mongo/db/query/planner_analysis_test.cpp30
-rw-r--r--src/mongo/db/query/planner_ixselect_test.cpp213
-rw-r--r--src/mongo/db/query/query_planner_test.cpp48
-rw-r--r--src/mongo/db/query/query_planner_test_fixture.cpp155
-rw-r--r--src/mongo/db/query/query_settings_test.cpp45
-rw-r--r--src/mongo/db/query/query_solution_test.cpp101
21 files changed, 1041 insertions, 644 deletions
diff --git a/src/mongo/db/catalog/collection_info_cache_impl.cpp b/src/mongo/db/catalog/collection_info_cache_impl.cpp
index 0b02a29896d..ecbca8a8509 100644
--- a/src/mongo/db/catalog/collection_info_cache_impl.cpp
+++ b/src/mongo/db/catalog/collection_info_cache_impl.cpp
@@ -188,7 +188,7 @@ QuerySettings* CollectionInfoCacheImpl::getQuerySettings() const {
}
void CollectionInfoCacheImpl::updatePlanCacheIndexEntries(OperationContext* opCtx) {
- std::vector<IndexEntry> indexEntries;
+ std::vector<CoreIndexInfo> indexCores;
// TODO We shouldn't need to include unfinished indexes, but we must here because the index
// catalog may be in an inconsistent state. SERVER-18346.
@@ -197,10 +197,10 @@ void CollectionInfoCacheImpl::updatePlanCacheIndexEntries(OperationContext* opCt
_collection->getIndexCatalog()->getIndexIterator(opCtx, includeUnfinishedIndexes);
while (ii->more()) {
const IndexCatalogEntry* ice = ii->next();
- indexEntries.emplace_back(indexEntryFromIndexCatalogEntry(opCtx, *ice));
+ indexCores.emplace_back(indexInfoFromIndexCatalogEntry(*ice));
}
- _planCache->notifyOfIndexEntries(indexEntries);
+ _planCache->notifyOfIndexUpdates(indexCores);
}
void CollectionInfoCacheImpl::init(OperationContext* opCtx) {
diff --git a/src/mongo/db/commands/index_filter_commands_test.cpp b/src/mongo/db/commands/index_filter_commands_test.cpp
index 3427eb1b8f7..a2b6eec3080 100644
--- a/src/mongo/db/commands/index_filter_commands_test.cpp
+++ b/src/mongo/db/commands/index_filter_commands_test.cpp
@@ -428,13 +428,12 @@ TEST(IndexFilterCommandsTest, SetAndClearFiltersCollation) {
// Create a plan cache. Add an index so that indexability is included in the plan cache keys.
PlanCache planCache;
- planCache.notifyOfIndexEntries({IndexEntry(fromjson("{a: 1}"),
- false,
- false,
- false,
- IndexEntry::Identifier{"index_name"},
- NULL,
- BSONObj())});
+ const auto keyPattern = fromjson("{a: 1}");
+ planCache.notifyOfIndexUpdates(
+ {CoreIndexInfo(keyPattern,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
+ true, // sparse
+ IndexEntry::Identifier{"index_name"})}); // name
// Inject query shapes with and without collation into plan cache.
addQueryShapeToPlanCache(
@@ -502,27 +501,23 @@ TEST(IndexFilterCommandsTest, SetAndClearFiltersCollation) {
TEST(IndexFilterCommandsTest, SetFilterAcceptsIndexNames) {
CollatorInterfaceMock reverseCollator(CollatorInterfaceMock::MockType::kReverseString);
- IndexEntry collatedIndex(fromjson("{a: 1}"),
- false,
- false,
- false,
- IndexEntry::Identifier{"a_1:rev"},
- nullptr,
- BSONObj());
+ PlanCache planCache;
+ const auto keyPattern = fromjson("{a: 1}");
+ CoreIndexInfo collatedIndex(keyPattern,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
+ false, // sparse
+ IndexEntry::Identifier{"a_1:rev"}); // name
collatedIndex.collator = &reverseCollator;
QueryTestServiceContext serviceContext;
auto opCtx = serviceContext.makeOperationContext();
QuerySettings querySettings;
- PlanCache planCache;
- planCache.notifyOfIndexEntries({IndexEntry(fromjson("{a: 1}"),
- false,
- false,
- false,
- IndexEntry::Identifier{"a_1"},
- nullptr,
- BSONObj()),
- collatedIndex});
+ planCache.notifyOfIndexUpdates(
+ {CoreIndexInfo(keyPattern,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
+ false, // sparse
+ IndexEntry::Identifier{"a_1"}), // name
+ collatedIndex});
addQueryShapeToPlanCache(opCtx.get(), &planCache, "{a: 2}", "{}", "{}", "{}");
ASSERT_TRUE(planCacheContains(opCtx.get(), planCache, "{a: 2}", "{}", "{}", "{}"));
diff --git a/src/mongo/db/commands/plan_cache_commands_test.cpp b/src/mongo/db/commands/plan_cache_commands_test.cpp
index b7dabbf3ea0..593909ac24f 100644
--- a/src/mongo/db/commands/plan_cache_commands_test.cpp
+++ b/src/mongo/db/commands/plan_cache_commands_test.cpp
@@ -390,13 +390,13 @@ TEST(PlanCacheCommandsTest, planCacheClearOneKeyCollation) {
// Create plan cache with 2 entries. Add an index so that indexability is included in the plan
// cache keys.
PlanCache planCache;
- planCache.notifyOfIndexEntries({IndexEntry(fromjson("{a: 1}"),
- false,
- false,
- false,
- IndexEntry::Identifier{"index_name"},
- NULL,
- BSONObj())});
+ const auto keyPattern = fromjson("{a: 1}");
+ planCache.notifyOfIndexUpdates(
+ {CoreIndexInfo(keyPattern,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
+ false, // sparse
+ IndexEntry::Identifier{"indexName"})}); // name
+
QuerySolution qs;
qs.cacheData.reset(createSolutionCacheData());
std::vector<QuerySolution*> solns;
@@ -640,13 +640,13 @@ TEST(PlanCacheCommandsTest, planCacheListPlansCollation) {
// Create plan cache with 2 entries. Add an index so that indexability is included in the plan
// cache keys. Give query with collation two solutions.
PlanCache planCache;
- planCache.notifyOfIndexEntries({IndexEntry(fromjson("{a: 1}"),
- false,
- false,
- false,
- IndexEntry::Identifier{"index_name"},
- NULL,
- BSONObj())});
+ const auto keyPattern = fromjson("{a: 1}");
+ planCache.notifyOfIndexUpdates(
+ {CoreIndexInfo(keyPattern,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
+ false, // sparse
+ IndexEntry::Identifier{"indexName"})}); // name
+
QuerySolution qs;
qs.cacheData.reset(createSolutionCacheData());
std::vector<QuerySolution*> solns;
diff --git a/src/mongo/db/query/get_executor.cpp b/src/mongo/db/query/get_executor.cpp
index d56410ec580..0e24ef31472 100644
--- a/src/mongo/db/query/get_executor.cpp
+++ b/src/mongo/db/query/get_executor.cpp
@@ -181,6 +181,26 @@ IndexEntry indexEntryFromIndexCatalogEntry(OperationContext* opCtx,
projExec};
}
+CoreIndexInfo indexInfoFromIndexCatalogEntry(const IndexCatalogEntry& ice) {
+ auto desc = ice.descriptor();
+ invariant(desc);
+
+ auto accessMethod = ice.accessMethod();
+ invariant(accessMethod);
+
+ const ProjectionExecAgg* projExec = nullptr;
+ if (desc->getIndexType() == IndexType::INDEX_WILDCARD)
+ projExec = static_cast<const WildcardAccessMethod*>(accessMethod)->getProjectionExec();
+
+ return {desc->keyPattern(),
+ desc->getIndexType(),
+ desc->isSparse(),
+ IndexEntry::Identifier{desc->indexName()},
+ ice.getFilterExpression(),
+ ice.getCollator(),
+ projExec};
+}
+
void fillOutPlannerParams(OperationContext* opCtx,
Collection* collection,
CanonicalQuery* canonicalQuery,
diff --git a/src/mongo/db/query/get_executor.h b/src/mongo/db/query/get_executor.h
index ec5f010748f..8ad39d5091e 100644
--- a/src/mongo/db/query/get_executor.h
+++ b/src/mongo/db/query/get_executor.h
@@ -68,7 +68,8 @@ void fillOutPlannerParams(OperationContext* opCtx,
/**
* Converts the catalog metadata for an index into an IndexEntry, which is a format that is meant to
- * be consumed by the query planner.
+ * be consumed by the query planner. This function can perform index reads and should not be called
+ * unless access to the storage engine is permitted.
*
* When 'canonicalQuery' is not null, only multikey metadata paths that intersect with the query
* field set will be retrieved for a multikey wildcard index. Otherwise all multikey metadata paths
@@ -79,6 +80,13 @@ IndexEntry indexEntryFromIndexCatalogEntry(OperationContext* opCtx,
const CanonicalQuery* canonicalQuery = nullptr);
/**
+ * Converts the catalog metadata for an index into a CoreIndexInfo, which is a format that is meant
+ * to be used to update the plan cache. This function has no side effects and is safe to call in
+ * all contexts.
+ */
+CoreIndexInfo indexInfoFromIndexCatalogEntry(const IndexCatalogEntry& ice);
+
+/**
* Determines whether or not to wait for oplog visibility for a query. This is only used for
* collection scans on the oplog.
*/
diff --git a/src/mongo/db/query/get_executor_test.cpp b/src/mongo/db/query/get_executor_test.cpp
index 592cfaea3c9..da234b77150 100644
--- a/src/mongo/db/query/get_executor_test.cpp
+++ b/src/mongo/db/query/get_executor_test.cpp
@@ -116,12 +116,51 @@ void testAllowedIndices(std::vector<IndexEntry> indexes,
}
}
+/**
+ * Make a minimal IndexEntry from just a key pattern and a name.
+ */
+IndexEntry buildSimpleIndexEntry(const BSONObj& kp, const std::string& indexName) {
+ return {kp,
+ IndexNames::nameToType(IndexNames::findPluginName(kp)),
+ false,
+ {},
+ {},
+ false,
+ false,
+ CoreIndexInfo::Identifier(indexName),
+ nullptr,
+ {},
+ nullptr,
+ nullptr};
+}
+
+/**
+ * Make a minimal IndexEntry from just a key pattern and a name. Include a wildcardProjection which
+ * is neccesary for wildcard indicies.
+ */
+IndexEntry buildWildcardIndexEntry(const BSONObj& kp,
+ const ProjectionExecAgg* projExec,
+ const std::string& indexName) {
+ return {kp,
+ IndexNames::nameToType(IndexNames::findPluginName(kp)),
+ false,
+ {},
+ {},
+ false,
+ false,
+ CoreIndexInfo::Identifier(indexName),
+ nullptr,
+ {},
+ nullptr,
+ projExec};
+}
+
// Use of index filters to select compound index over single key index.
TEST(GetExecutorTest, GetAllowedIndices) {
testAllowedIndices(
- {IndexEntry(fromjson("{a: 1}"), "a_1"),
- IndexEntry(fromjson("{a: 1, b: 1}"), "a_1_b_1"),
- IndexEntry(fromjson("{a: 1, c: 1}"), "a_1_c_1")},
+ {buildSimpleIndexEntry(fromjson("{a: 1}"), "a_1"),
+ buildSimpleIndexEntry(fromjson("{a: 1, b: 1}"), "a_1_b_1"),
+ buildSimpleIndexEntry(fromjson("{a: 1, c: 1}"), "a_1_c_1")},
SimpleBSONObjComparator::kInstance.makeBSONObjSet({fromjson("{a: 1, b: 1}")}),
stdx::unordered_set<std::string>{},
{"a_1_b_1"});
@@ -132,9 +171,9 @@ TEST(GetExecutorTest, GetAllowedIndices) {
// result in the planner generating a collection scan.
TEST(GetExecutorTest, GetAllowedIndicesNonExistentIndexKeyPatterns) {
testAllowedIndices(
- {IndexEntry(fromjson("{a: 1}"), "a_1"),
- IndexEntry(fromjson("{a: 1, b: 1}"), "a_1_b_1"),
- IndexEntry(fromjson("{a: 1, c: 1}"), "a_1_c_1")},
+ {buildSimpleIndexEntry(fromjson("{a: 1}"), "a_1"),
+ buildSimpleIndexEntry(fromjson("{a: 1, b: 1}"), "a_1_b_1"),
+ buildSimpleIndexEntry(fromjson("{a: 1, c: 1}"), "a_1_c_1")},
SimpleBSONObjComparator::kInstance.makeBSONObjSet({fromjson("{nosuchfield: 1}")}),
stdx::unordered_set<std::string>{},
stdx::unordered_set<std::string>{});
@@ -143,16 +182,17 @@ TEST(GetExecutorTest, GetAllowedIndicesNonExistentIndexKeyPatterns) {
// This test case shows how to force query execution to use
// an index that orders items in descending order.
TEST(GetExecutorTest, GetAllowedIndicesDescendingOrder) {
- testAllowedIndices(
- {IndexEntry(fromjson("{a: 1}"), "a_1"), IndexEntry(fromjson("{a: -1}"), "a_-1")},
- SimpleBSONObjComparator::kInstance.makeBSONObjSet({fromjson("{a: -1}")}),
- stdx::unordered_set<std::string>{},
- {"a_-1"});
+ testAllowedIndices({buildSimpleIndexEntry(fromjson("{a: 1}"), "a_1"),
+ buildSimpleIndexEntry(fromjson("{a: -1}"), "a_-1")},
+ SimpleBSONObjComparator::kInstance.makeBSONObjSet({fromjson("{a: -1}")}),
+ stdx::unordered_set<std::string>{},
+ {"a_-1"});
}
TEST(GetExecutorTest, GetAllowedIndicesMatchesByName) {
testAllowedIndices(
- {IndexEntry(fromjson("{a: 1}"), "a_1"), IndexEntry(fromjson("{a: 1}"), "a_1:en")},
+ {buildSimpleIndexEntry(fromjson("{a: 1}"), "a_1"),
+ buildSimpleIndexEntry(fromjson("{a: 1}"), "a_1:en")},
// BSONObjSet default constructor is explicit, so we cannot copy-list-initialize until
// C++14.
SimpleBSONObjComparator::kInstance.makeBSONObjSet(),
@@ -161,48 +201,64 @@ TEST(GetExecutorTest, GetAllowedIndicesMatchesByName) {
}
TEST(GetExecutorTest, GetAllowedIndicesMatchesMultipleIndexesByKey) {
- testAllowedIndices(
- {IndexEntry(fromjson("{a: 1}"), "a_1"), IndexEntry(fromjson("{a: 1}"), "a_1:en")},
- SimpleBSONObjComparator::kInstance.makeBSONObjSet({fromjson("{a: 1}")}),
- stdx::unordered_set<std::string>{},
- {"a_1", "a_1:en"});
+ testAllowedIndices({buildSimpleIndexEntry(fromjson("{a: 1}"), "a_1"),
+ buildSimpleIndexEntry(fromjson("{a: 1}"), "a_1:en")},
+ SimpleBSONObjComparator::kInstance.makeBSONObjSet({fromjson("{a: 1}")}),
+ stdx::unordered_set<std::string>{},
+ {"a_1", "a_1:en"});
}
TEST(GetExecutorTest, GetAllowedWildcardIndicesByKey) {
- testAllowedIndices({IndexEntry(BSON("$**" << 1), "$**_1"),
- IndexEntry(fromjson("{a: 1}"), "a_1"),
- IndexEntry(fromjson("{a: 1, b: 1}"), "a_1_b_1"),
- IndexEntry(fromjson("{a: 1, c: 1}"), "a_1_c_1")},
+ auto projExec = ProjectionExecAgg::create(
+ fromjson("{_id: 0}"),
+ ProjectionExecAgg::DefaultIdPolicy::kExcludeId,
+ ProjectionExecAgg::ArrayRecursionPolicy::kDoNotRecurseNestedArrays);
+ testAllowedIndices({buildWildcardIndexEntry(BSON("$**" << 1), projExec.get(), "$**_1"),
+ buildSimpleIndexEntry(fromjson("{a: 1}"), "a_1"),
+ buildSimpleIndexEntry(fromjson("{a: 1, b: 1}"), "a_1_b_1"),
+ buildSimpleIndexEntry(fromjson("{a: 1, c: 1}"), "a_1_c_1")},
SimpleBSONObjComparator::kInstance.makeBSONObjSet({BSON("$**" << 1)}),
stdx::unordered_set<std::string>{},
{"$**_1"});
}
TEST(GetExecutorTest, GetAllowedWildcardIndicesByName) {
- testAllowedIndices({IndexEntry(BSON("$**" << 1), "$**_1"),
- IndexEntry(fromjson("{a: 1}"), "a_1"),
- IndexEntry(fromjson("{a: 1, b: 1}"), "a_1_b_1"),
- IndexEntry(fromjson("{a: 1, c: 1}"), "a_1_c_1")},
+ auto projExec = ProjectionExecAgg::create(
+ fromjson("{_id: 0}"),
+ ProjectionExecAgg::DefaultIdPolicy::kExcludeId,
+ ProjectionExecAgg::ArrayRecursionPolicy::kDoNotRecurseNestedArrays);
+ testAllowedIndices({buildWildcardIndexEntry(BSON("$**" << 1), projExec.get(), "$**_1"),
+ buildSimpleIndexEntry(fromjson("{a: 1}"), "a_1"),
+ buildSimpleIndexEntry(fromjson("{a: 1, b: 1}"), "a_1_b_1"),
+ buildSimpleIndexEntry(fromjson("{a: 1, c: 1}"), "a_1_c_1")},
SimpleBSONObjComparator::kInstance.makeBSONObjSet(),
{"$**_1"},
{"$**_1"});
}
TEST(GetExecutorTest, GetAllowedPathSpecifiedWildcardIndicesByKey) {
- testAllowedIndices({IndexEntry(BSON("a.$**" << 1), "a.$**_1"),
- IndexEntry(fromjson("{a: 1}"), "a_1"),
- IndexEntry(fromjson("{a: 1, b: 1}"), "a_1_b_1"),
- IndexEntry(fromjson("{a: 1, c: 1}"), "a_1_c_1")},
+ auto projExec = ProjectionExecAgg::create(
+ fromjson("{_id: 0}"),
+ ProjectionExecAgg::DefaultIdPolicy::kExcludeId,
+ ProjectionExecAgg::ArrayRecursionPolicy::kDoNotRecurseNestedArrays);
+ testAllowedIndices({buildWildcardIndexEntry(BSON("a.$**" << 1), projExec.get(), "a.$**_1"),
+ buildSimpleIndexEntry(fromjson("{a: 1}"), "a_1"),
+ buildSimpleIndexEntry(fromjson("{a: 1, b: 1}"), "a_1_b_1"),
+ buildSimpleIndexEntry(fromjson("{a: 1, c: 1}"), "a_1_c_1")},
SimpleBSONObjComparator::kInstance.makeBSONObjSet({BSON("a.$**" << 1)}),
stdx::unordered_set<std::string>{},
{"a.$**_1"});
}
TEST(GetExecutorTest, GetAllowedPathSpecifiedWildcardIndicesByName) {
- testAllowedIndices({IndexEntry(BSON("a.$**" << 1), "a.$**_1"),
- IndexEntry(fromjson("{a: 1}"), "a_1"),
- IndexEntry(fromjson("{a: 1, b: 1}"), "a_1_b_1"),
- IndexEntry(fromjson("{a: 1, c: 1}"), "a_1_c_1")},
+ auto projExec = ProjectionExecAgg::create(
+ fromjson("{_id: 0}"),
+ ProjectionExecAgg::DefaultIdPolicy::kExcludeId,
+ ProjectionExecAgg::ArrayRecursionPolicy::kDoNotRecurseNestedArrays);
+ testAllowedIndices({buildWildcardIndexEntry(BSON("a.$**" << 1), projExec.get(), "a.$**_1"),
+ buildSimpleIndexEntry(fromjson("{a: 1}"), "a_1"),
+ buildSimpleIndexEntry(fromjson("{a: 1, b: 1}"), "a_1_b_1"),
+ buildSimpleIndexEntry(fromjson("{a: 1, c: 1}"), "a_1_c_1")},
SimpleBSONObjComparator::kInstance.makeBSONObjSet(),
{"a.$**_1"},
{"a.$**_1"});
diff --git a/src/mongo/db/query/index_bounds_builder_test.cpp b/src/mongo/db/query/index_bounds_builder_test.cpp
index 0bb9f2638ee..25bc1c3f523 100644
--- a/src/mongo/db/query/index_bounds_builder_test.cpp
+++ b/src/mongo/db/query/index_bounds_builder_test.cpp
@@ -58,6 +58,25 @@ double positiveInfinity = numeric_limits<double>::infinity();
double NaN = numeric_limits<double>::quiet_NaN();
/**
+ * Make a minimal IndexEntry from just an optional key pattern. A dummy name will be added. An empty
+ * key pattern will be used if none is provided.
+ */
+IndexEntry buildSimpleIndexEntry(const BSONObj& kp = BSONObj()) {
+ return {kp,
+ IndexNames::nameToType(IndexNames::findPluginName(kp)),
+ false,
+ {},
+ {},
+ false,
+ false,
+ CoreIndexInfo::Identifier("test_foo"),
+ nullptr,
+ {},
+ nullptr,
+ nullptr};
+}
+
+/**
* Utility function to create MatchExpression
*/
MatchExpression* parseMatchExpression(const BSONObj& obj) {
@@ -75,7 +94,7 @@ MatchExpression* parseMatchExpression(const BSONObj& obj) {
void testTranslateAndUnion(const vector<BSONObj>& toUnion,
OrderedIntervalList* oilOut,
IndexBoundsBuilder::BoundsTightness* tightnessOut) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
for (vector<BSONObj>::const_iterator it = toUnion.begin(); it != toUnion.end(); ++it) {
unique_ptr<MatchExpression> expr(parseMatchExpression(*it));
@@ -95,7 +114,7 @@ void testTranslateAndUnion(const vector<BSONObj>& toUnion,
void testTranslateAndIntersect(const vector<BSONObj>& toIntersect,
OrderedIntervalList* oilOut,
IndexBoundsBuilder::BoundsTightness* tightnessOut) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
for (vector<BSONObj>::const_iterator it = toIntersect.begin(); it != toIntersect.end(); ++it) {
unique_ptr<MatchExpression> expr(parseMatchExpression(*it));
@@ -119,7 +138,7 @@ void testTranslateAndIntersect(const vector<BSONObj>& toIntersect,
void testTranslate(const vector<std::pair<BSONObj, bool>>& constraints,
OrderedIntervalList* oilOut,
IndexBoundsBuilder::BoundsTightness* tightnessOut) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
for (vector<std::pair<BSONObj, bool>>::const_iterator it = constraints.begin();
it != constraints.end();
@@ -156,7 +175,7 @@ bool testSingleInterval(IndexBounds bounds) {
//
TEST(IndexBoundsBuilderTest, TranslateElemMatchValue) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
// Bounds generated should be the same as the embedded expression
// except for the tightness.
BSONObj obj = fromjson("{a: {$elemMatch: {$gt: 2}}}");
@@ -178,7 +197,7 @@ TEST(IndexBoundsBuilderTest, TranslateElemMatchValue) {
//
TEST(IndexBoundsBuilderTest, TranslateLteNumber) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$lte: 1}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -194,7 +213,7 @@ TEST(IndexBoundsBuilderTest, TranslateLteNumber) {
}
TEST(IndexBoundsBuilderTest, TranslateLteNumberMin) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = BSON("a" << BSON("$lte" << numberMin));
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -210,7 +229,7 @@ TEST(IndexBoundsBuilderTest, TranslateLteNumberMin) {
}
TEST(IndexBoundsBuilderTest, TranslateLteNegativeInfinity) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$lte: -Infinity}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -226,7 +245,7 @@ TEST(IndexBoundsBuilderTest, TranslateLteNegativeInfinity) {
}
TEST(IndexBoundsBuilderTest, TranslateLteObject) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$lte: {b: 1}}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -241,7 +260,7 @@ TEST(IndexBoundsBuilderTest, TranslateLteObject) {
}
TEST(IndexBoundsBuilderTest, TranslateLteCode) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = BSON("a" << BSON("$lte" << BSONCode("function(){ return 0; }")));
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -257,7 +276,7 @@ TEST(IndexBoundsBuilderTest, TranslateLteCode) {
}
TEST(IndexBoundsBuilderTest, TranslateLteCodeWScope) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = BSON("a" << BSON("$lte" << BSONCodeWScope("this.b == c", BSON("c" << 1))));
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -274,7 +293,7 @@ TEST(IndexBoundsBuilderTest, TranslateLteCodeWScope) {
}
TEST(IndexBoundsBuilderTest, TranslateLteMinKey) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = BSON("a" << BSON("$lte" << MINKEY));
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -290,7 +309,7 @@ TEST(IndexBoundsBuilderTest, TranslateLteMinKey) {
}
TEST(IndexBoundsBuilderTest, TranslateLteMaxKey) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = BSON("a" << BSON("$lte" << MAXKEY));
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -306,7 +325,7 @@ TEST(IndexBoundsBuilderTest, TranslateLteMaxKey) {
}
TEST(IndexBoundsBuilderTest, TranslateLtNumber) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$lt: 1}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -322,7 +341,7 @@ TEST(IndexBoundsBuilderTest, TranslateLtNumber) {
}
TEST(IndexBoundsBuilderTest, TranslateLtNumberMin) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = BSON("a" << BSON("$lt" << numberMin));
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -338,7 +357,7 @@ TEST(IndexBoundsBuilderTest, TranslateLtNumberMin) {
}
TEST(IndexBoundsBuilderTest, TranslateLtNegativeInfinity) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$lt: -Infinity}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -351,7 +370,7 @@ TEST(IndexBoundsBuilderTest, TranslateLtNegativeInfinity) {
}
TEST(IndexBoundsBuilderTest, TranslateLtDate) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = BSON("a" << LT << Date_t::fromMillisSinceEpoch(5000));
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -367,7 +386,7 @@ TEST(IndexBoundsBuilderTest, TranslateLtDate) {
}
TEST(IndexBoundsBuilderTest, TranslateLtObject) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$lt: {b: 1}}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -383,7 +402,7 @@ TEST(IndexBoundsBuilderTest, TranslateLtObject) {
}
TEST(IndexBoundsBuilderTest, TranslateLtCode) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = BSON("a" << BSON("$lt" << BSONCode("function(){ return 0; }")));
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -399,7 +418,7 @@ TEST(IndexBoundsBuilderTest, TranslateLtCode) {
}
TEST(IndexBoundsBuilderTest, TranslateLtCodeWScope) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = BSON("a" << BSON("$lt" << BSONCodeWScope("this.b == c", BSON("c" << 1))));
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -417,7 +436,7 @@ TEST(IndexBoundsBuilderTest, TranslateLtCodeWScope) {
// Nothing can be less than MinKey so the resulting index bounds would be a useless empty range.
TEST(IndexBoundsBuilderTest, TranslateLtMinKeyDoesNotGenerateBounds) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = BSON("a" << BSON("$lt" << MINKEY));
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -430,7 +449,7 @@ TEST(IndexBoundsBuilderTest, TranslateLtMinKeyDoesNotGenerateBounds) {
}
TEST(IndexBoundsBuilderTest, TranslateLtMaxKey) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = BSON("a" << BSON("$lt" << MAXKEY));
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -446,7 +465,7 @@ TEST(IndexBoundsBuilderTest, TranslateLtMaxKey) {
}
TEST(IndexBoundsBuilderTest, TranslateGtTimestamp) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = BSON("a" << GT << Timestamp(2, 3));
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -465,7 +484,7 @@ TEST(IndexBoundsBuilderTest, TranslateGtTimestamp) {
}
TEST(IndexBoundsBuilderTest, TranslateGtNumber) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$gt: 1}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -481,7 +500,7 @@ TEST(IndexBoundsBuilderTest, TranslateGtNumber) {
}
TEST(IndexBoundsBuilderTest, TranslateGtNumberMax) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = BSON("a" << BSON("$gt" << numberMax));
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -497,7 +516,7 @@ TEST(IndexBoundsBuilderTest, TranslateGtNumberMax) {
}
TEST(IndexBoundsBuilderTest, TranslateGtPositiveInfinity) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$gt: Infinity}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -510,7 +529,7 @@ TEST(IndexBoundsBuilderTest, TranslateGtPositiveInfinity) {
}
TEST(IndexBoundsBuilderTest, TranslateGtString) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$gt: 'abc'}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -526,7 +545,7 @@ TEST(IndexBoundsBuilderTest, TranslateGtString) {
}
TEST(IndexBoundsBuilderTest, TranslateGtObject) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$gt: {b: 1}}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -542,7 +561,7 @@ TEST(IndexBoundsBuilderTest, TranslateGtObject) {
}
TEST(IndexBoundsBuilderTest, TranslateGtCode) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = BSON("a" << BSON("$gt" << BSONCode("function(){ return 0; }")));
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -558,7 +577,7 @@ TEST(IndexBoundsBuilderTest, TranslateGtCode) {
}
TEST(IndexBoundsBuilderTest, TranslateGtCodeWScope) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = BSON("a" << BSON("$gt" << BSONCodeWScope("this.b == c", BSON("c" << 1))));
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -574,7 +593,7 @@ TEST(IndexBoundsBuilderTest, TranslateGtCodeWScope) {
}
TEST(IndexBoundsBuilderTest, TranslateGtMinKey) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = BSON("a" << BSON("$gt" << MINKEY));
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -591,7 +610,7 @@ TEST(IndexBoundsBuilderTest, TranslateGtMinKey) {
// Nothing can be greater than MaxKey so the resulting index bounds would be a useless empty range.
TEST(IndexBoundsBuilderTest, TranslateGtMaxKeyDoesNotGenerateBounds) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = BSON("a" << BSON("$gt" << MAXKEY));
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -604,7 +623,7 @@ TEST(IndexBoundsBuilderTest, TranslateGtMaxKeyDoesNotGenerateBounds) {
}
TEST(IndexBoundsBuilderTest, TranslateGteNumber) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$gte: 1}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -620,7 +639,7 @@ TEST(IndexBoundsBuilderTest, TranslateGteNumber) {
}
TEST(IndexBoundsBuilderTest, TranslateGteNumberMax) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = BSON("a" << BSON("$gte" << numberMax));
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -636,7 +655,7 @@ TEST(IndexBoundsBuilderTest, TranslateGteNumberMax) {
}
TEST(IndexBoundsBuilderTest, TranslateGtePositiveInfinity) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$gte: Infinity}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -652,7 +671,7 @@ TEST(IndexBoundsBuilderTest, TranslateGtePositiveInfinity) {
}
TEST(IndexBoundsBuilderTest, TranslateGteObject) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$gte: {b: 1}}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -668,7 +687,7 @@ TEST(IndexBoundsBuilderTest, TranslateGteObject) {
}
TEST(IndexBoundsBuilderTest, TranslateGteCode) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = BSON("a" << BSON("$gte" << BSONCode("function(){ return 0; }")));
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -684,7 +703,7 @@ TEST(IndexBoundsBuilderTest, TranslateGteCode) {
}
TEST(IndexBoundsBuilderTest, TranslateGteCodeWScope) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = BSON("a" << BSON("$gte" << BSONCodeWScope("this.b == c", BSON("c" << 1))));
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -700,7 +719,7 @@ TEST(IndexBoundsBuilderTest, TranslateGteCodeWScope) {
}
TEST(IndexBoundsBuilderTest, TranslateGteMinKey) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = BSON("a" << BSON("$gte" << MINKEY));
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -716,7 +735,7 @@ TEST(IndexBoundsBuilderTest, TranslateGteMinKey) {
}
TEST(IndexBoundsBuilderTest, TranslateGteMaxKey) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = BSON("a" << BSON("$gte" << MAXKEY));
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -732,7 +751,7 @@ TEST(IndexBoundsBuilderTest, TranslateGteMaxKey) {
}
TEST(IndexBoundsBuilderTest, TranslateEqualNan) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: NaN}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -747,7 +766,7 @@ TEST(IndexBoundsBuilderTest, TranslateEqualNan) {
}
TEST(IndexBoundsBuilderTest, TranslateLtNan) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$lt: NaN}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -760,7 +779,7 @@ TEST(IndexBoundsBuilderTest, TranslateLtNan) {
}
TEST(IndexBoundsBuilderTest, TranslateLteNan) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$lte: NaN}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -775,7 +794,7 @@ TEST(IndexBoundsBuilderTest, TranslateLteNan) {
}
TEST(IndexBoundsBuilderTest, TranslateGtNan) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$gt: NaN}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -788,7 +807,7 @@ TEST(IndexBoundsBuilderTest, TranslateGtNan) {
}
TEST(IndexBoundsBuilderTest, TranslateGteNan) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$gte: NaN}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -803,7 +822,7 @@ TEST(IndexBoundsBuilderTest, TranslateGteNan) {
}
TEST(IndexBoundsBuilderTest, TranslateEqual) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = BSON("a" << 4);
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -820,7 +839,7 @@ TEST(IndexBoundsBuilderTest, TranslateEqual) {
TEST(IndexBoundsBuilderTest, TranslateExprEqual) {
BSONObj keyPattern = BSON("a" << 1);
BSONElement elt = keyPattern.firstElement();
- IndexEntry testIndex{keyPattern};
+ auto testIndex = buildSimpleIndexEntry(keyPattern);
BSONObj obj = BSON("a" << BSON("$_internalExprEq" << 4));
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
OrderedIntervalList oil;
@@ -837,7 +856,7 @@ TEST(IndexBoundsBuilderTest, TranslateExprEqualToStringRespectsCollation) {
BSONObj keyPattern = BSON("a" << 1);
BSONElement elt = keyPattern.firstElement();
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
- IndexEntry testIndex{keyPattern};
+ auto testIndex = buildSimpleIndexEntry(keyPattern);
testIndex.collator = &collator;
BSONObj obj = BSON("a" << BSON("$_internalExprEq"
@@ -857,7 +876,7 @@ TEST(IndexBoundsBuilderTest, TranslateExprEqualToStringRespectsCollation) {
TEST(IndexBoundsBuilderTest, TranslateExprEqualHashedIndex) {
BSONObj keyPattern = fromjson("{a: 'hashed'}");
BSONElement elt = keyPattern.firstElement();
- IndexEntry testIndex{keyPattern};
+ auto testIndex = buildSimpleIndexEntry(keyPattern);
BSONObj obj = BSON("a" << BSON("$_internalExprEq" << 4));
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
OrderedIntervalList oil;
@@ -880,7 +899,7 @@ TEST(IndexBoundsBuilderTest, TranslateExprEqualHashedIndex) {
TEST(IndexBoundsBuilderTest, TranslateExprEqualToNullIsInexactFetch) {
BSONObj keyPattern = BSON("a" << 1);
BSONElement elt = keyPattern.firstElement();
- IndexEntry testIndex{keyPattern};
+ auto testIndex = buildSimpleIndexEntry(keyPattern);
BSONObj obj = BSON("a" << BSON("$_internalExprEq" << BSONNULL));
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
OrderedIntervalList oil;
@@ -897,7 +916,7 @@ TEST(IndexBoundsBuilderTest, TranslateExprEqualToNullIsInexactFetch) {
}
TEST(IndexBoundsBuilderTest, TranslateArrayEqualBasic) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: [1, 2, 3]}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -915,7 +934,7 @@ TEST(IndexBoundsBuilderTest, TranslateArrayEqualBasic) {
}
TEST(IndexBoundsBuilderTest, TranslateIn) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$in: [8, 44, -1, -3]}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -936,7 +955,7 @@ TEST(IndexBoundsBuilderTest, TranslateIn) {
}
TEST(IndexBoundsBuilderTest, TranslateInArray) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$in: [[1], 2]}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -955,7 +974,7 @@ TEST(IndexBoundsBuilderTest, TranslateInArray) {
}
TEST(IndexBoundsBuilderTest, TranslateLteBinData) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson(
"{a: {$lte: {$binary: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAA',"
"$type: '00'}}}");
@@ -976,7 +995,7 @@ TEST(IndexBoundsBuilderTest, TranslateLteBinData) {
}
TEST(IndexBoundsBuilderTest, TranslateLtBinData) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson(
"{a: {$lt: {$binary: 'AAAAAAAAAAAAAAAAAAAAAAAAAAAA',"
"$type: '00'}}}");
@@ -997,7 +1016,7 @@ TEST(IndexBoundsBuilderTest, TranslateLtBinData) {
}
TEST(IndexBoundsBuilderTest, TranslateGtBinData) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson(
"{a: {$gt: {$binary: '////////////////////////////',"
"$type: '00'}}}");
@@ -1018,7 +1037,7 @@ TEST(IndexBoundsBuilderTest, TranslateGtBinData) {
}
TEST(IndexBoundsBuilderTest, TranslateGteBinData) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson(
"{a: {$gte: {$binary: '////////////////////////////',"
"$type: '00'}}}");
@@ -1043,7 +1062,7 @@ TEST(IndexBoundsBuilderTest, TranslateGteBinData) {
//
TEST(IndexBoundsBuilderTest, TypeNumber) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$type: 'number'}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -1070,7 +1089,7 @@ TEST(IndexBoundsBuilderTest, TypeNumber) {
//
TEST(IndexBoundsBuilderTest, ExistsTrue) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$exists: true}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -1085,7 +1104,7 @@ TEST(IndexBoundsBuilderTest, ExistsTrue) {
}
TEST(IndexBoundsBuilderTest, ExistsFalse) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$exists: false}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -1100,13 +1119,20 @@ TEST(IndexBoundsBuilderTest, ExistsFalse) {
}
TEST(IndexBoundsBuilderTest, ExistsTrueSparse) {
- IndexEntry testIndex = IndexEntry(BSONObj(),
- false, // multikey
- true, // sparse
- false, // unique
- IndexEntry::Identifier{"exists_true_sparse"},
- nullptr, // filterExpr
- BSONObj());
+ auto keyPattern = BSONObj();
+ IndexEntry testIndex =
+ IndexEntry(keyPattern,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
+ false, // multikey
+ {},
+ {},
+ true, // sparse
+ false, // unique
+ IndexEntry::Identifier{"exists_true_sparse"},
+ nullptr, // filterExpr
+ BSONObj(),
+ nullptr,
+ nullptr);
BSONObj obj = fromjson("{a: {$exists: true}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -1125,7 +1151,7 @@ TEST(IndexBoundsBuilderTest, ExistsTrueSparse) {
//
TEST(IndexBoundsBuilderTest, UnionTwoLt) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
vector<BSONObj> toUnion;
toUnion.push_back(fromjson("{a: {$lt: 1}}"));
toUnion.push_back(fromjson("{a: {$lt: 5}}"));
@@ -1141,7 +1167,7 @@ TEST(IndexBoundsBuilderTest, UnionTwoLt) {
}
TEST(IndexBoundsBuilderTest, UnionDupEq) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
vector<BSONObj> toUnion;
toUnion.push_back(fromjson("{a: 1}"));
toUnion.push_back(fromjson("{a: 5}"));
@@ -1159,7 +1185,7 @@ TEST(IndexBoundsBuilderTest, UnionDupEq) {
}
TEST(IndexBoundsBuilderTest, UnionGtLt) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
vector<BSONObj> toUnion;
toUnion.push_back(fromjson("{a: {$gt: 1}}"));
toUnion.push_back(fromjson("{a: {$lt: 3}}"));
@@ -1175,7 +1201,7 @@ TEST(IndexBoundsBuilderTest, UnionGtLt) {
}
TEST(IndexBoundsBuilderTest, UnionTwoEmptyRanges) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
vector<std::pair<BSONObj, bool>> constraints;
constraints.push_back(std::make_pair(fromjson("{a: {$gt: 1}}"), true));
constraints.push_back(std::make_pair(fromjson("{a: {$lte: 0}}"), true));
@@ -1192,7 +1218,7 @@ TEST(IndexBoundsBuilderTest, UnionTwoEmptyRanges) {
//
TEST(IndexBoundsBuilderTest, IntersectTwoLt) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
vector<BSONObj> toIntersect;
toIntersect.push_back(fromjson("{a: {$lt: 1}}"));
toIntersect.push_back(fromjson("{a: {$lt: 5}}"));
@@ -1208,7 +1234,7 @@ TEST(IndexBoundsBuilderTest, IntersectTwoLt) {
}
TEST(IndexBoundsBuilderTest, IntersectEqGte) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
vector<BSONObj> toIntersect;
toIntersect.push_back(fromjson("{a: 1}}"));
toIntersect.push_back(fromjson("{a: {$gte: 1}}"));
@@ -1223,7 +1249,7 @@ TEST(IndexBoundsBuilderTest, IntersectEqGte) {
}
TEST(IndexBoundsBuilderTest, IntersectGtLte) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
vector<BSONObj> toIntersect;
toIntersect.push_back(fromjson("{a: {$gt: 0}}"));
toIntersect.push_back(fromjson("{a: {$lte: 10}}"));
@@ -1238,7 +1264,7 @@ TEST(IndexBoundsBuilderTest, IntersectGtLte) {
}
TEST(IndexBoundsBuilderTest, IntersectGtIn) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
vector<BSONObj> toIntersect;
toIntersect.push_back(fromjson("{a: {$gt: 4}}"));
toIntersect.push_back(fromjson("{a: {$in: [1,2,3,4,5,6]}}"));
@@ -1255,7 +1281,7 @@ TEST(IndexBoundsBuilderTest, IntersectGtIn) {
}
TEST(IndexBoundsBuilderTest, IntersectionIsPointInterval) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
vector<BSONObj> toIntersect;
toIntersect.push_back(fromjson("{a: {$gte: 1}}"));
toIntersect.push_back(fromjson("{a: {$lte: 1}}"));
@@ -1270,7 +1296,7 @@ TEST(IndexBoundsBuilderTest, IntersectionIsPointInterval) {
}
TEST(IndexBoundsBuilderTest, IntersectFullyContained) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
vector<BSONObj> toIntersect;
toIntersect.push_back(fromjson("{a: {$gt: 5}}"));
toIntersect.push_back(fromjson("{a: {$lt: 15}}"));
@@ -1287,7 +1313,7 @@ TEST(IndexBoundsBuilderTest, IntersectFullyContained) {
}
TEST(IndexBoundsBuilderTest, EmptyIntersection) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
vector<BSONObj> toIntersect;
toIntersect.push_back(fromjson("{a: 1}}"));
toIntersect.push_back(fromjson("{a: {$gte: 2}}"));
@@ -1303,7 +1329,7 @@ TEST(IndexBoundsBuilderTest, EmptyIntersection) {
//
TEST(IndexBoundsBuilderTest, TranslateMod) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$mod: [2, 0]}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -1323,7 +1349,7 @@ TEST(IndexBoundsBuilderTest, TranslateMod) {
//
TEST(SimpleRegexTest, RootedLine) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
IndexBoundsBuilder::BoundsTightness tightness;
string prefix = IndexBoundsBuilder::simpleRegex("^foo", "", testIndex, &tightness);
ASSERT_EQUALS(prefix, "foo");
@@ -1331,7 +1357,7 @@ TEST(SimpleRegexTest, RootedLine) {
}
TEST(SimpleRegexTest, RootedString) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
IndexBoundsBuilder::BoundsTightness tightness;
string prefix = IndexBoundsBuilder::simpleRegex("\\Afoo", "", testIndex, &tightness);
ASSERT_EQUALS(prefix, "foo");
@@ -1339,7 +1365,7 @@ TEST(SimpleRegexTest, RootedString) {
}
TEST(SimpleRegexTest, RootedOptionalFirstChar) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
IndexBoundsBuilder::BoundsTightness tightness;
string prefix = IndexBoundsBuilder::simpleRegex("^f?oo", "", testIndex, &tightness);
ASSERT_EQUALS(prefix, "");
@@ -1347,7 +1373,7 @@ TEST(SimpleRegexTest, RootedOptionalFirstChar) {
}
TEST(SimpleRegexTest, RootedOptionalSecondChar) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
IndexBoundsBuilder::BoundsTightness tightness;
string prefix = IndexBoundsBuilder::simpleRegex("^fz?oo", "", testIndex, &tightness);
ASSERT_EQUALS(prefix, "f");
@@ -1355,7 +1381,7 @@ TEST(SimpleRegexTest, RootedOptionalSecondChar) {
}
TEST(SimpleRegexTest, RootedMultiline) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
IndexBoundsBuilder::BoundsTightness tightness;
string prefix = IndexBoundsBuilder::simpleRegex("^foo", "m", testIndex, &tightness);
ASSERT_EQUALS(prefix, "");
@@ -1363,7 +1389,7 @@ TEST(SimpleRegexTest, RootedMultiline) {
}
TEST(SimpleRegexTest, RootedStringMultiline) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
IndexBoundsBuilder::BoundsTightness tightness;
string prefix = IndexBoundsBuilder::simpleRegex("\\Afoo", "m", testIndex, &tightness);
ASSERT_EQUALS(prefix, "foo");
@@ -1371,7 +1397,7 @@ TEST(SimpleRegexTest, RootedStringMultiline) {
}
TEST(SimpleRegexTest, RootedCaseInsensitiveMulti) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
IndexBoundsBuilder::BoundsTightness tightness;
string prefix = IndexBoundsBuilder::simpleRegex("\\Afoo", "mi", testIndex, &tightness);
ASSERT_EQUALS(prefix, "");
@@ -1379,7 +1405,7 @@ TEST(SimpleRegexTest, RootedCaseInsensitiveMulti) {
}
TEST(SimpleRegexTest, RootedComplex) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
IndexBoundsBuilder::BoundsTightness tightness;
string prefix = IndexBoundsBuilder::simpleRegex(
"\\Af \t\vo\n\ro \\ \\# #comment", "mx", testIndex, &tightness);
@@ -1388,7 +1414,7 @@ TEST(SimpleRegexTest, RootedComplex) {
}
TEST(SimpleRegexTest, RootedLiteral) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
IndexBoundsBuilder::BoundsTightness tightness;
string prefix = IndexBoundsBuilder::simpleRegex("^\\Qasdf\\E", "", testIndex, &tightness);
ASSERT_EQUALS(prefix, "asdf");
@@ -1396,7 +1422,7 @@ TEST(SimpleRegexTest, RootedLiteral) {
}
TEST(SimpleRegexTest, RootedLiteralWithExtra) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
IndexBoundsBuilder::BoundsTightness tightness;
string prefix = IndexBoundsBuilder::simpleRegex("^\\Qasdf\\E.*", "", testIndex, &tightness);
ASSERT_EQUALS(prefix, "asdf");
@@ -1404,7 +1430,7 @@ TEST(SimpleRegexTest, RootedLiteralWithExtra) {
}
TEST(SimpleRegexTest, RootedLiteralNoEnd) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
IndexBoundsBuilder::BoundsTightness tightness;
string prefix = IndexBoundsBuilder::simpleRegex("^\\Qasdf", "", testIndex, &tightness);
ASSERT_EQUALS(prefix, "asdf");
@@ -1412,7 +1438,7 @@ TEST(SimpleRegexTest, RootedLiteralNoEnd) {
}
TEST(SimpleRegexTest, RootedLiteralBackslash) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
IndexBoundsBuilder::BoundsTightness tightness;
string prefix = IndexBoundsBuilder::simpleRegex("^\\Qasdf\\\\E", "", testIndex, &tightness);
ASSERT_EQUALS(prefix, "asdf\\");
@@ -1420,7 +1446,7 @@ TEST(SimpleRegexTest, RootedLiteralBackslash) {
}
TEST(SimpleRegexTest, RootedLiteralDotStar) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
IndexBoundsBuilder::BoundsTightness tightness;
string prefix = IndexBoundsBuilder::simpleRegex("^\\Qas.*df\\E", "", testIndex, &tightness);
ASSERT_EQUALS(prefix, "as.*df");
@@ -1428,7 +1454,7 @@ TEST(SimpleRegexTest, RootedLiteralDotStar) {
}
TEST(SimpleRegexTest, RootedLiteralNestedEscape) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
IndexBoundsBuilder::BoundsTightness tightness;
string prefix = IndexBoundsBuilder::simpleRegex("^\\Qas\\Q[df\\E", "", testIndex, &tightness);
ASSERT_EQUALS(prefix, "as\\Q[df");
@@ -1436,7 +1462,7 @@ TEST(SimpleRegexTest, RootedLiteralNestedEscape) {
}
TEST(SimpleRegexTest, RootedLiteralNestedEscapeEnd) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
IndexBoundsBuilder::BoundsTightness tightness;
string prefix =
IndexBoundsBuilder::simpleRegex("^\\Qas\\E\\\\E\\Q$df\\E", "", testIndex, &tightness);
@@ -1447,7 +1473,7 @@ TEST(SimpleRegexTest, RootedLiteralNestedEscapeEnd) {
// An anchored regular expression that uses the "|" operator is not considered "simple" and has
// non-tight index bounds.
TEST(SimpleRegexTest, PipeCharacterUsesInexactBounds) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
IndexBoundsBuilder::BoundsTightness tightness;
string prefix = IndexBoundsBuilder::simpleRegex("^(a(a|$)|b", "", testIndex, &tightness);
ASSERT_EQUALS(prefix, "");
@@ -1455,7 +1481,7 @@ TEST(SimpleRegexTest, PipeCharacterUsesInexactBounds) {
}
TEST(SimpleRegexTest, PipeCharacterUsesInexactBoundsWithTwoPrefixes) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
IndexBoundsBuilder::BoundsTightness tightness;
string prefix = IndexBoundsBuilder::simpleRegex("^(a(a|$)|^b", "", testIndex, &tightness);
ASSERT_EQUALS(prefix, "");
@@ -1463,7 +1489,7 @@ TEST(SimpleRegexTest, PipeCharacterUsesInexactBoundsWithTwoPrefixes) {
}
TEST(SimpleRegexTest, PipeCharacterPrecededByEscapedBackslashUsesInexactBounds) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
IndexBoundsBuilder::BoundsTightness tightness;
string prefix = IndexBoundsBuilder::simpleRegex(R"(^a\\|b)", "", testIndex, &tightness);
ASSERT_EQUALS(prefix, "");
@@ -1477,7 +1503,7 @@ TEST(SimpleRegexTest, PipeCharacterPrecededByEscapedBackslashUsesInexactBounds)
// However, a regular expression with an escaped pipe (that is, using no special meaning) can use
// exact index bounds.
TEST(SimpleRegexTest, PipeCharacterEscapedWithBackslashUsesExactBounds) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
IndexBoundsBuilder::BoundsTightness tightness;
string prefix = IndexBoundsBuilder::simpleRegex(R"(^a\|b)", "", testIndex, &tightness);
ASSERT_EQUALS(prefix, "a|b");
@@ -1489,7 +1515,7 @@ TEST(SimpleRegexTest, PipeCharacterEscapedWithBackslashUsesExactBounds) {
}
TEST(SimpleRegexTest, FalsePositiveOnPipeInQEEscapeSequenceUsesInexactBounds) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
IndexBoundsBuilder::BoundsTightness tightness;
string prefix = IndexBoundsBuilder::simpleRegex(R"(^\Q|\E)", "", testIndex, &tightness);
ASSERT_EQUALS(prefix, "");
@@ -1497,7 +1523,7 @@ TEST(SimpleRegexTest, FalsePositiveOnPipeInQEEscapeSequenceUsesInexactBounds) {
}
TEST(SimpleRegexTest, FalsePositiveOnPipeInCharacterClassUsesInexactBounds) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
IndexBoundsBuilder::BoundsTightness tightness;
string prefix = IndexBoundsBuilder::simpleRegex(R"(^[|])", "", testIndex, &tightness);
ASSERT_EQUALS(prefix, "");
@@ -1506,7 +1532,7 @@ TEST(SimpleRegexTest, FalsePositiveOnPipeInCharacterClassUsesInexactBounds) {
// SERVER-9035
TEST(SimpleRegexTest, RootedSingleLineMode) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
IndexBoundsBuilder::BoundsTightness tightness;
string prefix = IndexBoundsBuilder::simpleRegex("^foo", "s", testIndex, &tightness);
ASSERT_EQUALS(prefix, "foo");
@@ -1515,7 +1541,7 @@ TEST(SimpleRegexTest, RootedSingleLineMode) {
// SERVER-9035
TEST(SimpleRegexTest, NonRootedSingleLineMode) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
IndexBoundsBuilder::BoundsTightness tightness;
string prefix = IndexBoundsBuilder::simpleRegex("foo", "s", testIndex, &tightness);
ASSERT_EQUALS(prefix, "");
@@ -1524,7 +1550,7 @@ TEST(SimpleRegexTest, NonRootedSingleLineMode) {
// SERVER-9035
TEST(SimpleRegexTest, RootedComplexSingleLineMode) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
IndexBoundsBuilder::BoundsTightness tightness;
string prefix = IndexBoundsBuilder::simpleRegex(
"\\Af \t\vo\n\ro \\ \\# #comment", "msx", testIndex, &tightness);
@@ -1534,7 +1560,7 @@ TEST(SimpleRegexTest, RootedComplexSingleLineMode) {
TEST(SimpleRegexTest, RootedRegexCantBeIndexedTightlyIfIndexHasCollation) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
testIndex.collator = &collator;
IndexBoundsBuilder::BoundsTightness tightness;
@@ -1548,7 +1574,7 @@ TEST(SimpleRegexTest, RootedRegexCantBeIndexedTightlyIfIndexHasCollation) {
//
TEST(IndexBoundsBuilderTest, SimpleNonPrefixRegex) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: /foo/}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -1565,7 +1591,7 @@ TEST(IndexBoundsBuilderTest, SimpleNonPrefixRegex) {
}
TEST(IndexBoundsBuilderTest, NonSimpleRegexWithPipe) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: /^foo.*|bar/}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -1582,7 +1608,7 @@ TEST(IndexBoundsBuilderTest, NonSimpleRegexWithPipe) {
}
TEST(IndexBoundsBuilderTest, SimpleRegexSingleLineMode) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: /^foo/s}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -1600,7 +1626,7 @@ TEST(IndexBoundsBuilderTest, SimpleRegexSingleLineMode) {
}
TEST(IndexBoundsBuilderTest, SimplePrefixRegex) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: /^foo/}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -1831,7 +1857,7 @@ BSONObj maxKeyIntObj(int start) {
// Expected oil: [MinKey, 3), (3, MaxKey]
TEST(IndexBoundsBuilderTest, SimpleNE) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = BSON("a" << BSON("$ne" << 3));
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -1848,7 +1874,7 @@ TEST(IndexBoundsBuilderTest, SimpleNE) {
}
TEST(IndexBoundsBuilderTest, IntersectWithNE) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
vector<BSONObj> toIntersect;
toIntersect.push_back(fromjson("{a: {$gt: 1}}"));
toIntersect.push_back(fromjson("{a: {$ne: 2}}}"));
@@ -1866,7 +1892,7 @@ TEST(IndexBoundsBuilderTest, IntersectWithNE) {
}
TEST(IndexBoundsBuilderTest, UnionizeWithNE) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
vector<BSONObj> toUnionize;
toUnionize.push_back(fromjson("{a: {$ne: 3}}"));
toUnionize.push_back(fromjson("{a: {$ne: 4}}}"));
@@ -1882,7 +1908,7 @@ TEST(IndexBoundsBuilderTest, UnionizeWithNE) {
// Test $type bounds for Code BSON type.
TEST(IndexBoundsBuilderTest, CodeTypeBounds) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$type: 13}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -1907,7 +1933,7 @@ TEST(IndexBoundsBuilderTest, CodeTypeBounds) {
// Test $type bounds for Code With Scoped BSON type.
TEST(IndexBoundsBuilderTest, CodeWithScopeTypeBounds) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$type: 15}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -1932,7 +1958,7 @@ TEST(IndexBoundsBuilderTest, CodeWithScopeTypeBounds) {
// Test $type bounds for double BSON type.
TEST(IndexBoundsBuilderTest, DoubleTypeBounds) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$type: 1}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -1956,7 +1982,7 @@ TEST(IndexBoundsBuilderTest, DoubleTypeBounds) {
}
TEST(IndexBoundsBuilderTest, TypeArrayBounds) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$type: 'array'}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -1979,7 +2005,7 @@ TEST(IndexBoundsBuilderTest, TypeArrayBounds) {
TEST(IndexBoundsBuilderTest, TranslateEqualityToStringWithMockCollator) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
testIndex.collator = &collator;
BSONObj obj = BSON("a"
@@ -2001,7 +2027,7 @@ TEST(IndexBoundsBuilderTest, TranslateEqualityToStringWithMockCollator) {
TEST(IndexBoundsBuilderTest, TranslateEqualityToNonStringWithMockCollator) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
testIndex.collator = &collator;
BSONObj obj = BSON("a" << 3);
@@ -2033,7 +2059,7 @@ void assertBoundsRepresentEqualsNull(const OrderedIntervalList& oil) {
TEST(IndexBoundsBuilderTest, TranslateEqualsToNullShouldBuildInexactBounds) {
BSONObj indexPattern = BSON("a" << 1);
- IndexEntry testIndex(indexPattern);
+ auto testIndex = buildSimpleIndexEntry(indexPattern);
BSONObj obj = BSON("a" << BSONNULL);
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
@@ -2050,7 +2076,7 @@ TEST(IndexBoundsBuilderTest, TranslateEqualsToNullShouldBuildInexactBounds) {
TEST(IndexBoundsBuilderTest, TranslateDottedEqualsToNullShouldBuildInexactBounds) {
BSONObj indexPattern = BSON("a.b" << 1);
- IndexEntry testIndex(indexPattern);
+ auto testIndex = buildSimpleIndexEntry(indexPattern);
BSONObj obj = BSON("a.b" << BSONNULL);
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
@@ -2067,7 +2093,7 @@ TEST(IndexBoundsBuilderTest, TranslateDottedEqualsToNullShouldBuildInexactBounds
TEST(IndexBoundsBuilderTest, TranslateEqualsToNullMultiKeyShouldBuildInexactBounds) {
BSONObj indexPattern = BSON("a" << 1);
- IndexEntry testIndex(indexPattern);
+ auto testIndex = buildSimpleIndexEntry(indexPattern);
testIndex.multikey = true;
BSONObj obj = BSON("a" << BSONNULL);
@@ -2086,7 +2112,7 @@ TEST(IndexBoundsBuilderTest, TranslateEqualsToNullMultiKeyShouldBuildInexactBoun
TEST(IndexBoundsBuilderTest, TranslateEqualsToNullShouldBuildTwoIntervalsForHashedIndex) {
BSONObj indexPattern = BSON("a"
<< "hashed");
- IndexEntry testIndex(indexPattern);
+ auto testIndex = buildSimpleIndexEntry(indexPattern);
testIndex.type = IndexType::INDEX_HASHED;
BSONObj obj = BSON("a" << BSONNULL);
@@ -2153,7 +2179,7 @@ void assertBoundsRepresentNotEqualsNull(const OrderedIntervalList& oil) {
TEST(IndexBoundsBuilderTest, TranslateNotEqualToNullShouldBuildExactBoundsIfIndexIsNotMultiKey) {
BSONObj indexPattern = BSON("a" << 1);
- IndexEntry testIndex(indexPattern);
+ auto testIndex = buildSimpleIndexEntry(indexPattern);
BSONObj obj = BSON("a" << BSON("$ne" << BSONNULL));
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
@@ -2172,7 +2198,7 @@ TEST(IndexBoundsBuilderTest, TranslateNotEqualToNullShouldBuildExactBoundsIfInde
TEST(IndexBoundsBuilderTest,
TranslateNotEqualToNullShouldBuildExactBoundsIfIndexIsNotMultiKeyOnRelevantPath) {
BSONObj indexPattern = BSON("a" << 1 << "b" << 1);
- IndexEntry testIndex(indexPattern);
+ auto testIndex = buildSimpleIndexEntry(indexPattern);
testIndex.multikeyPaths = {{}, {0}}; // "a" is not multi-key, but "b" is.
BSONObj obj = BSON("a" << BSON("$ne" << BSONNULL));
@@ -2191,7 +2217,7 @@ TEST(IndexBoundsBuilderTest,
TEST(IndexBoundsBuilderTest, TranslateNotEqualToNullShouldBuildExactBoundsOnReverseIndex) {
BSONObj indexPattern = BSON("a" << -1);
- IndexEntry testIndex(indexPattern);
+ auto testIndex = buildSimpleIndexEntry(indexPattern);
BSONObj obj = BSON("a" << BSON("$ne" << BSONNULL));
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
@@ -2209,7 +2235,7 @@ TEST(IndexBoundsBuilderTest, TranslateNotEqualToNullShouldBuildExactBoundsOnReve
TEST(IndexBoundsBuilderTest, TranslateNotEqualToNullShouldBuildInexactBoundsIfIndexIsMultiKey) {
BSONObj indexPattern = BSON("a" << 1);
- IndexEntry testIndex(indexPattern);
+ auto testIndex = buildSimpleIndexEntry(indexPattern);
testIndex.multikey = true;
BSONObj matchObj = BSON("a" << BSON("$ne" << BSONNULL));
@@ -2228,7 +2254,7 @@ TEST(IndexBoundsBuilderTest, TranslateNotEqualToNullShouldBuildInexactBoundsIfIn
TEST(IndexBoundsBuilderTest,
TranslateDottedElemMatchValueNotEqualToNullShouldBuildExactBoundsIfIsMultiKeyOnThatPath) {
BSONObj indexPattern = BSON("a.b" << 1);
- IndexEntry testIndex(indexPattern);
+ auto testIndex = buildSimpleIndexEntry(indexPattern);
testIndex.multikeyPaths = {{1}}; // "a.b" is multikey.
BSONObj matchObj = BSON("a.b" << BSON("$elemMatch" << BSON("$ne" << BSONNULL)));
@@ -2247,7 +2273,7 @@ TEST(IndexBoundsBuilderTest,
TEST(IndexBoundsBuilderTest,
TranslateDottedFieldNotEqualToNullShouldBuildInexactBoundsIfIndexIsMultiKey) {
BSONObj indexPattern = BSON("a.b" << 1);
- IndexEntry testIndex(indexPattern);
+ auto testIndex = buildSimpleIndexEntry(indexPattern);
testIndex.multikey = true;
BSONObj matchObj = BSON("a.b" << BSON("$ne" << BSONNULL));
@@ -2266,7 +2292,7 @@ TEST(IndexBoundsBuilderTest,
TEST(IndexBoundsBuilderTest,
TranslateElemMatchValueNotEqualToNullShouldBuildInexactBoundsIfIndexIsMultiKey) {
BSONObj indexPattern = BSON("a" << 1);
- IndexEntry testIndex(indexPattern);
+ auto testIndex = buildSimpleIndexEntry(indexPattern);
testIndex.multikey = true;
BSONObj obj = BSON("a" << BSON("$elemMatch" << BSON("$ne" << BSONNULL)));
@@ -2285,7 +2311,7 @@ TEST(IndexBoundsBuilderTest,
TEST(IndexBoundsBuilderTest,
TranslateElemMatchValueNotEqualToNullShouldBuildInExactBoundsIfIndexIsNotMultiKey) {
BSONObj indexPattern = BSON("a" << 1);
- IndexEntry testIndex(indexPattern);
+ auto testIndex = buildSimpleIndexEntry(indexPattern);
BSONObj matchObj = BSON("a" << BSON("$elemMatch" << BSON("$ne" << BSONNULL)));
unique_ptr<MatchExpression> expr(parseMatchExpression(matchObj));
@@ -2302,7 +2328,7 @@ TEST(IndexBoundsBuilderTest,
TEST(IndexBoundsBuilderTest, TranslateNotEqualToStringWithMockCollator) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
testIndex.collator = &collator;
BSONObj obj = BSON("a" << BSON("$ne"
@@ -2338,7 +2364,7 @@ TEST(IndexBoundsBuilderTest, TranslateNotEqualToStringWithMockCollator) {
TEST(IndexBoundsBuilderTest, TranslateEqualToStringElemMatchValueWithMockCollator) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
testIndex.collator = &collator;
BSONObj obj = fromjson("{a: {$elemMatch: {$eq: 'baz'}}}");
@@ -2359,7 +2385,7 @@ TEST(IndexBoundsBuilderTest, TranslateEqualToStringElemMatchValueWithMockCollato
TEST(IndexBoundsBuilderTest, TranslateLTEToStringWithMockCollator) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
testIndex.collator = &collator;
BSONObj obj = fromjson("{a: {$lte: 'foo'}}");
@@ -2379,7 +2405,7 @@ TEST(IndexBoundsBuilderTest, TranslateLTEToStringWithMockCollator) {
TEST(IndexBoundsBuilderTest, TranslateLTEToNumberWithMockCollator) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
testIndex.collator = &collator;
BSONObj obj = fromjson("{a: {$lte: 3}}");
@@ -2400,7 +2426,7 @@ TEST(IndexBoundsBuilderTest, TranslateLTEToNumberWithMockCollator) {
TEST(IndexBoundsBuilderTest, TranslateLTStringWithMockCollator) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
testIndex.collator = &collator;
BSONObj obj = fromjson("{a: {$lt: 'foo'}}");
@@ -2420,7 +2446,7 @@ TEST(IndexBoundsBuilderTest, TranslateLTStringWithMockCollator) {
TEST(IndexBoundsBuilderTest, TranslateLTNumberWithMockCollator) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
testIndex.collator = &collator;
BSONObj obj = fromjson("{a: {$lt: 3}}");
@@ -2441,7 +2467,7 @@ TEST(IndexBoundsBuilderTest, TranslateLTNumberWithMockCollator) {
TEST(IndexBoundsBuilderTest, TranslateGTStringWithMockCollator) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
testIndex.collator = &collator;
BSONObj obj = fromjson("{a: {$gt: 'foo'}}");
@@ -2462,7 +2488,7 @@ TEST(IndexBoundsBuilderTest, TranslateGTStringWithMockCollator) {
TEST(IndexBoundsBuilderTest, TranslateGTNumberWithMockCollator) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
testIndex.collator = &collator;
BSONObj obj = fromjson("{a: {$gt: 3}}");
@@ -2483,7 +2509,7 @@ TEST(IndexBoundsBuilderTest, TranslateGTNumberWithMockCollator) {
TEST(IndexBoundsBuilderTest, TranslateGTEToStringWithMockCollator) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
testIndex.collator = &collator;
BSONObj obj = fromjson("{a: {$gte: 'foo'}}");
@@ -2503,7 +2529,7 @@ TEST(IndexBoundsBuilderTest, TranslateGTEToStringWithMockCollator) {
TEST(IndexBoundsBuilderTest, TranslateGTEToNumberWithMockCollator) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
testIndex.collator = &collator;
BSONObj obj = fromjson("{a: {$gte: 3}}");
@@ -2524,7 +2550,7 @@ TEST(IndexBoundsBuilderTest, TranslateGTEToNumberWithMockCollator) {
TEST(IndexBoundsBuilderTest, SimplePrefixRegexWithMockCollator) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
testIndex.collator = &collator;
BSONObj obj = fromjson("{a: /^foo/}");
@@ -2546,7 +2572,7 @@ TEST(IndexBoundsBuilderTest, SimplePrefixRegexWithMockCollator) {
TEST(IndexBoundsBuilderTest, NotWithMockCollatorIsExact) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
testIndex.collator = &collator;
BSONObj obj = fromjson("{a: {$ne: 3}}");
@@ -2567,7 +2593,7 @@ TEST(IndexBoundsBuilderTest, NotWithMockCollatorIsExact) {
TEST(IndexBoundsBuilderTest, ExistsTrueWithMockCollatorAndSparseIsExact) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
testIndex.collator = &collator;
testIndex.sparse = true;
@@ -2588,7 +2614,7 @@ TEST(IndexBoundsBuilderTest, ExistsTrueWithMockCollatorAndSparseIsExact) {
TEST(IndexBoundsBuilderTest, ExistsFalseWithMockCollatorIsInexactFetch) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
testIndex.collator = &collator;
BSONObj obj = fromjson("{a: {$exists: false}}");
@@ -2608,7 +2634,7 @@ TEST(IndexBoundsBuilderTest, ExistsFalseWithMockCollatorIsInexactFetch) {
TEST(IndexBoundsBuilderTest, TypeStringIsInexactFetch) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
testIndex.collator = &collator;
BSONObj obj = fromjson("{a: {$type: 'string'}}");
@@ -2628,7 +2654,7 @@ TEST(IndexBoundsBuilderTest, TypeStringIsInexactFetch) {
TEST(IndexBoundsBuilderTest, InWithStringAndCollatorIsExact) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
testIndex.collator = &collator;
BSONObj obj = fromjson("{a: {$in: ['foo']}}");
@@ -2649,7 +2675,7 @@ TEST(IndexBoundsBuilderTest, InWithStringAndCollatorIsExact) {
TEST(IndexBoundsBuilderTest, InWithNumberAndStringAndCollatorIsExact) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
testIndex.collator = &collator;
BSONObj obj = fromjson("{a: {$in: [2, 'foo']}}");
@@ -2672,7 +2698,7 @@ TEST(IndexBoundsBuilderTest, InWithNumberAndStringAndCollatorIsExact) {
TEST(IndexBoundsBuilderTest, InWithRegexAndCollatorIsInexactFetch) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
testIndex.collator = &collator;
BSONObj obj = fromjson("{a: {$in: [/^foo/]}}");
@@ -2694,7 +2720,7 @@ TEST(IndexBoundsBuilderTest, InWithRegexAndCollatorIsInexactFetch) {
TEST(IndexBoundsBuilderTest, InWithNumberAndCollatorIsExact) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
testIndex.collator = &collator;
BSONObj obj = fromjson("{a: {$in: [2]}}");
@@ -2713,7 +2739,7 @@ TEST(IndexBoundsBuilderTest, InWithNumberAndCollatorIsExact) {
TEST(IndexBoundsBuilderTest, LTEMaxKeyWithCollator) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
testIndex.collator = &collator;
BSONObj obj = fromjson("{a: {$lte: {$maxKey: 1}}}");
@@ -2733,7 +2759,7 @@ TEST(IndexBoundsBuilderTest, LTEMaxKeyWithCollator) {
TEST(IndexBoundsBuilderTest, LTMaxKeyWithCollator) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
testIndex.collator = &collator;
BSONObj obj = fromjson("{a: {$lt: {$maxKey: 1}}}");
@@ -2753,7 +2779,7 @@ TEST(IndexBoundsBuilderTest, LTMaxKeyWithCollator) {
TEST(IndexBoundsBuilderTest, GTEMinKeyWithCollator) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
testIndex.collator = &collator;
BSONObj obj = fromjson("{a: {$gte: {$minKey: 1}}}");
@@ -2773,7 +2799,7 @@ TEST(IndexBoundsBuilderTest, GTEMinKeyWithCollator) {
TEST(IndexBoundsBuilderTest, GTMinKeyWithCollator) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
testIndex.collator = &collator;
BSONObj obj = fromjson("{a: {$gt: {$minKey: 1}}}");
@@ -2795,7 +2821,7 @@ TEST(IndexBoundsBuilderTest, StringEqualityAgainstHashedIndexWithCollatorUsesHas
BSONObj keyPattern = fromjson("{a: 'hashed'}");
BSONElement elt = keyPattern.firstElement();
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
- IndexEntry testIndex = IndexEntry(keyPattern);
+ auto testIndex = buildSimpleIndexEntry(keyPattern);
testIndex.collator = &collator;
BSONObj obj = fromjson("{a: 'foo'}");
@@ -2824,7 +2850,7 @@ TEST(IndexBoundsBuilderTest, EqualityToNumberAgainstHashedIndexWithCollatorUsesH
BSONObj keyPattern = fromjson("{a: 'hashed'}");
BSONElement elt = keyPattern.firstElement();
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
- IndexEntry testIndex = IndexEntry(keyPattern);
+ auto testIndex = buildSimpleIndexEntry(keyPattern);
testIndex.collator = &collator;
BSONObj obj = fromjson("{a: 3}");
@@ -2851,7 +2877,7 @@ TEST(IndexBoundsBuilderTest, InWithStringAgainstHashedIndexWithCollatorUsesHashO
BSONObj keyPattern = fromjson("{a: 'hashed'}");
BSONElement elt = keyPattern.firstElement();
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
- IndexEntry testIndex = IndexEntry(keyPattern);
+ auto testIndex = buildSimpleIndexEntry(keyPattern);
testIndex.collator = &collator;
BSONObj obj = fromjson("{a: {$in: ['foo']}}");
@@ -2877,7 +2903,7 @@ TEST(IndexBoundsBuilderTest, InWithStringAgainstHashedIndexWithCollatorUsesHashO
}
TEST(IndexBoundsBuilderTest, TypeArrayWithAdditionalTypesHasOpenBounds) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$type: ['array', 'long']}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -2894,7 +2920,7 @@ TEST(IndexBoundsBuilderTest, TypeArrayWithAdditionalTypesHasOpenBounds) {
}
TEST(IndexBoundsBuilderTest, TypeStringOrNumberHasCorrectBounds) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$type: ['string', 'number']}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -2914,7 +2940,7 @@ TEST(IndexBoundsBuilderTest, TypeStringOrNumberHasCorrectBounds) {
}
TEST(IndexBoundsBuilderTest, RedundantTypeNumberHasCorrectBounds) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$type: ['number', 'int', 'long', 'double']}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
BSONElement elt = obj.firstElement();
@@ -2932,49 +2958,49 @@ TEST(IndexBoundsBuilderTest, RedundantTypeNumberHasCorrectBounds) {
}
TEST(IndexBoundsBuilderTest, CanUseCoveredMatchingForEqualityPredicate) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$eq: 3}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
ASSERT_TRUE(IndexBoundsBuilder::canUseCoveredMatching(expr.get(), testIndex));
}
TEST(IndexBoundsBuilderTest, CannotUseCoveredMatchingForEqualityToArrayPredicate) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$eq: [1, 2, 3]}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
ASSERT_FALSE(IndexBoundsBuilder::canUseCoveredMatching(expr.get(), testIndex));
}
TEST(IndexBoundsBuilderTest, CannotUseCoveredMatchingForEqualityToNullPredicate) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: null}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
ASSERT_FALSE(IndexBoundsBuilder::canUseCoveredMatching(expr.get(), testIndex));
}
TEST(IndexBoundsBuilderTest, CannotUseCoveredMatchingForTypeArrayPredicate) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$type: 'array'}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
ASSERT_FALSE(IndexBoundsBuilder::canUseCoveredMatching(expr.get(), testIndex));
}
TEST(IndexBoundsBuilderTest, CannotUseCoveredMatchingForExistsTruePredicate) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$exists: true}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
ASSERT_FALSE(IndexBoundsBuilder::canUseCoveredMatching(expr.get(), testIndex));
}
TEST(IndexBoundsBuilderTest, CannotUseCoveredMatchingForExistsFalsePredicate) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
BSONObj obj = fromjson("{a: {$exists: false}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
ASSERT_FALSE(IndexBoundsBuilder::canUseCoveredMatching(expr.get(), testIndex));
}
TEST(IndexBoundsBuilderTest, CanUseCoveredMatchingForExistsTrueWithSparseIndex) {
- IndexEntry testIndex = IndexEntry(BSONObj());
+ auto testIndex = buildSimpleIndexEntry();
testIndex.sparse = true;
BSONObj obj = fromjson("{a: {$exists: true}}");
unique_ptr<MatchExpression> expr(parseMatchExpression(obj));
diff --git a/src/mongo/db/query/index_entry.h b/src/mongo/db/query/index_entry.h
index a2c9bd555d1..9760fe97ae1 100644
--- a/src/mongo/db/query/index_entry.h
+++ b/src/mongo/db/query/index_entry.h
@@ -46,9 +46,31 @@ class CollatorInterface;
class MatchExpression;
/**
- * This name sucks, but every name involving 'index' is used somewhere.
+ * A CoreIndexInfo is a representation of an index in the catalog with parsed information which is
+ * used for updating indexability discriminators. Its lifetime is not tied to the underlying
+ * collection. It is a subset of IndexEntry and is missing fields that are expensive or unavailable.
*/
-struct IndexEntry {
+struct CoreIndexInfo {
+
+ struct Identifier;
+
+ CoreIndexInfo(const BSONObj& kp,
+ IndexType type,
+ bool sp,
+ Identifier ident,
+ const MatchExpression* fe = nullptr,
+ const CollatorInterface* ci = nullptr,
+ const ProjectionExecAgg* projExec = nullptr)
+ : identifier(std::move(ident)),
+ keyPattern(kp),
+ filterExpr(fe),
+ type(type),
+ sparse(sp),
+ collator(ci),
+ wildcardProjection(projExec) {
+ // We always expect a projection executor for $** indexes, and none otherwise.
+ invariant((type == IndexType::INDEX_WILDCARD) == (projExec != nullptr));
+ }
/**
* This struct is used to uniquely identify an index. The index "Identifier" has two
@@ -92,11 +114,35 @@ struct IndexEntry {
// A string used for disambiguating multiple IndexEntries with the same catalogName (such
// as in the case with a wildcard index).
std::string disambiguator;
- };
+ } identifier;
- /**
- * Use this constructor if you're making an IndexEntry from the catalog.
- */
+ BSONObj keyPattern;
+
+ const MatchExpression* filterExpr;
+
+ // What type of index is this? (What access method can we use on the index described by the
+ // keyPattern?)
+ IndexType type;
+
+ bool sparse;
+
+ // Null if this index orders strings according to the simple binary compare. If non-null,
+ // represents the collator used to generate index keys for indexed strings.
+ const CollatorInterface* collator = nullptr;
+
+ // For $** indexes, a pointer to the projection executor owned by the index access method. Null
+ // unless this IndexEntry represents a wildcard index, in which case this is always non-null.
+ const ProjectionExecAgg* wildcardProjection = nullptr;
+};
+
+/**
+ * An IndexEntry is a representation of an index in the catalog with parsed information which is
+ * helpful for query planning. Its lifetime is not tied to the underlying collection. In contrast
+ * to CoreIndexInfo, it includes information such as 'multikeyPaths' which can require resources to
+ * compute (i.e. for wildcard indexes, this requires reading the index) and so may not always be
+ * available.
+ */
+struct IndexEntry : CoreIndexInfo {
IndexEntry(const BSONObj& kp,
IndexType type,
bool mk,
@@ -109,58 +155,14 @@ struct IndexEntry {
const BSONObj& io,
const CollatorInterface* ci,
const ProjectionExecAgg* projExec)
- : keyPattern(kp),
+ : CoreIndexInfo(kp, type, sp, std::move(ident), fe, ci, projExec),
multikey(mk),
multikeyPaths(mkp),
multikeyPathSet(std::move(multikeyPathSet)),
- sparse(sp),
unique(unq),
- identifier(std::move(ident)),
- filterExpr(fe),
- infoObj(io),
- type(type),
- collator(ci),
- wildcardProjection(projExec) {
+ infoObj(io) {
// The caller must not supply multikey metadata in two different formats.
invariant(multikeyPaths.empty() || multikeyPathSet.empty());
- // We always expect a projection executor for $** indexes, and none otherwise.
- invariant((type == IndexType::INDEX_WILDCARD) == (projExec != nullptr));
- }
-
- /**
- * For testing purposes only.
- */
- IndexEntry(const BSONObj& kp,
- bool mk,
- bool sp,
- bool unq,
- Identifier ident,
- const MatchExpression* fe,
- const BSONObj& io,
- const ProjectionExecAgg* projExec = nullptr)
- : keyPattern(kp),
- multikey(mk),
- sparse(sp),
- unique(unq),
- identifier(std::move(ident)),
- filterExpr(fe),
- infoObj(io),
- wildcardProjection(projExec) {
- type = IndexNames::nameToType(IndexNames::findPluginName(keyPattern));
- }
-
- /**
- * For testing purposes only.
- */
- IndexEntry(const BSONObj& kp, const std::string& indexName = "test_foo")
- : keyPattern(kp),
- multikey(false),
- sparse(false),
- unique(false),
- identifier(indexName),
- filterExpr(nullptr),
- infoObj(BSONObj()) {
- type = IndexNames::nameToType(IndexNames::findPluginName(keyPattern));
}
~IndexEntry() {
@@ -186,8 +188,6 @@ struct IndexEntry {
std::string toString() const;
- BSONObj keyPattern;
-
bool multikey;
// If non-empty, 'multikeyPaths' is a vector with size equal to the number of elements in the
@@ -208,28 +208,10 @@ struct IndexEntry {
// 'multikeyPathSet' must be empty.
std::set<FieldRef> multikeyPathSet;
- bool sparse;
-
bool unique;
- Identifier identifier;
-
- const MatchExpression* filterExpr;
-
// Geo indices have extra parameters. We need those available to plan correctly.
BSONObj infoObj;
-
- // What type of index is this? (What access method can we use on the index described
- // by the keyPattern?)
- IndexType type;
-
- // Null if this index orders strings according to the simple binary compare. If non-null,
- // represents the collator used to generate index keys for indexed strings.
- const CollatorInterface* collator = nullptr;
-
- // For $** indexes, a pointer to the projection executor owned by the index access method. Null
- // unless this IndexEntry represents a wildcard index, in which case this is always non-null.
- const ProjectionExecAgg* wildcardProjection = nullptr;
};
std::ostream& operator<<(std::ostream& stream, const IndexEntry::Identifier& ident);
diff --git a/src/mongo/db/query/index_entry_test.cpp b/src/mongo/db/query/index_entry_test.cpp
index 1e9c4c1cf3b..7626bf215a3 100644
--- a/src/mongo/db/query/index_entry_test.cpp
+++ b/src/mongo/db/query/index_entry_test.cpp
@@ -40,12 +40,22 @@ namespace mongo {
namespace {
IndexEntry makeIndexEntry(BSONObj keyPattern, MultikeyPaths multiKeyPaths) {
- IndexEntry entry{std::move(keyPattern)};
- entry.multikeyPaths = std::move(multiKeyPaths);
- entry.multikey = std::any_of(entry.multikeyPaths.cbegin(),
- entry.multikeyPaths.cend(),
- [](const auto& entry) { return !entry.empty(); });
- return entry;
+ bool multiKey = std::any_of(multiKeyPaths.cbegin(),
+ multiKeyPaths.cend(),
+ [](const auto& entry) { return !entry.empty(); });
+
+ return {keyPattern,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
+ multiKey,
+ multiKeyPaths,
+ {},
+ false,
+ false,
+ CoreIndexInfo::Identifier("test_foo"),
+ nullptr,
+ {},
+ nullptr,
+ nullptr};
}
TEST(QueryPlannerIXSelectTest, IndexedFieldHasMultikeyComponents) {
diff --git a/src/mongo/db/query/plan_cache.cpp b/src/mongo/db/query/plan_cache.cpp
index 0786f995c17..3ea3cf871d7 100644
--- a/src/mongo/db/query/plan_cache.cpp
+++ b/src/mongo/db/query/plan_cache.cpp
@@ -650,8 +650,8 @@ size_t PlanCache::size() const {
return _cache.size();
}
-void PlanCache::notifyOfIndexEntries(const std::vector<IndexEntry>& indexEntries) {
- _indexabilityState.updateDiscriminators(indexEntries);
+void PlanCache::notifyOfIndexUpdates(const std::vector<CoreIndexInfo>& indexCores) {
+ _indexabilityState.updateDiscriminators(indexCores);
}
std::vector<BSONObj> PlanCache::getMatchingStats(
diff --git a/src/mongo/db/query/plan_cache.h b/src/mongo/db/query/plan_cache.h
index 99f88ed23a9..2c8ca6c690c 100644
--- a/src/mongo/db/query/plan_cache.h
+++ b/src/mongo/db/query/plan_cache.h
@@ -517,7 +517,7 @@ public:
*
* Callers must hold the collection lock in exclusive mode when calling this method.
*/
- void notifyOfIndexEntries(const std::vector<IndexEntry>& indexEntries);
+ void notifyOfIndexUpdates(const std::vector<CoreIndexInfo>& indexCores);
/**
* Iterates over the plan cache. For each entry, serializes the PlanCacheEntry according to
diff --git a/src/mongo/db/query/plan_cache_indexability.cpp b/src/mongo/db/query/plan_cache_indexability.cpp
index 488e40d7cc1..f227f8aca20 100644
--- a/src/mongo/db/query/plan_cache_indexability.cpp
+++ b/src/mongo/db/query/plan_cache_indexability.cpp
@@ -114,11 +114,11 @@ void PlanCacheIndexabilityState::processPartialIndex(const std::string& indexNam
}
}
-void PlanCacheIndexabilityState::processWildcardIndex(const IndexEntry& ie) {
- invariant(ie.type == IndexType::INDEX_WILDCARD);
+void PlanCacheIndexabilityState::processWildcardIndex(const CoreIndexInfo& cii) {
+ invariant(cii.type == IndexType::INDEX_WILDCARD);
_wildcardIndexDiscriminators.emplace_back(
- ie.wildcardProjection, ie.identifier.catalogName, ie.filterExpr, ie.collator);
+ cii.wildcardProjection, cii.identifier.catalogName, cii.filterExpr, cii.collator);
}
void PlanCacheIndexabilityState::processIndexCollation(const std::string& indexName,
@@ -166,11 +166,12 @@ IndexToDiscriminatorMap PlanCacheIndexabilityState::buildWildcardDiscriminators(
return ret;
}
-void PlanCacheIndexabilityState::updateDiscriminators(const std::vector<IndexEntry>& indexEntries) {
+void PlanCacheIndexabilityState::updateDiscriminators(
+ const std::vector<CoreIndexInfo>& indexCores) {
_pathDiscriminatorsMap = PathDiscriminatorsMap();
_wildcardIndexDiscriminators.clear();
- for (const IndexEntry& idx : indexEntries) {
+ for (const auto& idx : indexCores) {
if (idx.type == IndexType::INDEX_WILDCARD) {
processWildcardIndex(idx);
continue;
diff --git a/src/mongo/db/query/plan_cache_indexability.h b/src/mongo/db/query/plan_cache_indexability.h
index 1c9991bd019..702dbd20e19 100644
--- a/src/mongo/db/query/plan_cache_indexability.h
+++ b/src/mongo/db/query/plan_cache_indexability.h
@@ -43,7 +43,7 @@ class BSONObj;
class CollatorInterface;
class CompositeIndexabilityDiscriminator;
class MatchExpression;
-struct IndexEntry;
+struct CoreIndexInfo;
using IndexabilityDiscriminator = stdx::function<bool(const MatchExpression* me)>;
using IndexabilityDiscriminators = std::vector<IndexabilityDiscriminator>;
@@ -104,9 +104,9 @@ public:
IndexToDiscriminatorMap buildWildcardDiscriminators(StringData path) const;
/**
- * Clears discriminators for all paths, and regenerate them from 'indexEntries'.
+ * Clears discriminators for all paths, and regenerates them from 'indexCores'.
*/
- void updateDiscriminators(const std::vector<IndexEntry>& indexEntries);
+ void updateDiscriminators(const std::vector<CoreIndexInfo>& indexCores);
private:
using PathDiscriminatorsMap = StringMap<IndexToDiscriminatorMap>;
@@ -174,7 +174,7 @@ private:
* path, appropriate discriminators for the wildcard index will be included if it includes the
* given path.
*/
- void processWildcardIndex(const IndexEntry& ie);
+ void processWildcardIndex(const CoreIndexInfo& cii);
// PathDiscriminatorsMap is a map from field path to index name to IndexabilityDiscriminator.
PathDiscriminatorsMap _pathDiscriminatorsMap;
diff --git a/src/mongo/db/query/plan_cache_indexability_test.cpp b/src/mongo/db/query/plan_cache_indexability_test.cpp
index dc67fd8c30a..6d314199695 100644
--- a/src/mongo/db/query/plan_cache_indexability_test.cpp
+++ b/src/mongo/db/query/plan_cache_indexability_test.cpp
@@ -61,27 +61,38 @@ std::unique_ptr<MatchExpression> parseMatchExpression(const BSONObj& obj,
std::pair<IndexEntry, std::unique_ptr<ProjectionExecAgg>> makeWildcardEntry(
BSONObj keyPattern, const MatchExpression* filterExpr = nullptr) {
auto projExec = WildcardKeyGenerator::createProjectionExec(keyPattern, {});
- return {IndexEntry(keyPattern,
- false, // multikey
- false, // sparse
- false, // unique
- IndexEntry::Identifier{"indexName"},
- filterExpr,
- BSONObj(),
- projExec.get()),
+ return {{keyPattern,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
+ false, // multikey
+ {},
+ {},
+ false, // sparse
+ false, // unique
+ IndexEntry::Identifier{"indexName"},
+ filterExpr,
+ BSONObj(),
+ nullptr,
+ projExec.get()},
std::move(projExec)};
}
// Test sparse index discriminators for a simple sparse index.
TEST(PlanCacheIndexabilityTest, SparseIndexSimple) {
PlanCacheIndexabilityState state;
- state.updateDiscriminators({IndexEntry(BSON("a" << 1),
- false, // multikey
- true, // sparse
- false, // unique
- IndexEntry::Identifier{"a_1"}, // name
- nullptr, // filterExpr
- BSONObj())});
+ auto keyPattern = BSON("a" << 1);
+ state.updateDiscriminators(
+ {IndexEntry(keyPattern,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
+ false, // multikey
+ {},
+ {},
+ true, // sparse
+ false, // unique
+ IndexEntry::Identifier{"a_1"}, // name
+ nullptr, // filterExpr
+ BSONObj(),
+ nullptr,
+ nullptr)});
auto discriminators = state.getDiscriminators("a");
ASSERT_EQ(1U, discriminators.size());
@@ -108,13 +119,20 @@ TEST(PlanCacheIndexabilityTest, SparseIndexSimple) {
// Test sparse index discriminators for a compound sparse index.
TEST(PlanCacheIndexabilityTest, SparseIndexCompound) {
PlanCacheIndexabilityState state;
- state.updateDiscriminators({IndexEntry(BSON("a" << 1 << "b" << 1),
- false, // multikey
- true, // sparse
- false, // unique
- IndexEntry::Identifier{"a_1_b_1"}, // name
- nullptr, // filterExpr
- BSONObj())});
+ auto keyPattern = BSON("a" << 1 << "b" << 1);
+ state.updateDiscriminators(
+ {IndexEntry(keyPattern,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
+ false, // multikey
+ {},
+ {},
+ true, // sparse
+ false, // unique
+ IndexEntry::Identifier{"a_1_b_1"}, // name
+ nullptr, // filterExpr
+ BSONObj(),
+ nullptr,
+ nullptr)});
{
auto discriminators = state.getDiscriminators("a");
@@ -148,13 +166,20 @@ TEST(PlanCacheIndexabilityTest, PartialIndexSimple) {
BSONObj filterObj = BSON("f" << BSON("$gt" << 0));
std::unique_ptr<MatchExpression> filterExpr(parseMatchExpression(filterObj));
PlanCacheIndexabilityState state;
- state.updateDiscriminators({IndexEntry(BSON("a" << 1),
- false, // multikey
- false, // sparse
- false, // unique
- IndexEntry::Identifier{"a_1"}, // name
- filterExpr.get(),
- BSONObj())});
+ auto keyPattern = BSON("a" << 1);
+ state.updateDiscriminators(
+ {IndexEntry(keyPattern,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
+ false, // multikey
+ {},
+ {},
+ false, // sparse
+ false, // unique
+ IndexEntry::Identifier{"a_1"}, // name
+ filterExpr.get(),
+ BSONObj(),
+ nullptr,
+ nullptr)});
{
auto discriminators = state.getDiscriminators("f");
@@ -190,13 +215,20 @@ TEST(PlanCacheIndexabilityTest, PartialIndexAnd) {
BSONObj filterObj = BSON("f" << 1 << "g" << 1);
std::unique_ptr<MatchExpression> filterExpr(parseMatchExpression(filterObj));
PlanCacheIndexabilityState state;
- state.updateDiscriminators({IndexEntry(BSON("a" << 1),
- false, // multikey
- false, // sparse
- false, // unique
- IndexEntry::Identifier{"a_1"}, // name
- filterExpr.get(),
- BSONObj())});
+ auto keyPattern = BSON("a" << 1);
+ state.updateDiscriminators(
+ {IndexEntry(keyPattern,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
+ false, // multikey
+ {},
+ {},
+ false, // sparse
+ false, // unique
+ IndexEntry::Identifier{"a_1"}, // name
+ filterExpr.get(),
+ BSONObj(),
+ nullptr,
+ nullptr)});
{
auto discriminators = state.getDiscriminators("f");
@@ -244,20 +276,33 @@ TEST(PlanCacheIndexabilityTest, MultiplePartialIndexes) {
std::unique_ptr<MatchExpression> filterExpr2(parseMatchExpression(filterObj2));
PlanCacheIndexabilityState state;
- state.updateDiscriminators({IndexEntry(BSON("a" << 1),
- false, // multikey
- false, // sparse
- false, // unique
- IndexEntry::Identifier{"a_1"}, // name
- filterExpr1.get(),
- BSONObj()),
- IndexEntry(BSON("b" << 1),
- false, // multikey
- false, // sparse
- false, // unique
- IndexEntry::Identifier{"b_1"}, // name
- filterExpr2.get(),
- BSONObj())});
+ auto keyPattern_a = BSON("a" << 1);
+ auto keyPattern_b = BSON("b" << 1);
+ state.updateDiscriminators(
+ {IndexEntry(keyPattern_a,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern_a)),
+ false, // multikey
+ {},
+ {},
+ false, // sparse
+ false, // unique
+ IndexEntry::Identifier{"a_1"}, // name
+ filterExpr1.get(),
+ BSONObj(),
+ nullptr,
+ nullptr),
+ IndexEntry(keyPattern_b,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern_b)),
+ false, // multikey
+ {},
+ {},
+ false, // sparse
+ false, // unique
+ IndexEntry::Identifier{"b_1"}, // name
+ filterExpr2.get(),
+ BSONObj(),
+ nullptr,
+ nullptr)});
{
auto discriminators = state.getDiscriminators("f");
@@ -317,13 +362,20 @@ TEST(PlanCacheIndexabilityTest, MultiplePartialIndexes) {
// collation indexability).
TEST(PlanCacheIndexabilityTest, IndexNeitherSparseNorPartial) {
PlanCacheIndexabilityState state;
- state.updateDiscriminators({IndexEntry(BSON("a" << 1),
- false, // multikey
- false, // sparse
- false, // unique
- IndexEntry::Identifier{"a_1"}, // name
- nullptr,
- BSONObj())});
+ auto keyPattern = BSON("a" << 1);
+ state.updateDiscriminators(
+ {IndexEntry(keyPattern,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
+ false, // multikey
+ {},
+ {},
+ false, // sparse
+ false, // unique
+ IndexEntry::Identifier{"a_1"}, // name
+ nullptr,
+ BSONObj(),
+ nullptr,
+ nullptr)});
auto discriminators = state.getDiscriminators("a");
ASSERT_EQ(1U, discriminators.size());
ASSERT(discriminators.find("a_1") != discriminators.end());
@@ -332,13 +384,19 @@ TEST(PlanCacheIndexabilityTest, IndexNeitherSparseNorPartial) {
// Test discriminator for a simple index with a collation.
TEST(PlanCacheIndexabilityTest, DiscriminatorForCollationIndicatesWhenCollationsAreCompatible) {
PlanCacheIndexabilityState state;
- IndexEntry entry(BSON("a" << 1),
- false, // multikey
+ auto keyPattern = BSON("a" << 1);
+ IndexEntry entry(keyPattern,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
+ false, // multikey
+ {},
+ {},
false, // sparse
false, // unique
IndexEntry::Identifier{"a_1"}, // name
nullptr, // filterExpr
- BSONObj());
+ BSONObj(),
+ nullptr,
+ nullptr);
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
entry.collator = &collator;
state.updateDiscriminators({entry});
@@ -413,13 +471,20 @@ TEST(PlanCacheIndexabilityTest, DiscriminatorForCollationIndicatesWhenCollations
// only encode collation indexability).
TEST(PlanCacheIndexabilityTest, CompoundIndexCollationDiscriminator) {
PlanCacheIndexabilityState state;
- state.updateDiscriminators({IndexEntry(BSON("a" << 1 << "b" << 1),
- false, // multikey
- false, // sparse
- false, // unique
- IndexEntry::Identifier{"a_1_b_1"}, // name
- nullptr,
- BSONObj())});
+ auto keyPattern = BSON("a" << 1 << "b" << 1);
+ state.updateDiscriminators(
+ {IndexEntry(keyPattern,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
+ false, // multikey
+ {},
+ {},
+ false, // sparse
+ false, // unique
+ IndexEntry::Identifier{"a_1_b_1"}, // name
+ nullptr,
+ BSONObj(),
+ nullptr,
+ nullptr)});
auto discriminatorsA = state.getDiscriminators("a");
ASSERT_EQ(1U, discriminatorsA.size());
diff --git a/src/mongo/db/query/plan_cache_test.cpp b/src/mongo/db/query/plan_cache_test.cpp
index dbc5b13dec4..fde92088aa1 100644
--- a/src/mongo/db/query/plan_cache_test.cpp
+++ b/src/mongo/db/query/plan_cache_test.cpp
@@ -247,16 +247,34 @@ void assertEquivalent(const char* queryStr,
std::pair<IndexEntry, std::unique_ptr<ProjectionExecAgg>> makeWildcardEntry(BSONObj keyPattern) {
auto projExec = WildcardKeyGenerator::createProjectionExec(keyPattern, {});
return {IndexEntry(keyPattern,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
false, // multikey
+ {},
+ {},
false, // sparse
false, // unique
IndexEntry::Identifier{"indexName"},
nullptr,
BSONObj(),
+ nullptr,
projExec.get()),
std::move(projExec)};
}
+// A version of the above for CoreIndexInfo, used for plan cache update tests.
+std::pair<CoreIndexInfo, std::unique_ptr<ProjectionExecAgg>> makeWildcardUpdate(
+ BSONObj keyPattern) {
+ auto projExec = WildcardKeyGenerator::createProjectionExec(keyPattern, {});
+ return {CoreIndexInfo(keyPattern,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
+ false, // sparse
+ IndexEntry::Identifier{"indexName"}, // name
+ nullptr, // filterExpr
+ nullptr, // collation
+ projExec.get()), // wildcard
+ std::move(projExec)};
+}
+
//
// Tests for CachedSolution
//
@@ -872,31 +890,50 @@ protected:
}
void addIndex(BSONObj keyPattern, const std::string& indexName, bool multikey = false) {
- // The first false means not multikey.
- // The second false means not sparse.
- // The NULL means no filter expression.
- params.indices.push_back(IndexEntry(keyPattern,
- multikey,
- false,
- false,
- IndexEntry::Identifier{indexName},
- NULL,
- BSONObj()));
+ params.indices.push_back(
+ IndexEntry(keyPattern,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
+ multikey,
+ {},
+ {},
+ false,
+ false,
+ IndexEntry::Identifier{indexName},
+ nullptr,
+ BSONObj(),
+ nullptr,
+ nullptr));
}
void addIndex(BSONObj keyPattern, const std::string& indexName, bool multikey, bool sparse) {
- params.indices.push_back(IndexEntry(keyPattern,
- multikey,
- sparse,
- false,
- IndexEntry::Identifier{indexName},
- NULL,
- BSONObj()));
+ params.indices.push_back(
+ IndexEntry(keyPattern,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
+ multikey,
+ {},
+ {},
+ sparse,
+ false,
+ IndexEntry::Identifier{indexName},
+ nullptr,
+ BSONObj(),
+ nullptr,
+ nullptr));
}
void addIndex(BSONObj keyPattern, const std::string& indexName, CollatorInterface* collator) {
- IndexEntry entry(
- keyPattern, false, false, false, IndexEntry::Identifier{indexName}, NULL, BSONObj());
+ IndexEntry entry(keyPattern,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
+ false,
+ {},
+ {},
+ false,
+ false,
+ IndexEntry::Identifier{indexName},
+ nullptr,
+ BSONObj(),
+ nullptr,
+ nullptr);
entry.collator = collator;
params.indices.push_back(entry);
}
@@ -1763,13 +1800,12 @@ TEST_F(CachePlanSelectionTest, ContainedOrAndIntersection) {
// whether or not the predicates in the given query can use the index.
TEST(PlanCacheTest, ComputeKeySparseIndex) {
PlanCache planCache;
- planCache.notifyOfIndexEntries({IndexEntry(BSON("a" << 1),
- false, // multikey
- true, // sparse
- false, // unique
- IndexEntry::Identifier{""}, // name
- nullptr, // filterExpr
- BSONObj())});
+ const auto keyPattern = BSON("a" << 1);
+ planCache.notifyOfIndexUpdates(
+ {CoreIndexInfo(keyPattern,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
+ true, // sparse
+ IndexEntry::Identifier{""})}); // name
unique_ptr<CanonicalQuery> cqEqNumber(canonicalize("{a: 0}}"));
unique_ptr<CanonicalQuery> cqEqString(canonicalize("{a: 'x'}}"));
@@ -1797,13 +1833,13 @@ TEST(PlanCacheTest, ComputeKeyPartialIndex) {
unique_ptr<MatchExpression> filterExpr(parseMatchExpression(filterObj));
PlanCache planCache;
- planCache.notifyOfIndexEntries({IndexEntry(BSON("a" << 1),
- false, // multikey
- false, // sparse
- false, // unique
- IndexEntry::Identifier{""}, // name
- filterExpr.get(),
- BSONObj())});
+ const auto keyPattern = BSON("a" << 1);
+ planCache.notifyOfIndexUpdates(
+ {CoreIndexInfo(keyPattern,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
+ false, // sparse
+ IndexEntry::Identifier{""}, // name
+ filterExpr.get())}); // filterExpr
unique_ptr<CanonicalQuery> cqGtNegativeFive(canonicalize("{f: {$gt: -5}}"));
unique_ptr<CanonicalQuery> cqGtZero(canonicalize("{f: {$gt: 0}}"));
@@ -1822,15 +1858,14 @@ TEST(PlanCacheTest, ComputeKeyCollationIndex) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kReverseString);
PlanCache planCache;
- IndexEntry entry(BSON("a" << 1),
- false, // multikey
- false, // sparse
- false, // unique
- IndexEntry::Identifier{""}, // name
- nullptr, // filterExpr
- BSONObj());
- entry.collator = &collator;
- planCache.notifyOfIndexEntries({entry});
+ const auto keyPattern = BSON("a" << 1);
+ planCache.notifyOfIndexUpdates(
+ {CoreIndexInfo(keyPattern,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
+ false, // sparse
+ IndexEntry::Identifier{""}, // name
+ nullptr, // filterExpr
+ &collator)}); // collation
unique_ptr<CanonicalQuery> containsString(canonicalize("{a: 'abc'}"));
unique_ptr<CanonicalQuery> containsObject(canonicalize("{a: {b: 'abc'}}"));
@@ -1887,10 +1922,10 @@ TEST(PlanCacheTest, ComputeKeyCollationIndex) {
}
TEST(PlanCacheTest, ComputeKeyWildcardIndex) {
- auto entryProjExecPair = makeWildcardEntry(BSON("a.$**" << 1));
+ auto entryProjUpdatePair = makeWildcardUpdate(BSON("a.$**" << 1));
PlanCache planCache;
- planCache.notifyOfIndexEntries({entryProjExecPair.first});
+ planCache.notifyOfIndexUpdates({entryProjUpdatePair.first});
// Used to check that two queries have the same shape when no indexes are present.
PlanCache planCacheWithNoIndexes;
@@ -1950,10 +1985,10 @@ TEST(PlanCacheTest, ComputeKeyWildcardIndex) {
}
TEST(PlanCacheTest, ComputeKeyWildcardIndexDiscriminatesEqualityToEmptyObj) {
- auto entryProjExecPair = makeWildcardEntry(BSON("a.$**" << 1));
+ auto entryProjUpdatePair = makeWildcardUpdate(BSON("a.$**" << 1));
PlanCache planCache;
- planCache.notifyOfIndexEntries({entryProjExecPair.first});
+ planCache.notifyOfIndexUpdates({entryProjUpdatePair.first});
// Equality to empty obj and equality to non-empty obj have different plan cache keys.
std::unique_ptr<CanonicalQuery> equalsEmptyObj(canonicalize("{a: {}}"));
@@ -1979,14 +2014,13 @@ TEST(PlanCacheTest, StableKeyDoesNotChangeAcrossIndexCreation) {
const auto preIndexStableKey = preIndexKey.getStableKey();
ASSERT_EQ(preIndexKey.getUnstablePart(), "");
+ const auto keyPattern = BSON("a" << 1);
// Create a sparse index (which requires a discriminator).
- planCache.notifyOfIndexEntries({IndexEntry(BSON("a" << 1),
- false, // multikey
- true, // sparse
- false, // unique
- IndexEntry::Identifier{""}, // name
- nullptr, // filterExpr
- BSONObj())});
+ planCache.notifyOfIndexUpdates(
+ {CoreIndexInfo(keyPattern,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
+ true, // sparse
+ IndexEntry::Identifier{""})}); // name
const PlanCacheKey postIndexKey = planCache.computeKey(*cq);
const auto postIndexStableKey = postIndexKey.getStableKey();
diff --git a/src/mongo/db/query/planner_analysis_test.cpp b/src/mongo/db/query/planner_analysis_test.cpp
index 11fee9f0bc0..1ad7de68ece 100644
--- a/src/mongo/db/query/planner_analysis_test.cpp
+++ b/src/mongo/db/query/planner_analysis_test.cpp
@@ -42,6 +42,24 @@ using namespace mongo;
namespace {
+/**
+ * Make a minimal IndexEntry from just a key pattern. A dummy name will be added.
+ */
+IndexEntry buildSimpleIndexEntry(const BSONObj& kp) {
+ return {kp,
+ IndexNames::nameToType(IndexNames::findPluginName(kp)),
+ false,
+ {},
+ {},
+ false,
+ false,
+ CoreIndexInfo::Identifier("test_foo"),
+ nullptr,
+ {},
+ nullptr,
+ nullptr};
+}
+
TEST(QueryPlannerAnalysis, GetSortPatternBasic) {
ASSERT_BSONOBJ_EQ(fromjson("{a: 1}"), QueryPlannerAnalysis::getSortPattern(fromjson("{a: 1}")));
ASSERT_BSONOBJ_EQ(fromjson("{a: -1}"),
@@ -114,7 +132,7 @@ TEST(QueryPlannerAnalysis, GetSortPatternSpecialIndexTypes) {
// Test the generation of sort orders provided by an index scan done by
// IndexScanNode::computeProperties().
TEST(QueryPlannerAnalysis, IxscanSortOrdersBasic) {
- IndexScanNode ixscan(IndexEntry(fromjson("{a: 1, b: 1, c: 1, d: 1, e: 1}")));
+ IndexScanNode ixscan(buildSimpleIndexEntry(fromjson("{a: 1, b: 1, c: 1, d: 1, e: 1}")));
// Bounds are {a: [[1,1]], b: [[2,2]], c: [[3,3]], d: [[1,5]], e:[[1,1],[2,2]]},
// all inclusive.
@@ -166,11 +184,11 @@ TEST(QueryPlannerAnalysis, GeoSkipValidation) {
BSONObj unsupportedVersion = fromjson("{'2dsphereIndexVersion': 2}");
BSONObj supportedVersion = fromjson("{'2dsphereIndexVersion': 3}");
- IndexEntry relevantIndex(fromjson("{'geometry.field': '2dsphere'}"));
- IndexEntry irrelevantIndex(fromjson("{'geometry.field': 1}"));
- IndexEntry differentFieldIndex(fromjson("{'geometry.blah': '2dsphere'}"));
- IndexEntry compoundIndex(fromjson("{'geometry.field': '2dsphere', 'a': -1}"));
- IndexEntry unsupportedIndex(fromjson("{'geometry.field': '2dsphere'}"));
+ auto relevantIndex = buildSimpleIndexEntry(fromjson("{'geometry.field': '2dsphere'}"));
+ auto irrelevantIndex = buildSimpleIndexEntry(fromjson("{'geometry.field': 1}"));
+ auto differentFieldIndex = buildSimpleIndexEntry(fromjson("{'geometry.blah': '2dsphere'}"));
+ auto compoundIndex = buildSimpleIndexEntry(fromjson("{'geometry.field': '2dsphere', 'a': -1}"));
+ auto unsupportedIndex = buildSimpleIndexEntry(fromjson("{'geometry.field': '2dsphere'}"));
relevantIndex.infoObj = irrelevantIndex.infoObj = differentFieldIndex.infoObj =
compoundIndex.infoObj = supportedVersion;
diff --git a/src/mongo/db/query/planner_ixselect_test.cpp b/src/mongo/db/query/planner_ixselect_test.cpp
index d9acd0a2542..4c45dc7f3c4 100644
--- a/src/mongo/db/query/planner_ixselect_test.cpp
+++ b/src/mongo/db/query/planner_ixselect_test.cpp
@@ -193,6 +193,24 @@ void findRelevantTaggedNodePathsAndIndices(MatchExpression* root,
}
/**
+ * Make a minimal IndexEntry from just a key pattern. A dummy name will be added.
+ */
+IndexEntry buildSimpleIndexEntry(const BSONObj& kp) {
+ return {kp,
+ IndexNames::nameToType(IndexNames::findPluginName(kp)),
+ false,
+ {},
+ {},
+ false,
+ false,
+ CoreIndexInfo::Identifier("test_foo"),
+ nullptr,
+ {},
+ nullptr,
+ nullptr};
+}
+
+/**
* Parses a MatchExpression from query string and passes that along with prefix, collator, and
* indices to rateIndices. Verifies results against list of expected paths and expected indices. In
* future, we may expand this test function to validate which indices are assigned to which node.
@@ -314,7 +332,7 @@ TEST(QueryPlannerIXSelectTest, RateIndicesTaggedNodePathArrayNegation) {
*/
TEST(QueryPlannerIXSelectTest, ElemMatchNotExistsShouldNotUseSparseIndex) {
std::vector<IndexEntry> indices;
- auto idxEntry = IndexEntry(BSON("a" << 1));
+ auto idxEntry = buildSimpleIndexEntry(BSON("a" << 1));
idxEntry.sparse = true;
indices.push_back(idxEntry);
std::set<size_t> expectedIndices;
@@ -331,7 +349,7 @@ TEST(QueryPlannerIXSelectTest, ElemMatchNotExistsShouldNotUseSparseIndex) {
*/
TEST(QueryPlannerIXSelectTest, ElemMatchInNullValueShouldUseSparseIndex) {
std::vector<IndexEntry> indices;
- auto idxEntry = IndexEntry(BSON("a" << 1));
+ auto idxEntry = buildSimpleIndexEntry(BSON("a" << 1));
idxEntry.sparse = true;
indices.push_back(idxEntry);
std::set<size_t> expectedIndices = {0};
@@ -344,7 +362,7 @@ TEST(QueryPlannerIXSelectTest, ElemMatchInNullValueShouldUseSparseIndex) {
*/
TEST(QueryPlannerIXSelectTest, ElemMatchGeoShouldNotUseBtreeIndex) {
std::vector<IndexEntry> indices;
- auto idxEntry = IndexEntry(BSON("a" << 1));
+ auto idxEntry = buildSimpleIndexEntry(BSON("a" << 1));
indices.push_back(idxEntry);
std::set<size_t> expectedIndices;
testRateIndices(R"({a: {$elemMatch: {$geoWithin: {$geometry: {type: 'Polygon',
@@ -361,7 +379,7 @@ TEST(QueryPlannerIXSelectTest, ElemMatchGeoShouldNotUseBtreeIndex) {
*/
TEST(QueryPlannerIXSelectTest, ElemMatchEqNullValueShouldUseSparseIndex) {
std::vector<IndexEntry> indices;
- auto idxEntry = IndexEntry(BSON("a" << 1));
+ auto idxEntry = buildSimpleIndexEntry(BSON("a" << 1));
idxEntry.sparse = true;
indices.push_back(idxEntry);
std::set<size_t> expectedIndices = {0};
@@ -374,7 +392,7 @@ TEST(QueryPlannerIXSelectTest, ElemMatchEqNullValueShouldUseSparseIndex) {
*/
TEST(QueryPlannerIXSelectTest, ElemMatchMultipleChildrenShouldRequireAllToBeCompatible) {
std::vector<IndexEntry> indices;
- auto idxEntry = IndexEntry(BSON("a" << 1));
+ auto idxEntry = buildSimpleIndexEntry(BSON("a" << 1));
idxEntry.sparse = true;
indices.push_back(idxEntry);
std::set<size_t> expectedIndices;
@@ -391,7 +409,7 @@ TEST(QueryPlannerIXSelectTest, ElemMatchMultipleChildrenShouldRequireAllToBeComp
*/
TEST(QueryPlannerIXSelectTest, NullCollatorsMatch) {
std::vector<IndexEntry> indices;
- indices.push_back(IndexEntry(BSON("a" << 1)));
+ indices.push_back(buildSimpleIndexEntry(BSON("a" << 1)));
std::set<size_t> expectedIndices = {0};
testRateIndices("{a: 'string'}", "", nullptr, indices, "a", expectedIndices);
}
@@ -402,7 +420,7 @@ TEST(QueryPlannerIXSelectTest, NullCollatorsMatch) {
TEST(QueryPlannerIXSelectTest, NonNullCollatorDoesNotMatchIndexWithNullCollator) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
std::vector<IndexEntry> indices;
- indices.push_back(IndexEntry(BSON("a" << 1)));
+ indices.push_back(buildSimpleIndexEntry(BSON("a" << 1)));
std::set<size_t> expectedIndices;
testRateIndices("{a: 'string'}", "", &collator, indices, "a", expectedIndices);
}
@@ -411,7 +429,7 @@ TEST(QueryPlannerIXSelectTest, NonNullCollatorDoesNotMatchIndexWithNullCollator)
* If the collator is null, we do not select the relevant index with a non-null collator.
*/
TEST(QueryPlannerIXSelectTest, NullCollatorDoesNotMatchIndexWithNonNullCollator) {
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
CollatorInterfaceMock indexCollator(CollatorInterfaceMock::MockType::kAlwaysEqual);
index.collator = &indexCollator;
std::vector<IndexEntry> indices;
@@ -425,7 +443,7 @@ TEST(QueryPlannerIXSelectTest, NullCollatorDoesNotMatchIndexWithNonNullCollator)
*/
TEST(QueryPlannerIXSelectTest, EqualCollatorsMatch) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
CollatorInterfaceMock indexCollator(CollatorInterfaceMock::MockType::kAlwaysEqual);
index.collator = &indexCollator;
std::vector<IndexEntry> indices;
@@ -439,7 +457,7 @@ TEST(QueryPlannerIXSelectTest, EqualCollatorsMatch) {
*/
TEST(QueryPlannerIXSelectTest, UnequalCollatorsDoNotMatch) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
CollatorInterfaceMock indexCollator(CollatorInterfaceMock::MockType::kReverseString);
index.collator = &indexCollator;
std::vector<IndexEntry> indices;
@@ -453,7 +471,7 @@ TEST(QueryPlannerIXSelectTest, UnequalCollatorsDoNotMatch) {
*/
TEST(QueryPlannerIXSelectTest, NoStringComparison) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
CollatorInterfaceMock indexCollator(CollatorInterfaceMock::MockType::kReverseString);
index.collator = &indexCollator;
std::vector<IndexEntry> indices;
@@ -464,7 +482,7 @@ TEST(QueryPlannerIXSelectTest, NoStringComparison) {
TEST(QueryPlannerIXSelectTest, StringInternalExprEqUnequalCollatorsCannotUseIndex) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
CollatorInterfaceMock indexCollator(CollatorInterfaceMock::MockType::kReverseString);
index.collator = &indexCollator;
std::vector<IndexEntry> indices;
@@ -476,7 +494,7 @@ TEST(QueryPlannerIXSelectTest, StringInternalExprEqUnequalCollatorsCannotUseInde
TEST(QueryPlannerIXSelectTest, StringInternalExprEqEqualCollatorsCanUseIndex) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
index.collator = &collator;
std::vector<IndexEntry> indices;
indices.push_back(index);
@@ -487,7 +505,7 @@ TEST(QueryPlannerIXSelectTest, StringInternalExprEqEqualCollatorsCanUseIndex) {
TEST(QueryPlannerIXSelectTest, NestedObjectInternalExprEqUnequalCollatorsCannotUseIndex) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
CollatorInterfaceMock indexCollator(CollatorInterfaceMock::MockType::kReverseString);
index.collator = &indexCollator;
std::vector<IndexEntry> indices;
@@ -499,7 +517,7 @@ TEST(QueryPlannerIXSelectTest, NestedObjectInternalExprEqUnequalCollatorsCannotU
TEST(QueryPlannerIXSelectTest, NestedObjectInternalExprEqEqualCollatorsCanUseIndex) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
index.collator = &collator;
std::vector<IndexEntry> indices;
indices.push_back(index);
@@ -513,7 +531,7 @@ TEST(QueryPlannerIXSelectTest, NestedObjectInternalExprEqEqualCollatorsCanUseInd
*/
TEST(QueryPlannerIXSelectTest, StringGTUnequalCollators) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
CollatorInterfaceMock indexCollator(CollatorInterfaceMock::MockType::kReverseString);
index.collator = &indexCollator;
std::vector<IndexEntry> indices;
@@ -527,7 +545,7 @@ TEST(QueryPlannerIXSelectTest, StringGTUnequalCollators) {
*/
TEST(QueryPlannerIXSelectTest, StringGTEqualCollators) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
index.collator = &collator;
std::vector<IndexEntry> indices;
indices.push_back(index);
@@ -540,7 +558,7 @@ TEST(QueryPlannerIXSelectTest, StringGTEqualCollators) {
*/
TEST(QueryPlannerIXSelectTest, ArrayGTUnequalCollators) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
CollatorInterfaceMock indexCollator(CollatorInterfaceMock::MockType::kReverseString);
index.collator = &indexCollator;
std::vector<IndexEntry> indices;
@@ -554,7 +572,7 @@ TEST(QueryPlannerIXSelectTest, ArrayGTUnequalCollators) {
*/
TEST(QueryPlannerIXSelectTest, ArrayGTEqualCollators) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
index.collator = &collator;
std::vector<IndexEntry> indices;
indices.push_back(index);
@@ -567,7 +585,7 @@ TEST(QueryPlannerIXSelectTest, ArrayGTEqualCollators) {
*/
TEST(QueryPlannerIXSelectTest, NestedObjectGTUnequalCollators) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
CollatorInterfaceMock indexCollator(CollatorInterfaceMock::MockType::kReverseString);
index.collator = &indexCollator;
std::vector<IndexEntry> indices;
@@ -581,7 +599,7 @@ TEST(QueryPlannerIXSelectTest, NestedObjectGTUnequalCollators) {
*/
TEST(QueryPlannerIXSelectTest, NestedObjectGTEqualCollators) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
index.collator = &collator;
std::vector<IndexEntry> indices;
indices.push_back(index);
@@ -594,7 +612,7 @@ TEST(QueryPlannerIXSelectTest, NestedObjectGTEqualCollators) {
*/
TEST(QueryPlannerIXSelectTest, StringGTEUnequalCollators) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
CollatorInterfaceMock indexCollator(CollatorInterfaceMock::MockType::kReverseString);
index.collator = &indexCollator;
std::vector<IndexEntry> indices;
@@ -608,7 +626,7 @@ TEST(QueryPlannerIXSelectTest, StringGTEUnequalCollators) {
*/
TEST(QueryPlannerIXSelectTest, StringGTEEqualCollators) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
index.collator = &collator;
std::vector<IndexEntry> indices;
indices.push_back(index);
@@ -621,7 +639,7 @@ TEST(QueryPlannerIXSelectTest, StringGTEEqualCollators) {
*/
TEST(QueryPlannerIXSelectTest, StringLTUnequalCollators) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
CollatorInterfaceMock indexCollator(CollatorInterfaceMock::MockType::kReverseString);
index.collator = &indexCollator;
std::vector<IndexEntry> indices;
@@ -635,7 +653,7 @@ TEST(QueryPlannerIXSelectTest, StringLTUnequalCollators) {
*/
TEST(QueryPlannerIXSelectTest, StringLTEqualCollators) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
index.collator = &collator;
std::vector<IndexEntry> indices;
indices.push_back(index);
@@ -648,7 +666,7 @@ TEST(QueryPlannerIXSelectTest, StringLTEqualCollators) {
*/
TEST(QueryPlannerIXSelectTest, StringLTEUnequalCollators) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
CollatorInterfaceMock indexCollator(CollatorInterfaceMock::MockType::kReverseString);
index.collator = &indexCollator;
std::vector<IndexEntry> indices;
@@ -662,7 +680,7 @@ TEST(QueryPlannerIXSelectTest, StringLTEUnequalCollators) {
*/
TEST(QueryPlannerIXSelectTest, StringLTEEqualCollators) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
index.collator = &collator;
std::vector<IndexEntry> indices;
indices.push_back(index);
@@ -675,7 +693,7 @@ TEST(QueryPlannerIXSelectTest, StringLTEEqualCollators) {
*/
TEST(QueryPlannerIXSelectTest, NoStringComparisonInExpression) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
CollatorInterfaceMock indexCollator(CollatorInterfaceMock::MockType::kReverseString);
index.collator = &indexCollator;
std::vector<IndexEntry> indices;
@@ -689,7 +707,7 @@ TEST(QueryPlannerIXSelectTest, NoStringComparisonInExpression) {
*/
TEST(QueryPlannerIXSelectTest, StringComparisonInExpressionUnequalCollators) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
CollatorInterfaceMock indexCollator(CollatorInterfaceMock::MockType::kReverseString);
index.collator = &indexCollator;
std::vector<IndexEntry> indices;
@@ -703,7 +721,7 @@ TEST(QueryPlannerIXSelectTest, StringComparisonInExpressionUnequalCollators) {
*/
TEST(QueryPlannerIXSelectTest, StringComparisonInExpressionEqualCollators) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
index.collator = &collator;
std::vector<IndexEntry> indices;
indices.push_back(index);
@@ -716,7 +734,7 @@ TEST(QueryPlannerIXSelectTest, StringComparisonInExpressionEqualCollators) {
*/
TEST(QueryPlannerIXSelectTest, NoStringComparisonNotExpression) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
CollatorInterfaceMock indexCollator(CollatorInterfaceMock::MockType::kReverseString);
index.collator = &indexCollator;
std::vector<IndexEntry> indices;
@@ -730,7 +748,7 @@ TEST(QueryPlannerIXSelectTest, NoStringComparisonNotExpression) {
*/
TEST(QueryPlannerIXSelectTest, StringComparisonNotExpressionUnequalCollators) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
CollatorInterfaceMock indexCollator(CollatorInterfaceMock::MockType::kReverseString);
index.collator = &indexCollator;
std::vector<IndexEntry> indices;
@@ -744,7 +762,7 @@ TEST(QueryPlannerIXSelectTest, StringComparisonNotExpressionUnequalCollators) {
*/
TEST(QueryPlannerIXSelectTest, StringComparisonNotExpressionEqualCollators) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
index.collator = &collator;
std::vector<IndexEntry> indices;
indices.push_back(index);
@@ -757,7 +775,7 @@ TEST(QueryPlannerIXSelectTest, StringComparisonNotExpressionEqualCollators) {
*/
TEST(QueryPlannerIXSelectTest, NoStringComparisonElemMatchValueExpression) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
CollatorInterfaceMock indexCollator(CollatorInterfaceMock::MockType::kReverseString);
index.collator = &indexCollator;
std::vector<IndexEntry> indices;
@@ -771,7 +789,7 @@ TEST(QueryPlannerIXSelectTest, NoStringComparisonElemMatchValueExpression) {
*/
TEST(QueryPlannerIXSelectTest, StringComparisonElemMatchValueExpressionUnequalCollators) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
CollatorInterfaceMock indexCollator(CollatorInterfaceMock::MockType::kReverseString);
index.collator = &indexCollator;
std::vector<IndexEntry> indices;
@@ -786,7 +804,7 @@ TEST(QueryPlannerIXSelectTest, StringComparisonElemMatchValueExpressionUnequalCo
*/
TEST(QueryPlannerIXSelectTest, StringComparisonElemMatchValueExpressionEqualCollators) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
index.collator = &collator;
std::vector<IndexEntry> indices;
indices.push_back(index);
@@ -800,7 +818,7 @@ TEST(QueryPlannerIXSelectTest, StringComparisonElemMatchValueExpressionEqualColl
*/
TEST(QueryPlannerIXSelectTest, NoStringComparisonNotInExpression) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
CollatorInterfaceMock indexCollator(CollatorInterfaceMock::MockType::kReverseString);
index.collator = &indexCollator;
std::vector<IndexEntry> indices;
@@ -814,7 +832,7 @@ TEST(QueryPlannerIXSelectTest, NoStringComparisonNotInExpression) {
*/
TEST(QueryPlannerIXSelectTest, StringComparisonNotInExpressionUnequalCollators) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
CollatorInterfaceMock indexCollator(CollatorInterfaceMock::MockType::kReverseString);
index.collator = &indexCollator;
std::vector<IndexEntry> indices;
@@ -828,7 +846,7 @@ TEST(QueryPlannerIXSelectTest, StringComparisonNotInExpressionUnequalCollators)
*/
TEST(QueryPlannerIXSelectTest, StringComparisonNotInExpressionEqualCollators) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
index.collator = &collator;
std::vector<IndexEntry> indices;
indices.push_back(index);
@@ -841,7 +859,7 @@ TEST(QueryPlannerIXSelectTest, StringComparisonNotInExpressionEqualCollators) {
*/
TEST(QueryPlannerIXSelectTest, NoStringComparisonNinExpression) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
CollatorInterfaceMock indexCollator(CollatorInterfaceMock::MockType::kReverseString);
index.collator = &indexCollator;
std::vector<IndexEntry> indices;
@@ -855,7 +873,7 @@ TEST(QueryPlannerIXSelectTest, NoStringComparisonNinExpression) {
*/
TEST(QueryPlannerIXSelectTest, StringComparisonNinExpressionUnequalCollators) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
CollatorInterfaceMock indexCollator(CollatorInterfaceMock::MockType::kReverseString);
index.collator = &indexCollator;
std::vector<IndexEntry> indices;
@@ -869,7 +887,7 @@ TEST(QueryPlannerIXSelectTest, StringComparisonNinExpressionUnequalCollators) {
*/
TEST(QueryPlannerIXSelectTest, StringComparisonNinExpressionEqualCollators) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
index.collator = &collator;
std::vector<IndexEntry> indices;
indices.push_back(index);
@@ -882,7 +900,7 @@ TEST(QueryPlannerIXSelectTest, StringComparisonNinExpressionEqualCollators) {
*/
TEST(QueryPlannerIXSelectTest, StringComparisonOrExpressionUnequalCollators) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
CollatorInterfaceMock indexCollator(CollatorInterfaceMock::MockType::kReverseString);
index.collator = &indexCollator;
std::vector<IndexEntry> indices;
@@ -896,7 +914,7 @@ TEST(QueryPlannerIXSelectTest, StringComparisonOrExpressionUnequalCollators) {
*/
TEST(QueryPlannerIXSelectTest, StringComparisonOrExpressionEqualCollators) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
index.collator = &collator;
std::vector<IndexEntry> indices;
indices.push_back(index);
@@ -909,7 +927,7 @@ TEST(QueryPlannerIXSelectTest, StringComparisonOrExpressionEqualCollators) {
*/
TEST(QueryPlannerIXSelectTest, StringComparisonAndExpressionUnequalCollators) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
CollatorInterfaceMock indexCollator(CollatorInterfaceMock::MockType::kReverseString);
index.collator = &indexCollator;
std::vector<IndexEntry> indices;
@@ -923,7 +941,7 @@ TEST(QueryPlannerIXSelectTest, StringComparisonAndExpressionUnequalCollators) {
*/
TEST(QueryPlannerIXSelectTest, StringComparisonAndExpressionEqualCollators) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
index.collator = &collator;
std::vector<IndexEntry> indices;
indices.push_back(index);
@@ -936,7 +954,7 @@ TEST(QueryPlannerIXSelectTest, StringComparisonAndExpressionEqualCollators) {
*/
TEST(QueryPlannerIXSelectTest, StringComparisonAllExpressionUnequalCollators) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
CollatorInterfaceMock indexCollator(CollatorInterfaceMock::MockType::kReverseString);
index.collator = &indexCollator;
std::vector<IndexEntry> indices;
@@ -950,7 +968,7 @@ TEST(QueryPlannerIXSelectTest, StringComparisonAllExpressionUnequalCollators) {
*/
TEST(QueryPlannerIXSelectTest, StringComparisonAllExpressionEqualCollators) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
index.collator = &collator;
std::vector<IndexEntry> indices;
indices.push_back(index);
@@ -963,7 +981,7 @@ TEST(QueryPlannerIXSelectTest, StringComparisonAllExpressionEqualCollators) {
*/
TEST(QueryPlannerIXSelectTest, StringComparisonElemMatchObjectExpressionUnequalCollators) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a.b" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a.b" << 1));
CollatorInterfaceMock indexCollator(CollatorInterfaceMock::MockType::kReverseString);
index.collator = &indexCollator;
std::vector<IndexEntry> indices;
@@ -978,7 +996,7 @@ TEST(QueryPlannerIXSelectTest, StringComparisonElemMatchObjectExpressionUnequalC
*/
TEST(QueryPlannerIXSelectTest, StringComparisonElemMatchObjectExpressionEqualCollators) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a.b" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a.b" << 1));
index.collator = &collator;
std::vector<IndexEntry> indices;
indices.push_back(index);
@@ -992,7 +1010,7 @@ TEST(QueryPlannerIXSelectTest, StringComparisonElemMatchObjectExpressionEqualCol
*/
TEST(QueryPlannerIXSelectTest, NoStringComparisonMod) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
CollatorInterfaceMock indexCollator(CollatorInterfaceMock::MockType::kReverseString);
index.collator = &indexCollator;
std::vector<IndexEntry> indices;
@@ -1006,7 +1024,7 @@ TEST(QueryPlannerIXSelectTest, NoStringComparisonMod) {
*/
TEST(QueryPlannerIXSelectTest, NoStringComparisonExists) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
CollatorInterfaceMock indexCollator(CollatorInterfaceMock::MockType::kReverseString);
index.collator = &indexCollator;
std::vector<IndexEntry> indices;
@@ -1020,7 +1038,7 @@ TEST(QueryPlannerIXSelectTest, NoStringComparisonExists) {
*/
TEST(QueryPlannerIXSelectTest, NoStringComparisonType) {
CollatorInterfaceMock collator(CollatorInterfaceMock::MockType::kAlwaysEqual);
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
CollatorInterfaceMock indexCollator(CollatorInterfaceMock::MockType::kReverseString);
index.collator = &indexCollator;
std::vector<IndexEntry> indices;
@@ -1039,23 +1057,30 @@ TEST(QueryPlannerIXSelectTest, NoStringComparisonType) {
std::pair<IndexEntry, std::unique_ptr<ProjectionExecAgg>> makeIndexEntry(
BSONObj keyPattern,
MultikeyPaths multiKeyPaths,
- std::set<FieldRef> multikeyPathSet = {},
+ std::set<FieldRef> multiKeyPathSet = {},
BSONObj infoObj = BSONObj()) {
auto projExec = (keyPattern.firstElement().fieldNameStringData().endsWith("$**"_sd)
? WildcardKeyGenerator::createProjectionExec(
keyPattern, infoObj.getObjectField("wildcardProjection"))
: nullptr);
- IndexEntry entry{std::move(keyPattern)};
- entry.multikeyPaths = std::move(multiKeyPaths);
- entry.multikey =
- !multikeyPathSet.empty() || std::any_of(entry.multikeyPaths.cbegin(),
- entry.multikeyPaths.cend(),
- [](const auto& entry) { return !entry.empty(); });
- entry.multikeyPathSet = std::move(multikeyPathSet);
- entry.wildcardProjection = projExec.get();
- entry.infoObj = infoObj;
- return {entry, std::move(projExec)};
+ auto multiKey = !multiKeyPathSet.empty() ||
+ std::any_of(multiKeyPaths.cbegin(), multiKeyPaths.cend(), [](const auto& entry) {
+ return !entry.empty();
+ });
+ return {{keyPattern,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
+ multiKey,
+ multiKeyPaths,
+ multiKeyPathSet,
+ false,
+ false,
+ CoreIndexInfo::Identifier("test_foo"),
+ nullptr,
+ {},
+ nullptr,
+ projExec.get()},
+ std::move(projExec)};
}
TEST(QueryPlannerIXSelectTest, InternalExprEqCannotUseMultiKeyIndex) {
@@ -1077,7 +1102,7 @@ TEST(QueryPlannerIXSelectTest, InternalExprEqCanUseNonMultikeyFieldOfMultikeyInd
}
TEST(QueryPlannerIXSelectTest, InternalExprEqCannotUseMultikeyIndexWithoutPathLevelMultikeyData) {
- IndexEntry entry{BSON("a" << 1)};
+ auto entry = buildSimpleIndexEntry(BSON("a" << 1));
entry.multikey = true;
std::vector<IndexEntry> indices;
indices.push_back(entry);
@@ -1087,7 +1112,7 @@ TEST(QueryPlannerIXSelectTest, InternalExprEqCannotUseMultikeyIndexWithoutPathLe
}
TEST(QueryPlannerIXSelectTest, InternalExprEqCanUseNonMultikeyIndexWithNoPathLevelMultikeyData) {
- IndexEntry entry{BSON("a" << 1)};
+ auto entry = buildSimpleIndexEntry(BSON("a" << 1));
std::vector<IndexEntry> indices;
indices.push_back(entry);
std::set<size_t> expectedIndices = {0};
@@ -1096,8 +1121,8 @@ TEST(QueryPlannerIXSelectTest, InternalExprEqCanUseNonMultikeyIndexWithNoPathLev
}
TEST(QueryPlannerIXSelectTest, InternalExprEqCanUseHashedIndex) {
- IndexEntry entry{BSON("a"
- << "hashed")};
+ auto entry = buildSimpleIndexEntry(BSON("a"
+ << "hashed"));
std::vector<IndexEntry> indices;
indices.push_back(entry);
std::set<size_t> expectedIndices = {0};
@@ -1106,10 +1131,10 @@ TEST(QueryPlannerIXSelectTest, InternalExprEqCanUseHashedIndex) {
}
TEST(QueryPlannerIXSelectTest, InternalExprEqCannotUseTextIndexPrefix) {
- IndexEntry entry{BSON("a" << 1 << "_fts"
- << "text"
- << "_ftsx"
- << 1)};
+ auto entry = buildSimpleIndexEntry(BSON("a" << 1 << "_fts"
+ << "text"
+ << "_ftsx"
+ << 1));
std::vector<IndexEntry> indices;
indices.push_back(entry);
std::set<size_t> expectedIndices;
@@ -1118,12 +1143,12 @@ TEST(QueryPlannerIXSelectTest, InternalExprEqCannotUseTextIndexPrefix) {
}
TEST(QueryPlannerIXSelectTest, InternalExprEqCanUseTextIndexSuffix) {
- IndexEntry entry{BSON("_fts"
- << "text"
- << "_ftsx"
- << 1
- << "a"
- << 1)};
+ auto entry = buildSimpleIndexEntry(BSON("_fts"
+ << "text"
+ << "_ftsx"
+ << 1
+ << "a"
+ << 1));
std::vector<IndexEntry> indices;
indices.push_back(entry);
std::set<size_t> expectedIndices = {0};
@@ -1132,7 +1157,7 @@ TEST(QueryPlannerIXSelectTest, InternalExprEqCanUseTextIndexSuffix) {
}
TEST(QueryPlannerIXSelectTest, InternalExprEqCanUseSparseIndexWithComparisonToNull) {
- IndexEntry entry{BSON("a" << 1)};
+ auto entry = buildSimpleIndexEntry(BSON("a" << 1));
entry.sparse = true;
std::vector<IndexEntry> indices;
indices.push_back(entry);
@@ -1142,7 +1167,7 @@ TEST(QueryPlannerIXSelectTest, InternalExprEqCanUseSparseIndexWithComparisonToNu
}
TEST(QueryPlannerIXSelectTest, InternalExprEqCanUseSparseIndexWithComparisonToNonNull) {
- IndexEntry entry{BSON("a" << 1)};
+ auto entry = buildSimpleIndexEntry(BSON("a" << 1));
entry.sparse = true;
std::vector<IndexEntry> indices;
indices.push_back(entry);
@@ -1151,20 +1176,20 @@ TEST(QueryPlannerIXSelectTest, InternalExprEqCanUseSparseIndexWithComparisonToNo
"{a: {$_internalExprEq: 1}}", "", kSimpleCollator, indices, "a", expectedIndices);
}
TEST(QueryPlannerIXSelectTest, NotEqualsNullCanUseIndex) {
- IndexEntry entry{BSON("a" << 1)};
+ auto entry = buildSimpleIndexEntry(BSON("a" << 1));
std::set<size_t> expectedIndices = {0};
testRateIndices("{a: {$ne: null}}", "", kSimpleCollator, {entry}, "a,a", expectedIndices);
}
TEST(QueryPlannerIXSelectTest, NotEqualsNullCannotUseMultiKeyIndex) {
- IndexEntry entry{BSON("a" << 1)};
+ auto entry = buildSimpleIndexEntry(BSON("a" << 1));
entry.multikey = true;
std::set<size_t> expectedIndices = {};
testRateIndices("{a: {$ne: null}}", "", kSimpleCollator, {entry}, "a,a", expectedIndices);
}
TEST(QueryPlannerIXSelectTest, NotEqualsNullCannotUseDottedMultiKeyIndex) {
- IndexEntry entry{BSON("a.b" << 1)};
+ auto entry = buildSimpleIndexEntry(BSON("a.b" << 1));
entry.multikeyPaths = {{0}};
std::set<size_t> expectedIndices = {};
testRateIndices(
@@ -1172,21 +1197,21 @@ TEST(QueryPlannerIXSelectTest, NotEqualsNullCannotUseDottedMultiKeyIndex) {
}
TEST(QueryPlannerIXSelectTest, NotEqualsNullCanUseIndexWhichIsMultiKeyOnAnotherPath) {
- IndexEntry entry{BSON("a" << 1 << "mk" << 1)};
+ auto entry = buildSimpleIndexEntry(BSON("a" << 1 << "mk" << 1));
entry.multikeyPaths = {{}, {0}};
std::set<size_t> expectedIndices = {0};
testRateIndices("{a: {$ne: null}}", "", kSimpleCollator, {entry}, "a,a", expectedIndices);
}
TEST(QueryPlannerIXSelectTest, ElemMatchValueWithNotEqualsNullCanUseIndex) {
- IndexEntry entry{BSON("a" << 1)};
+ auto entry = buildSimpleIndexEntry(BSON("a" << 1));
std::set<size_t> expectedIndices = {0};
testRateIndices(
"{a: {$elemMatch: {$ne: null}}}", "", kSimpleCollator, {entry}, "a", expectedIndices);
}
TEST(QueryPlannerIXSelectTest, ElemMatchValueWithNotEqualsNullCanUseMultiKeyIndex) {
- IndexEntry entry{BSON("a" << 1)};
+ auto entry = buildSimpleIndexEntry(BSON("a" << 1));
entry.multikey = true;
std::set<size_t> expectedIndices = {0};
testRateIndices(
@@ -1194,7 +1219,7 @@ TEST(QueryPlannerIXSelectTest, ElemMatchValueWithNotEqualsNullCanUseMultiKeyInde
}
TEST(QueryPlannerIXSelectTest, ElemMatchObjectWithNotEqualNullCanUseIndex) {
- IndexEntry entry{BSON("a.b" << 1)};
+ auto entry = buildSimpleIndexEntry(BSON("a.b" << 1));
std::set<size_t> expectedIndices = {0};
testRateIndices("{a: {$elemMatch: {b: {$ne: null}}}}",
"",
@@ -1205,7 +1230,7 @@ TEST(QueryPlannerIXSelectTest, ElemMatchObjectWithNotEqualNullCanUseIndex) {
}
TEST(QueryPlannerIXSelectTest, ElemMatchObjectWithNotEqualNullCannotUseOldMultiKeyIndex) {
- IndexEntry entry{BSON("a.b" << 1)};
+ auto entry = buildSimpleIndexEntry(BSON("a.b" << 1));
entry.multikey = true;
std::set<size_t> expectedIndices = {};
testRateIndices("{a: {$elemMatch: {b: {$ne: null}}}}",
@@ -1217,7 +1242,7 @@ TEST(QueryPlannerIXSelectTest, ElemMatchObjectWithNotEqualNullCannotUseOldMultiK
}
TEST(QueryPlannerIXSelectTest, ElemMatchObjectWithNotEqualNullCanUseIndexMultikeyOnPrefix) {
- IndexEntry entry{BSON("a.b.c.d" << 1)};
+ auto entry = buildSimpleIndexEntry(BSON("a.b.c.d" << 1));
entry.multikeyPaths = {{0U}};
std::set<size_t> expectedIndices = {0U};
const auto query = "{'a.b': {$elemMatch: {'c.d': {$ne: null}}}}";
@@ -1237,7 +1262,7 @@ TEST(QueryPlannerIXSelectTest, ElemMatchObjectWithNotEqualNullCanUseIndexMultike
TEST(QueryPlannerIXSelectTest,
NestedElemMatchObjectWithNotEqualNullCanUseIndexMultikeyOnAnyPrefix) {
- IndexEntry entry{BSON("a.b.c.d" << 1)};
+ auto entry = buildSimpleIndexEntry(BSON("a.b.c.d" << 1));
entry.multikeyPaths = {{0U}};
std::set<size_t> expectedIndices = {0U};
const auto query = "{a: {$elemMatch: {b: {$elemMatch: {'c.d': {$ne: null}}}}}}";
@@ -1256,16 +1281,16 @@ TEST(QueryPlannerIXSelectTest,
}
TEST(QueryPlannerIXSelectTest, HashedIndexShouldNotBeRelevantForNotPredicate) {
- IndexEntry entry{BSON("a"
- << "hashed")};
+ auto entry = buildSimpleIndexEntry(BSON("a"
+ << "hashed"));
entry.type = IndexType::INDEX_HASHED;
std::set<size_t> expectedIndices = {};
testRateIndices("{a: {$ne: 4}}", "", kSimpleCollator, {entry}, "a,a", expectedIndices);
}
TEST(QueryPlannerIXSelectTest, HashedIndexShouldNotBeRelevantForNotEqualsNullPredicate) {
- IndexEntry entry{BSON("a"
- << "hashed")};
+ auto entry = buildSimpleIndexEntry(BSON("a"
+ << "hashed"));
entry.type = IndexType::INDEX_HASHED;
std::set<size_t> expectedIndices = {};
testRateIndices("{a: {$ne: null}}", "", kSimpleCollator, {entry}, "a,a", expectedIndices);
diff --git a/src/mongo/db/query/query_planner_test.cpp b/src/mongo/db/query/query_planner_test.cpp
index b5d64fd6f0b..b983cfd2294 100644
--- a/src/mongo/db/query/query_planner_test.cpp
+++ b/src/mongo/db/query/query_planner_test.cpp
@@ -45,6 +45,24 @@ namespace {
using namespace mongo;
+/**
+ * Make a minimal IndexEntry from just a key pattern and a name.
+ */
+IndexEntry buildSimpleIndexEntry(const BSONObj& kp, const std::string& indexName) {
+ return {kp,
+ IndexNames::nameToType(IndexNames::findPluginName(kp)),
+ false,
+ {},
+ {},
+ false,
+ false,
+ CoreIndexInfo::Identifier(indexName),
+ nullptr,
+ {},
+ nullptr,
+ nullptr};
+}
+
TEST_F(QueryPlannerTest, PlannerUsesCoveredIxscanForCountWhenIndexSatisfiesQuery) {
params.options = QueryPlannerParams::IS_COUNT;
addIndex(BSON("x" << 1));
@@ -341,13 +359,19 @@ TEST_F(QueryPlannerTest, NotEqualsNullInElemMatchValueSparseMultiKeyIndex) {
}
TEST_F(QueryPlannerTest, NotEqualsNullInElemMatchObjectSparseMultiKeyAboveElemMatch) {
- IndexEntry ind(BSON("a.b.c.d" << 1),
+ auto keyPattern = BSON("a.b.c.d" << 1);
+ IndexEntry ind(keyPattern,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
true,
+ {},
+ {},
true,
false,
IndexEntry::Identifier{"ind"},
- NULL, // filterExpr
- BSONObj());
+ nullptr, // filterExpr
+ BSONObj(),
+ nullptr,
+ nullptr);
ind.multikeyPaths = {{0U, 1U}};
addIndex(ind);
@@ -364,13 +388,19 @@ TEST_F(QueryPlannerTest, NotEqualsNullInElemMatchObjectSparseMultiKeyAboveElemMa
TEST_F(QueryPlannerTest, NotEqualsNullInElemMatchObjectSparseMultiKeyBelowElemMatch) {
// "a.b.c" being multikey will prevent us from using the index since $elemMatch doesn't do
// implicit array traversal.
- IndexEntry ind(BSON("a.b.c.d" << 1),
+ auto keyPattern = BSON("a.b.c.d" << 1);
+ IndexEntry ind(keyPattern,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
true,
+ {},
+ {},
true,
false,
IndexEntry::Identifier{"ind"},
- NULL, // filterExpr
- BSONObj());
+ nullptr, // filterExpr
+ BSONObj(),
+ nullptr,
+ nullptr);
ind.multikeyPaths = {{2U}};
addIndex(ind);
@@ -4417,7 +4447,7 @@ TEST_F(QueryPlannerTest, CacheDataFromTaggedTreeFailsOnBadInput) {
ASSERT_NOT_OK(QueryPlanner::cacheDataFromTaggedTree(NULL, relevantIndices).getStatus());
// No relevant index matching the index tag.
- relevantIndices.push_back(IndexEntry(BSON("a" << 1)));
+ relevantIndices.push_back(buildSimpleIndexEntry(BSON("a" << 1), "a_1"));
auto qr = stdx::make_unique<QueryRequest>(NamespaceString("test.collection"));
qr->setFilter(BSON("a" << 3));
@@ -4440,7 +4470,7 @@ TEST_F(QueryPlannerTest, TagAccordingToCacheFailsOnBadInput) {
std::unique_ptr<CanonicalQuery> scopedCq = std::move(statusWithCQ.getValue());
std::unique_ptr<PlanCacheIndexTree> indexTree(new PlanCacheIndexTree());
- indexTree->setIndexEntry(IndexEntry(BSON("a" << 1), "a_1"));
+ indexTree->setIndexEntry(buildSimpleIndexEntry(BSON("a" << 1), "a_1"));
std::map<IndexEntry::Identifier, size_t> indexMap;
@@ -4470,7 +4500,7 @@ TEST_F(QueryPlannerTest, TagAccordingToCacheFailsOnBadInput) {
// Mismatched tree topology.
PlanCacheIndexTree* child = new PlanCacheIndexTree();
- child->setIndexEntry(IndexEntry(BSON("a" << 1)));
+ child->setIndexEntry(buildSimpleIndexEntry(BSON("a" << 1), "a_1"));
indexTree->children.push_back(child);
s = QueryPlanner::tagAccordingToCache(scopedCq->root(), indexTree.get(), indexMap);
ASSERT_NOT_OK(s);
diff --git a/src/mongo/db/query/query_planner_test_fixture.cpp b/src/mongo/db/query/query_planner_test_fixture.cpp
index 61367200a6b..01c0823809f 100644
--- a/src/mongo/db/query/query_planner_test_fixture.cpp
+++ b/src/mongo/db/query/query_planner_test_fixture.cpp
@@ -66,59 +66,85 @@ void QueryPlannerTest::clearState() {
}
void QueryPlannerTest::addIndex(BSONObj keyPattern, bool multikey) {
- params.indices.push_back(IndexEntry(keyPattern,
- multikey,
- false, // sparse
- false, // unique
- IndexEntry::Identifier{"hari_king_of_the_stove"},
- NULL, // filterExpr
- BSONObj()));
+ params.indices.push_back({keyPattern,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
+ multikey,
+ {},
+ {},
+ false, // sparse
+ false, // unique
+ IndexEntry::Identifier{"hari_king_of_the_stove"},
+ nullptr, // filterExpr
+ BSONObj(),
+ nullptr,
+ nullptr});
}
void QueryPlannerTest::addIndex(BSONObj keyPattern, bool multikey, bool sparse) {
- params.indices.push_back(IndexEntry(keyPattern,
- multikey,
- sparse,
- false, // unique
- IndexEntry::Identifier{"note_to_self_dont_break_build"},
- NULL, // filterExpr
- BSONObj()));
+ params.indices.push_back({keyPattern,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
+ multikey,
+ {},
+ {},
+ sparse,
+ false, // unique
+ IndexEntry::Identifier{"note_to_self_dont_break_build"},
+ nullptr, // filterExpr
+ BSONObj(),
+ nullptr,
+ nullptr});
}
void QueryPlannerTest::addIndex(BSONObj keyPattern, bool multikey, bool sparse, bool unique) {
params.indices.push_back(
- IndexEntry(keyPattern,
- multikey,
- sparse,
- unique,
- IndexEntry::Identifier{"sql_query_walks_into_bar_and_says_can_i_join_you?"},
- NULL, // filterExpr
- BSONObj()));
+ {keyPattern,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
+ multikey,
+ {},
+ {},
+ sparse,
+ unique,
+ IndexEntry::Identifier{"sql_query_walks_into_bar_and_says_can_i_join_you?"},
+ nullptr, // filterExpr
+ BSONObj(),
+ nullptr,
+ nullptr});
}
void QueryPlannerTest::addIndex(BSONObj keyPattern, BSONObj infoObj) {
- params.indices.push_back(IndexEntry(keyPattern,
- false, // multikey
- false, // sparse
- false, // unique
- IndexEntry::Identifier{"foo"},
- NULL, // filterExpr
- infoObj));
+ params.indices.push_back({keyPattern,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
+ false, // multikey
+ {},
+ {},
+ false, // sparse
+ false, // unique
+ IndexEntry::Identifier{"foo"},
+ nullptr, // filterExpr
+ infoObj,
+ nullptr,
+ nullptr});
}
void QueryPlannerTest::addIndex(BSONObj keyPattern, MatchExpression* filterExpr) {
- params.indices.push_back(IndexEntry(keyPattern,
- false, // multikey
- false, // sparse
- false, // unique
- IndexEntry::Identifier{"foo"},
- filterExpr,
- BSONObj()));
+ params.indices.push_back({keyPattern,
+ IndexNames::nameToType(IndexNames::findPluginName(keyPattern)),
+ false, // multikey
+ {},
+ {},
+ false, // sparse
+ false, // unique
+ IndexEntry::Identifier{"foo"},
+ filterExpr,
+ BSONObj(),
+ nullptr,
+ nullptr});
}
void QueryPlannerTest::addIndex(BSONObj keyPattern, const MultikeyPaths& multikeyPaths) {
invariant(multikeyPaths.size() == static_cast<size_t>(keyPattern.nFields()));
+ const auto type = IndexNames::nameToType(IndexNames::findPluginName(keyPattern));
const bool multikey =
std::any_of(multikeyPaths.cbegin(),
multikeyPaths.cend(),
@@ -128,21 +154,42 @@ void QueryPlannerTest::addIndex(BSONObj keyPattern, const MultikeyPaths& multike
const char name[] = "my_index_with_path_level_multikey_info";
const MatchExpression* filterExpr = nullptr;
const BSONObj infoObj;
- IndexEntry entry(
- keyPattern, multikey, sparse, unique, IndexEntry::Identifier{name}, filterExpr, infoObj);
+ IndexEntry entry(keyPattern,
+ type,
+ multikey,
+ {},
+ {},
+ sparse,
+ unique,
+ IndexEntry::Identifier{name},
+ filterExpr,
+ infoObj,
+ nullptr,
+ nullptr);
entry.multikeyPaths = multikeyPaths;
params.indices.push_back(entry);
}
void QueryPlannerTest::addIndex(BSONObj keyPattern, const CollatorInterface* collator) {
+ const auto type = IndexNames::nameToType(IndexNames::findPluginName(keyPattern));
const bool sparse = false;
const bool unique = false;
const bool multikey = false;
const char name[] = "my_index_with_collator";
const MatchExpression* filterExpr = nullptr;
const BSONObj infoObj;
- IndexEntry entry(
- keyPattern, multikey, sparse, unique, IndexEntry::Identifier{name}, filterExpr, infoObj);
+ IndexEntry entry(keyPattern,
+ type,
+ multikey,
+ {},
+ {},
+ sparse,
+ unique,
+ IndexEntry::Identifier{name},
+ filterExpr,
+ infoObj,
+ nullptr,
+ nullptr);
entry.collator = collator;
params.indices.push_back(entry);
}
@@ -150,14 +197,25 @@ void QueryPlannerTest::addIndex(BSONObj keyPattern, const CollatorInterface* col
void QueryPlannerTest::addIndex(BSONObj keyPattern,
const CollatorInterface* collator,
StringData indexName) {
+ const auto type = IndexNames::nameToType(IndexNames::findPluginName(keyPattern));
const bool sparse = false;
const bool unique = false;
const bool multikey = false;
const auto name = indexName.toString();
const MatchExpression* filterExpr = nullptr;
const BSONObj infoObj;
- IndexEntry entry(
- keyPattern, multikey, sparse, unique, IndexEntry::Identifier{name}, filterExpr, infoObj);
+ IndexEntry entry(keyPattern,
+ type,
+ multikey,
+ {},
+ {},
+ sparse,
+ unique,
+ IndexEntry::Identifier{name},
+ filterExpr,
+ infoObj,
+ nullptr,
+ nullptr);
entry.collator = collator;
params.indices.push_back(entry);
}
@@ -165,13 +223,24 @@ void QueryPlannerTest::addIndex(BSONObj keyPattern,
void QueryPlannerTest::addIndex(BSONObj keyPattern,
MatchExpression* filterExpr,
const CollatorInterface* collator) {
+ const auto type = IndexNames::nameToType(IndexNames::findPluginName(keyPattern));
const bool sparse = false;
const bool unique = false;
const bool multikey = false;
const char name[] = "my_partial_index_with_collator";
const BSONObj infoObj;
- IndexEntry entry(
- keyPattern, multikey, sparse, unique, IndexEntry::Identifier{name}, filterExpr, infoObj);
+ IndexEntry entry(keyPattern,
+ type,
+ multikey,
+ {},
+ {},
+ sparse,
+ unique,
+ IndexEntry::Identifier{name},
+ filterExpr,
+ infoObj,
+ nullptr,
+ nullptr);
entry.collator = collator;
params.indices.push_back(entry);
}
diff --git a/src/mongo/db/query/query_settings_test.cpp b/src/mongo/db/query/query_settings_test.cpp
index 9d3365d1f4a..23b5217d467 100644
--- a/src/mongo/db/query/query_settings_test.cpp
+++ b/src/mongo/db/query/query_settings_test.cpp
@@ -37,6 +37,7 @@
#include "mongo/bson/bsonobj.h"
#include "mongo/bson/json.h"
#include "mongo/bson/simple_bsonobj_comparator.h"
+#include "mongo/db/index_names.h"
#include "mongo/db/query/index_entry.h"
#include "mongo/unittest/unittest.h"
@@ -50,20 +51,31 @@ namespace {
TEST(QuerySettingsTest, AllowedIndicesFilterAllowsIndexesByName) {
SimpleBSONObjComparator bsonCmp;
AllowedIndicesFilter filter(bsonCmp.makeBSONObjSet({fromjson("{a:1}")}), {"a_1"});
- IndexEntry a_idx(fromjson("{a:1, b:1}"),
+ auto keyPat = fromjson("{a:1, b:1}");
+ IndexEntry a_idx(keyPat,
+ mongo::IndexNames::nameToType(mongo::IndexNames::findPluginName(keyPat)),
false,
+ {},
+ {},
false,
false,
IndexEntry::Identifier{"a_1"},
nullptr,
- BSONObj());
- IndexEntry ab_idx(fromjson("{a:1, b:1}"),
+ BSONObj(),
+ nullptr,
+ nullptr);
+ IndexEntry ab_idx(keyPat,
+ mongo::IndexNames::nameToType(mongo::IndexNames::findPluginName(keyPat)),
false,
+ {},
+ {},
false,
false,
IndexEntry::Identifier{"a_1:2"},
nullptr,
- BSONObj());
+ BSONObj(),
+ nullptr,
+ nullptr);
ASSERT_TRUE(filter.allows(a_idx));
ASSERT_FALSE(filter.allows(ab_idx));
@@ -72,15 +84,32 @@ TEST(QuerySettingsTest, AllowedIndicesFilterAllowsIndexesByName) {
TEST(QuerySettingsTest, AllowedIndicesFilterAllowsIndexesByKeyPattern) {
SimpleBSONObjComparator bsonCmp;
AllowedIndicesFilter filter(bsonCmp.makeBSONObjSet({fromjson("{a:1}")}), {"a"});
- IndexEntry a_idx(
- fromjson("{a:1}"), false, false, false, IndexEntry::Identifier{"foo"}, nullptr, BSONObj());
- IndexEntry ab_idx(fromjson("{a:1, b:1}"),
+ auto keyPat_a = fromjson("{a:1}");
+ IndexEntry a_idx(keyPat_a,
+ mongo::IndexNames::nameToType(mongo::IndexNames::findPluginName(keyPat_a)),
+ false,
+ {},
+ {},
+ false,
+ false,
+ IndexEntry::Identifier{"foo"},
+ nullptr,
+ BSONObj(),
+ nullptr,
+ nullptr);
+ auto keyPat_ab = fromjson("{a:1, b:1}");
+ IndexEntry ab_idx(keyPat_ab,
+ mongo::IndexNames::nameToType(mongo::IndexNames::findPluginName(keyPat_ab)),
false,
+ {},
+ {},
false,
false,
IndexEntry::Identifier{"bar"},
nullptr,
- BSONObj());
+ BSONObj(),
+ nullptr,
+ nullptr);
ASSERT_TRUE(filter.allows(a_idx));
ASSERT_FALSE(filter.allows(ab_idx));
diff --git a/src/mongo/db/query/query_solution_test.cpp b/src/mongo/db/query/query_solution_test.cpp
index 0e05968f887..c8555503e7c 100644
--- a/src/mongo/db/query/query_solution_test.cpp
+++ b/src/mongo/db/query/query_solution_test.cpp
@@ -44,11 +44,30 @@ namespace {
using namespace mongo;
+/**
+ * Make a minimal IndexEntry from just a key pattern. A dummy name will be added.
+ */
+IndexEntry buildSimpleIndexEntry(const BSONObj& kp) {
+ return {kp,
+ IndexNames::nameToType(IndexNames::findPluginName(kp)),
+ false,
+ {},
+ {},
+ false,
+ false,
+ CoreIndexInfo::Identifier("test_foo"),
+ nullptr,
+ {},
+ nullptr,
+ nullptr};
+}
+
// Index: {a: 1, b: 1, c: 1, d: 1, e: 1}
// Min: {a: 1, b: 1, c: 1, d: 1, e: 1}
// Max: {a: 1, b: 1, c: 1, d: 1, e: 1}
TEST(QuerySolutionTest, SimpleRangeAllEqual) {
- IndexScanNode node{IndexEntry(BSON("a" << 1 << "b" << 1 << "c" << 1 << "d" << 1 << "e" << 1))};
+ IndexScanNode node{
+ buildSimpleIndexEntry(BSON("a" << 1 << "b" << 1 << "c" << 1 << "d" << 1 << "e" << 1))};
node.bounds.isSimpleRange = true;
node.bounds.startKey = BSON("a" << 1 << "b" << 1 << "c" << 1 << "d" << 1 << "e" << 1);
node.bounds.endKey = BSON("a" << 1 << "b" << 1 << "c" << 1 << "d" << 1 << "e" << 1);
@@ -71,7 +90,8 @@ TEST(QuerySolutionTest, SimpleRangeAllEqual) {
// Min: {a: 1, b: 1, c: 1, d: 1, e: 1}
// Max: {a: 2, b: 2, c: 2, d: 2, e: 2}
TEST(QuerySolutionTest, SimpleRangeNoneEqual) {
- IndexScanNode node{IndexEntry(BSON("a" << 1 << "b" << 1 << "c" << 1 << "d" << 1 << "e" << 1))};
+ IndexScanNode node{
+ buildSimpleIndexEntry(BSON("a" << 1 << "b" << 1 << "c" << 1 << "d" << 1 << "e" << 1))};
node.bounds.isSimpleRange = true;
node.bounds.startKey = BSON("a" << 1 << "b" << 1 << "c" << 1 << "d" << 1 << "e" << 1);
node.bounds.endKey = BSON("a" << 2 << "b" << 2 << "c" << 2 << "d" << 2 << "e" << 2);
@@ -90,7 +110,8 @@ TEST(QuerySolutionTest, SimpleRangeNoneEqual) {
// Min: {a: 1, b: 1, c: 1, d: 1, e: 1}
// Max: {a: 1, b: 1, c: 2, d: 2, e: 2}
TEST(QuerySolutionTest, SimpleRangeSomeEqual) {
- IndexScanNode node{IndexEntry(BSON("a" << 1 << "b" << 1 << "c" << 1 << "d" << 1 << "e" << 1))};
+ IndexScanNode node{
+ buildSimpleIndexEntry(BSON("a" << 1 << "b" << 1 << "c" << 1 << "d" << 1 << "e" << 1))};
node.bounds.isSimpleRange = true;
node.bounds.startKey = BSON("a" << 1 << "b" << 1 << "c" << 1 << "d" << 1 << "e" << 1);
node.bounds.endKey = BSON("a" << 1 << "b" << 1 << "c" << 2 << "d" << 2 << "e" << 2);
@@ -112,7 +133,8 @@ TEST(QuerySolutionTest, SimpleRangeSomeEqual) {
// Index: {a: 1, b: 1, c: 1, d: 1, e: 1}
// Intervals: a: [1,1], b: [1,1], c: [1,1], d: [1,1], e: [1,1]
TEST(QuerySolutionTest, IntervalListAllPoints) {
- IndexScanNode node{IndexEntry(BSON("a" << 1 << "b" << 1 << "c" << 1 << "d" << 1 << "e" << 1))};
+ IndexScanNode node{
+ buildSimpleIndexEntry(BSON("a" << 1 << "b" << 1 << "c" << 1 << "d" << 1 << "e" << 1))};
OrderedIntervalList a{};
a.name = "a";
@@ -158,7 +180,8 @@ TEST(QuerySolutionTest, IntervalListAllPoints) {
// Index: {a: 1, b: 1, c: 1, d: 1, e: 1}
// Intervals: a: [1,2], b: [1,2], c: [1,2], d: [1,2], e: [1,2]
TEST(QuerySolutionTest, IntervalListNoPoints) {
- IndexScanNode node{IndexEntry(BSON("a" << 1 << "b" << 1 << "c" << 1 << "d" << 1 << "e" << 1))};
+ IndexScanNode node{
+ buildSimpleIndexEntry(BSON("a" << 1 << "b" << 1 << "c" << 1 << "d" << 1 << "e" << 1))};
OrderedIntervalList a{};
a.name = "a";
@@ -204,7 +227,8 @@ TEST(QuerySolutionTest, IntervalListNoPoints) {
// Index: {a: 1, b: 1, c: 1, d: 1, e: 1}
// Intervals: a: [1,1], b: [1,1], c: [1,2], d: [1,2], e: [1,2]
TEST(QuerySolutionTest, IntervalListSomePoints) {
- IndexScanNode node{IndexEntry(BSON("a" << 1 << "b" << 1 << "c" << 1 << "d" << 1 << "e" << 1))};
+ IndexScanNode node{
+ buildSimpleIndexEntry(BSON("a" << 1 << "b" << 1 << "c" << 1 << "d" << 1 << "e" << 1))};
OrderedIntervalList a{};
a.name = "a";
@@ -420,7 +444,7 @@ TEST(QuerySolutionTest, GetFieldsWithStringBoundsIdentifiesStringsWithInclusiveB
}
TEST(QuerySolutionTest, IndexScanNodeRemovesNonMatchingCollatedFieldsFromSortsOnSimpleBounds) {
- IndexScanNode node{IndexEntry(BSON("a" << 1 << "b" << 1))};
+ IndexScanNode node{buildSimpleIndexEntry(BSON("a" << 1 << "b" << 1))};
CollatorInterfaceMock queryCollator(CollatorInterfaceMock::MockType::kReverseString);
node.queryCollator = &queryCollator;
@@ -437,7 +461,7 @@ TEST(QuerySolutionTest, IndexScanNodeRemovesNonMatchingCollatedFieldsFromSortsOn
}
TEST(QuerySolutionTest, IndexScanNodeGetFieldsWithStringBoundsCorrectlyHandlesEndKeyInclusive) {
- IndexScanNode node{IndexEntry(BSON("a" << 1 << "b" << 1))};
+ IndexScanNode node{buildSimpleIndexEntry(BSON("a" << 1 << "b" << 1))};
CollatorInterfaceMock queryCollator(CollatorInterfaceMock::MockType::kReverseString);
node.queryCollator = &queryCollator;
@@ -467,7 +491,7 @@ TEST(QuerySolutionTest, IndexScanNodeGetFieldsWithStringBoundsCorrectlyHandlesEn
// Index: {a: 1}
// Bounds: [MINKEY, MAXKEY]
TEST(QuerySolutionTest, IndexScanNodeRemovesCollatedFieldsFromSortsIfCollationDifferent) {
- IndexScanNode node{IndexEntry(BSON("a" << 1))};
+ IndexScanNode node{buildSimpleIndexEntry(BSON("a" << 1))};
CollatorInterfaceMock queryCollator(CollatorInterfaceMock::MockType::kReverseString);
node.queryCollator = &queryCollator;
@@ -484,7 +508,7 @@ TEST(QuerySolutionTest, IndexScanNodeRemovesCollatedFieldsFromSortsIfCollationDi
}
TEST(QuerySolutionTest, IndexScanNodeDoesNotRemoveCollatedFieldsFromSortsIfCollationMatches) {
- IndexScanNode node{IndexEntry(BSON("a" << 1))};
+ IndexScanNode node{buildSimpleIndexEntry(BSON("a" << 1))};
CollatorInterfaceMock queryCollator(CollatorInterfaceMock::MockType::kReverseString);
OrderedIntervalList oilA{};
@@ -503,11 +527,13 @@ TEST(QuerySolutionTest, IndexScanNodeDoesNotRemoveCollatedFieldsFromSortsIfColla
// Index: {a: 1, b: 1, c: 1, d: 1, e: 1}
// Intervals: a: [1,1], b: [1,1], c: [MinKey, MaxKey], d: [1,2], e: [1,2]
TEST(QuerySolutionTest, CompoundIndexWithNonMatchingCollationFiltersAllSortsWithCollatedField) {
- IndexScanNode node{IndexEntry(BSON("a" << 1 << "b" << 1 << "c" << 1 << "d" << 1 << "e" << 1))};
+ IndexScanNode node{
+ buildSimpleIndexEntry(BSON("a" << 1 << "b" << 1 << "c" << 1 << "d" << 1 << "e" << 1))};
CollatorInterfaceMock queryCollator(CollatorInterfaceMock::MockType::kReverseString);
node.queryCollator = &queryCollator;
- node.index = IndexEntry(BSON("a" << 1 << "b" << 1 << "c" << 1 << "d" << 1 << "e" << 1));
+ node.index =
+ buildSimpleIndexEntry(BSON("a" << 1 << "b" << 1 << "c" << 1 << "d" << 1 << "e" << 1));
OrderedIntervalList a{};
a.name = "a";
@@ -548,7 +574,7 @@ TEST(QuerySolutionTest, CompoundIndexWithNonMatchingCollationFiltersAllSortsWith
// Index: {a : 1}
// Bounds: [{}, {}]
TEST(QuerySolutionTest, IndexScanNodeWithNonMatchingCollationFiltersObjectField) {
- IndexScanNode node{IndexEntry(BSON("a" << 1))};
+ IndexScanNode node{buildSimpleIndexEntry(BSON("a" << 1))};
CollatorInterfaceMock queryCollator(CollatorInterfaceMock::MockType::kReverseString);
node.queryCollator = &queryCollator;
@@ -568,7 +594,7 @@ TEST(QuerySolutionTest, IndexScanNodeWithNonMatchingCollationFiltersObjectField)
// Index: {a : 1}
// Bounds: [[], []]
TEST(QuerySolutionTest, IndexScanNodeWithNonMatchingCollationFiltersArrayField) {
- IndexScanNode node{IndexEntry(BSON("a" << 1))};
+ IndexScanNode node{buildSimpleIndexEntry(BSON("a" << 1))};
CollatorInterfaceMock queryCollator(CollatorInterfaceMock::MockType::kReverseString);
node.queryCollator = &queryCollator;
@@ -586,7 +612,7 @@ TEST(QuerySolutionTest, IndexScanNodeWithNonMatchingCollationFiltersArrayField)
}
TEST(QuerySolutionTest, WithNonMatchingCollatorAndNoEqualityPrefixSortsAreNotDuplicated) {
- IndexScanNode node{IndexEntry(BSON("a" << 1 << "b" << 1))};
+ IndexScanNode node{buildSimpleIndexEntry(BSON("a" << 1 << "b" << 1))};
CollatorInterfaceMock queryCollator(CollatorInterfaceMock::MockType::kReverseString);
node.queryCollator = &queryCollator;
@@ -614,7 +640,7 @@ TEST(QuerySolutionTest, WithNonMatchingCollatorAndNoEqualityPrefixSortsAreNotDup
}
TEST(QuerySolutionTest, IndexScanNodeHasFieldIncludesStringFieldWhenNoCollator) {
- IndexScanNode node{IndexEntry(BSON("a" << 1 << "b" << 1))};
+ IndexScanNode node{buildSimpleIndexEntry(BSON("a" << 1 << "b" << 1))};
OrderedIntervalList oilA{};
oilA.name = "a";
@@ -636,7 +662,7 @@ TEST(QuerySolutionTest, IndexScanNodeHasFieldIncludesStringFieldWhenNoCollator)
}
TEST(QuerySolutionTest, IndexScanNodeHasFieldIncludesSimpleBoundsStringFieldWhenNoCollator) {
- IndexScanNode node{IndexEntry(BSON("a" << 1 << "b" << 1))};
+ IndexScanNode node{buildSimpleIndexEntry(BSON("a" << 1 << "b" << 1))};
node.bounds.isSimpleRange = true;
node.bounds.startKey = BSON("a" << 1 << "b" << 2);
@@ -648,7 +674,7 @@ TEST(QuerySolutionTest, IndexScanNodeHasFieldIncludesSimpleBoundsStringFieldWhen
}
TEST(QuerySolutionTest, IndexScanNodeHasFieldExcludesStringFieldWhenIndexHasCollator) {
- IndexScanNode node{IndexEntry(BSON("a" << 1 << "b" << 1))};
+ IndexScanNode node{buildSimpleIndexEntry(BSON("a" << 1 << "b" << 1))};
CollatorInterfaceMock indexCollator(CollatorInterfaceMock::MockType::kReverseString);
node.index.collator = &indexCollator;
@@ -673,7 +699,7 @@ TEST(QuerySolutionTest, IndexScanNodeHasFieldExcludesStringFieldWhenIndexHasColl
}
TEST(QuerySolutionTest, IndexScanNodeHasFieldExcludesSimpleBoundsStringFieldWhenIndexHasCollator) {
- IndexScanNode node{IndexEntry(BSON("a" << 1 << "b" << 1))};
+ IndexScanNode node{buildSimpleIndexEntry(BSON("a" << 1 << "b" << 1))};
CollatorInterfaceMock indexCollator(CollatorInterfaceMock::MockType::kReverseString);
node.index.collator = &indexCollator;
@@ -710,7 +736,7 @@ std::unique_ptr<ParsedProjection> createParsedProjection(const BSONObj& query,
}
TEST(QuerySolutionTest, InclusionProjectionPreservesSort) {
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
auto node = stdx::make_unique<IndexScanNode>(index);
BSONObj projection = BSON("a" << 1);
@@ -727,7 +753,7 @@ TEST(QuerySolutionTest, InclusionProjectionPreservesSort) {
}
TEST(QuerySolutionTest, ExclusionProjectionDoesNotPreserveSort) {
- IndexEntry index(BSON("a" << 1));
+ auto index = buildSimpleIndexEntry(BSON("a" << 1));
auto node = stdx::make_unique<IndexScanNode>(index);
BSONObj projection = BSON("a" << 0);
@@ -743,7 +769,7 @@ TEST(QuerySolutionTest, ExclusionProjectionDoesNotPreserveSort) {
}
TEST(QuerySolutionTest, InclusionProjectionTruncatesSort) {
- auto node = stdx::make_unique<IndexScanNode>(IndexEntry(BSON("a" << 1 << "b" << 1)));
+ auto node = stdx::make_unique<IndexScanNode>(buildSimpleIndexEntry(BSON("a" << 1 << "b" << 1)));
BSONObj projection = BSON("a" << 1);
BSONObj match;
@@ -759,7 +785,7 @@ TEST(QuerySolutionTest, InclusionProjectionTruncatesSort) {
}
TEST(QuerySolutionTest, ExclusionProjectionTruncatesSort) {
- auto node = stdx::make_unique<IndexScanNode>(IndexEntry(BSON("a" << 1 << "b" << 1)));
+ auto node = stdx::make_unique<IndexScanNode>(buildSimpleIndexEntry(BSON("a" << 1 << "b" << 1)));
BSONObj projection = BSON("b" << 0);
BSONObj match;
@@ -775,7 +801,8 @@ TEST(QuerySolutionTest, ExclusionProjectionTruncatesSort) {
}
TEST(QuerySolutionTest, NonMultikeyIndexWithoutPathLevelInfoCanCoverItsFields) {
- auto node = stdx::make_unique<IndexScanNode>(IndexEntry(BSON("a" << 1 << "b.c.d" << 1)));
+ auto node =
+ stdx::make_unique<IndexScanNode>(buildSimpleIndexEntry(BSON("a" << 1 << "b.c.d" << 1)));
node->index.multikey = false;
node->index.multikeyPaths = MultikeyPaths{};
ASSERT_TRUE(node->hasField("a"));
@@ -786,7 +813,8 @@ TEST(QuerySolutionTest, NonMultikeyIndexWithoutPathLevelInfoCanCoverItsFields) {
}
TEST(QuerySolutionTest, NonMultikeyIndexWithPathLevelInfoCanCoverItsFields) {
- auto node = stdx::make_unique<IndexScanNode>(IndexEntry(BSON("a" << 1 << "b.c.d" << 1)));
+ auto node =
+ stdx::make_unique<IndexScanNode>(buildSimpleIndexEntry(BSON("a" << 1 << "b.c.d" << 1)));
node->index.multikey = false;
node->index.multikeyPaths = MultikeyPaths{{}, {}};
ASSERT_TRUE(node->hasField("a"));
@@ -797,7 +825,8 @@ TEST(QuerySolutionTest, NonMultikeyIndexWithPathLevelInfoCanCoverItsFields) {
}
TEST(QuerySolutionTest, MultikeyIndexWithoutPathLevelInfoCannotCoverAnyFields) {
- auto node = stdx::make_unique<IndexScanNode>(IndexEntry(BSON("a" << 1 << "b.c.d" << 1)));
+ auto node =
+ stdx::make_unique<IndexScanNode>(buildSimpleIndexEntry(BSON("a" << 1 << "b.c.d" << 1)));
node->index.multikey = true;
node->index.multikeyPaths = MultikeyPaths{};
ASSERT_FALSE(node->hasField("a"));
@@ -808,8 +837,8 @@ TEST(QuerySolutionTest, MultikeyIndexWithoutPathLevelInfoCannotCoverAnyFields) {
}
TEST(QuerySolutionTest, MultikeyIndexWithPathLevelInfoCanCoverNonMultikeyFields) {
- auto node =
- stdx::make_unique<IndexScanNode>(IndexEntry(BSON("a" << 1 << "b" << 1 << "c" << 1)));
+ auto node = stdx::make_unique<IndexScanNode>(
+ buildSimpleIndexEntry(BSON("a" << 1 << "b" << 1 << "c" << 1)));
// Add metadata indicating that "b" is multikey.
node->index.multikey = true;
@@ -822,8 +851,8 @@ TEST(QuerySolutionTest, MultikeyIndexWithPathLevelInfoCanCoverNonMultikeyFields)
}
TEST(QuerySolutionTest, MultikeyIndexCannotCoverFieldWithAnyMultikeyPathComponent) {
- auto node =
- stdx::make_unique<IndexScanNode>(IndexEntry(BSON("a" << 1 << "b.c.d" << 1 << "e" << 1)));
+ auto node = stdx::make_unique<IndexScanNode>(
+ buildSimpleIndexEntry(BSON("a" << 1 << "b.c.d" << 1 << "e" << 1)));
// Add metadata indicating that "b.c" is multikey.
node->index.multikey = true;
@@ -837,7 +866,7 @@ TEST(QuerySolutionTest, MultikeyIndexCannotCoverFieldWithAnyMultikeyPathComponen
}
TEST(QuerySolutionTest, MultikeyIndexWithoutPathLevelInfoCannotProvideAnySorts) {
- IndexScanNode node{IndexEntry(BSON("a" << 1 << "b" << 1 << "c" << 1))};
+ IndexScanNode node{buildSimpleIndexEntry(BSON("a" << 1 << "b" << 1 << "c" << 1))};
node.index.multikey = true;
{
@@ -861,7 +890,7 @@ TEST(QuerySolutionTest, MultikeyIndexWithoutPathLevelInfoCannotProvideAnySorts)
TEST(QuerySolutionTest, SimpleRangeAllEqualExcludesFieldWithMultikeyComponent) {
IndexScanNode node{
- IndexEntry(BSON("a" << 1 << "b" << 1 << "c.z" << 1 << "d" << 1 << "e" << 1))};
+ buildSimpleIndexEntry(BSON("a" << 1 << "b" << 1 << "c.z" << 1 << "d" << 1 << "e" << 1))};
node.bounds.isSimpleRange = true;
node.bounds.startKey = BSON("a" << 1 << "b" << 1 << "c.z" << 1 << "d" << 1 << "e" << 1);
node.bounds.endKey = BSON("a" << 1 << "b" << 1 << "c.z" << 1 << "d" << 1 << "e" << 1);
@@ -880,7 +909,7 @@ TEST(QuerySolutionTest, SimpleRangeAllEqualExcludesFieldWithMultikeyComponent) {
}
TEST(QuerySolutionTest, MultikeyFieldsEmptyWhenIndexIsNotMultikey) {
- IndexScanNode node{IndexEntry(BSON("a.b" << 1 << "c.d" << 1))};
+ IndexScanNode node{buildSimpleIndexEntry(BSON("a.b" << 1 << "c.d" << 1))};
node.index.multikey = false;
node.index.multikeyPaths = MultikeyPaths{};
node.computeProperties();
@@ -888,7 +917,7 @@ TEST(QuerySolutionTest, MultikeyFieldsEmptyWhenIndexIsNotMultikey) {
}
TEST(QuerySolutionTest, MultikeyFieldsEmptyWhenIndexHasNoMultikeynessMetadata) {
- IndexScanNode node{IndexEntry(BSON("a.b" << 1 << "c.d" << 1))};
+ IndexScanNode node{buildSimpleIndexEntry(BSON("a.b" << 1 << "c.d" << 1))};
node.index.multikey = true;
node.index.multikeyPaths = MultikeyPaths{};
node.computeProperties();
@@ -896,7 +925,7 @@ TEST(QuerySolutionTest, MultikeyFieldsEmptyWhenIndexHasNoMultikeynessMetadata) {
}
TEST(QuerySolutionTest, MultikeyFieldsChosenCorrectlyWhenIndexHasPathLevelMultikeyMetadata) {
- IndexScanNode node{IndexEntry(BSON("a.b" << 1 << "c.d" << 1 << "e.f" << 1))};
+ IndexScanNode node{buildSimpleIndexEntry(BSON("a.b" << 1 << "c.d" << 1 << "e.f" << 1))};
node.index.multikey = true;
node.index.multikeyPaths = MultikeyPaths{{0U}, {}, {0U, 1U}};
node.computeProperties();
@@ -907,7 +936,7 @@ TEST(QuerySolutionTest, MultikeyFieldsChosenCorrectlyWhenIndexHasPathLevelMultik
TEST(QuerySolutionTest, NonSimpleRangeAllEqualExcludesFieldWithMultikeyComponent) {
IndexScanNode node{
- IndexEntry(BSON("a" << 1 << "b" << 1 << "c.z" << 1 << "d" << 1 << "e" << 1))};
+ buildSimpleIndexEntry(BSON("a" << 1 << "b" << 1 << "c.z" << 1 << "d" << 1 << "e" << 1))};
// Add metadata indicating that "c.z" is multikey.
node.index.multikey = true;
node.index.multikeyPaths = MultikeyPaths{{}, {}, {1U}, {}, {}};