summaryrefslogtreecommitdiff
path: root/src/mongo/db/query
diff options
context:
space:
mode:
authorJames Wahlin <james@mongodb.com>2018-10-01 16:05:08 -0400
committerJames Wahlin <james@mongodb.com>2018-10-02 09:56:37 -0400
commitf7ddb89c8caf438781de9191d690d03f711b63fe (patch)
tree9244266869d8c17de23d5e0c817a2fddc2bc849a /src/mongo/db/query
parent5a6ee566f608c46654133de17a4e8bb3464d680d (diff)
downloadmongo-f7ddb89c8caf438781de9191d690d03f711b63fe.tar.gz
SERVER-37188 Rename "All Paths" index to "Wildcard" index
Diffstat (limited to 'src/mongo/db/query')
-rw-r--r--src/mongo/db/query/SConscript4
-rw-r--r--src/mongo/db/query/get_executor.cpp2
-rw-r--r--src/mongo/db/query/index_bounds_builder.cpp8
-rw-r--r--src/mongo/db/query/index_entry.h2
-rw-r--r--src/mongo/db/query/plan_cache.cpp8
-rw-r--r--src/mongo/db/query/plan_cache_indexability.cpp30
-rw-r--r--src/mongo/db/query/plan_cache_indexability.h14
-rw-r--r--src/mongo/db/query/plan_cache_indexability_test.cpp22
-rw-r--r--src/mongo/db/query/plan_cache_test.cpp10
-rw-r--r--src/mongo/db/query/planner_access.cpp18
-rw-r--r--src/mongo/db/query/planner_access.h2
-rw-r--r--src/mongo/db/query/planner_ixselect.cpp58
-rw-r--r--src/mongo/db/query/planner_ixselect.h14
-rw-r--r--src/mongo/db/query/planner_ixselect_test.cpp96
-rw-r--r--src/mongo/db/query/planner_wildcard_helpers.cpp (renamed from src/mongo/db/query/planner_allpaths_helpers.cpp)20
-rw-r--r--src/mongo/db/query/planner_wildcard_helpers.h (renamed from src/mongo/db/query/planner_allpaths_helpers.h)12
-rw-r--r--src/mongo/db/query/query_planner.cpp8
-rw-r--r--src/mongo/db/query/query_planner_collation_test.cpp4
-rw-r--r--src/mongo/db/query/query_planner_wildcard_index_test.cpp (renamed from src/mongo/db/query/query_planner_all_paths_index_test.cpp)354
-rw-r--r--src/mongo/db/query/query_solution.cpp2
20 files changed, 344 insertions, 344 deletions
diff --git a/src/mongo/db/query/SConscript b/src/mongo/db/query/SConscript
index 3ce7ee94e67..64018a41388 100644
--- a/src/mongo/db/query/SConscript
+++ b/src/mongo/db/query/SConscript
@@ -24,7 +24,7 @@ env.Library(
"plan_cache_indexability.cpp",
"plan_enumerator.cpp",
"planner_access.cpp",
- "planner_allpaths_helpers.cpp",
+ "planner_wildcard_helpers.cpp",
"planner_analysis.cpp",
"planner_ixselect.cpp",
"query_planner.cpp",
@@ -341,12 +341,12 @@ env.CppUnitTest(
env.CppUnitTest(
target="query_planner_test",
source=[
- "query_planner_all_paths_index_test.cpp",
"query_planner_array_test.cpp",
"query_planner_collation_test.cpp",
"query_planner_geo_test.cpp",
"query_planner_partialidx_test.cpp",
"query_planner_test.cpp",
+ "query_planner_wildcard_index_test.cpp",
],
LIBDEPS=[
"collation/collator_interface_mock",
diff --git a/src/mongo/db/query/get_executor.cpp b/src/mongo/db/query/get_executor.cpp
index 958049fbdfd..161b73386dc 100644
--- a/src/mongo/db/query/get_executor.cpp
+++ b/src/mongo/db/query/get_executor.cpp
@@ -51,8 +51,8 @@
#include "mongo/db/exec/sort_key_generator.h"
#include "mongo/db/exec/subplan.h"
#include "mongo/db/exec/update.h"
-#include "mongo/db/index/all_paths_access_method.h"
#include "mongo/db/index/index_descriptor.h"
+#include "mongo/db/index/wildcard_access_method.h"
#include "mongo/db/index_names.h"
#include "mongo/db/matcher/extensions_callback_noop.h"
#include "mongo/db/matcher/extensions_callback_real.h"
diff --git a/src/mongo/db/query/index_bounds_builder.cpp b/src/mongo/db/query/index_bounds_builder.cpp
index 13d45890e72..fdfcfc2096c 100644
--- a/src/mongo/db/query/index_bounds_builder.cpp
+++ b/src/mongo/db/query/index_bounds_builder.cpp
@@ -45,8 +45,8 @@
#include "mongo/db/query/expression_index.h"
#include "mongo/db/query/expression_index_knobs.h"
#include "mongo/db/query/indexability.h"
-#include "mongo/db/query/planner_allpaths_helpers.h"
#include "mongo/db/query/planner_ixselect.h"
+#include "mongo/db/query/planner_wildcard_helpers.h"
#include "mongo/db/query/query_knobs.h"
#include "mongo/util/log.h"
#include "mongo/util/mongoutils/str.h"
@@ -57,7 +57,7 @@ namespace mongo {
namespace {
-namespace app = ::mongo::all_paths_planning;
+namespace app = ::mongo::wildcard_planning;
// Helper for checking that an OIL "appears" to be ascending given one interval.
void assertOILIsAscendingLocally(const vector<Interval>& intervals, size_t idx) {
@@ -344,8 +344,8 @@ void IndexBoundsBuilder::translate(const MatchExpression* expr,
// Under certain circumstances, queries on a $** index require that the bounds' tightness be
// adjusted regardless of the predicate. Having filled out the initial bounds, we apply any
// necessary changes to the tightness here.
- if (index.type == IndexType::INDEX_ALLPATHS) {
- *tightnessOut = app::applyAllPathsIndexScanBoundsTightness(index, *tightnessOut);
+ if (index.type == IndexType::INDEX_WILDCARD) {
+ *tightnessOut = app::applyWildcardIndexScanBoundsTightness(index, *tightnessOut);
}
}
diff --git a/src/mongo/db/query/index_entry.h b/src/mongo/db/query/index_entry.h
index c032b47d785..c028618394e 100644
--- a/src/mongo/db/query/index_entry.h
+++ b/src/mongo/db/query/index_entry.h
@@ -87,7 +87,7 @@ struct IndexEntry {
std::string catalogName;
// A string used for disambiguating multiple IndexEntries with the same catalogName (such
- // as in the case with an allPaths index).
+ // as in the case with a wildcard index).
std::string disambiguator;
};
diff --git a/src/mongo/db/query/plan_cache.cpp b/src/mongo/db/query/plan_cache.cpp
index 49020044448..4fccc01a648 100644
--- a/src/mongo/db/query/plan_cache.cpp
+++ b/src/mongo/db/query/plan_cache.cpp
@@ -326,16 +326,16 @@ void encodeIndexability(const MatchExpression* tree,
const IndexToDiscriminatorMap& discriminators =
indexabilityState.getDiscriminators(tree->path());
- IndexToDiscriminatorMap allPathsDiscriminators =
- indexabilityState.buildAllPathsDiscriminators(tree->path());
- if (discriminators.empty() && allPathsDiscriminators.empty()) {
+ IndexToDiscriminatorMap wildcardDiscriminators =
+ indexabilityState.buildWildcardDiscriminators(tree->path());
+ if (discriminators.empty() && wildcardDiscriminators.empty()) {
return;
}
*keyBuilder << kEncodeDiscriminatorsBegin;
// For each discriminator on this path, append the character '0' or '1'.
encodeIndexabilityForDiscriminators(tree, discriminators, keyBuilder);
- encodeIndexabilityForDiscriminators(tree, allPathsDiscriminators, keyBuilder);
+ encodeIndexabilityForDiscriminators(tree, wildcardDiscriminators, keyBuilder);
*keyBuilder << kEncodeDiscriminatorsEnd;
}
diff --git a/src/mongo/db/query/plan_cache_indexability.cpp b/src/mongo/db/query/plan_cache_indexability.cpp
index 353c5c87fe3..462b4ecedc1 100644
--- a/src/mongo/db/query/plan_cache_indexability.cpp
+++ b/src/mongo/db/query/plan_cache_indexability.cpp
@@ -32,7 +32,7 @@
#include "mongo/base/init.h"
#include "mongo/base/owned_pointer_vector.h"
-#include "mongo/db/index/all_paths_key_generator.h"
+#include "mongo/db/index/wildcard_key_generator.h"
#include "mongo/db/matcher/expression.h"
#include "mongo/db/matcher/expression_algo.h"
#include "mongo/db/matcher/expression_internal_expr_eq.h"
@@ -112,11 +112,11 @@ void PlanCacheIndexabilityState::processPartialIndex(const std::string& indexNam
}
}
-void PlanCacheIndexabilityState::processAllPathsIndex(const IndexEntry& ie) {
- invariant(ie.type == IndexType::INDEX_ALLPATHS);
+void PlanCacheIndexabilityState::processWildcardIndex(const IndexEntry& ie) {
+ invariant(ie.type == IndexType::INDEX_WILDCARD);
- _allPathsIndexDiscriminators.emplace_back(
- AllPathsKeyGenerator::createProjectionExec(ie.keyPattern,
+ _wildcardIndexDiscriminators.emplace_back(
+ WildcardKeyGenerator::createProjectionExec(ie.keyPattern,
ie.infoObj.getObjectField("wildcardProjection")),
ie.identifier.catalogName,
ie.filterExpr,
@@ -145,23 +145,23 @@ const IndexToDiscriminatorMap& PlanCacheIndexabilityState::getDiscriminators(
return it->second;
}
-IndexToDiscriminatorMap PlanCacheIndexabilityState::buildAllPathsDiscriminators(
+IndexToDiscriminatorMap PlanCacheIndexabilityState::buildWildcardDiscriminators(
StringData path) const {
IndexToDiscriminatorMap ret;
- for (auto&& allPathsDiscriminator : _allPathsIndexDiscriminators) {
- if (allPathsDiscriminator.projectionExec->applyProjectionToOneField(path)) {
- CompositeIndexabilityDiscriminator& cid = ret[allPathsDiscriminator.catalogName];
+ for (auto&& wildcardDiscriminator : _wildcardIndexDiscriminators) {
+ if (wildcardDiscriminator.projectionExec->applyProjectionToOneField(path)) {
+ CompositeIndexabilityDiscriminator& cid = ret[wildcardDiscriminator.catalogName];
// We can use these 'shallow' functions because the code building the plan cache key
// will descend the match expression for us, and check the discriminator's return value
// at each node.
- cid.addDiscriminator(QueryPlannerIXSelect::nodeIsSupportedByAllPathsIndex);
+ cid.addDiscriminator(QueryPlannerIXSelect::nodeIsSupportedByWildcardIndex);
cid.addDiscriminator(nodeIsConservativelySupportedBySparseIndex);
- cid.addDiscriminator(getCollatedIndexDiscriminator(allPathsDiscriminator.collator));
- if (allPathsDiscriminator.filterExpr) {
+ cid.addDiscriminator(getCollatedIndexDiscriminator(wildcardDiscriminator.collator));
+ if (wildcardDiscriminator.filterExpr) {
cid.addDiscriminator(
- getPartialIndexDiscriminator(allPathsDiscriminator.filterExpr));
+ getPartialIndexDiscriminator(wildcardDiscriminator.filterExpr));
}
}
}
@@ -172,8 +172,8 @@ void PlanCacheIndexabilityState::updateDiscriminators(const std::vector<IndexEnt
_pathDiscriminatorsMap = PathDiscriminatorsMap();
for (const IndexEntry& idx : indexEntries) {
- if (idx.type == IndexType::INDEX_ALLPATHS) {
- processAllPathsIndex(idx);
+ 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 7f43a60cace..a79aceaef3d 100644
--- a/src/mongo/db/query/plan_cache_indexability.h
+++ b/src/mongo/db/query/plan_cache_indexability.h
@@ -96,10 +96,10 @@ public:
const IndexToDiscriminatorMap& getDiscriminators(StringData path) const;
/**
- * Construct an IndexToDiscriminator map for the given path, only for the allPaths indexes
+ * Construct an IndexToDiscriminator map for the given path, only for the wildcard indexes
* which have been included in the indexability state.
*/
- IndexToDiscriminatorMap buildAllPathsDiscriminators(StringData path) const;
+ IndexToDiscriminatorMap buildWildcardDiscriminators(StringData path) const;
/**
* Clears discriminators for all paths, and regenerate them from 'indexEntries'.
@@ -114,8 +114,8 @@ private:
* every possible field that it indexes, so we have to maintain some special context about the
* index.
*/
- struct AllPathsIndexDiscriminatorContext {
- AllPathsIndexDiscriminatorContext(std::unique_ptr<ProjectionExecAgg> proj,
+ struct WildcardIndexDiscriminatorContext {
+ WildcardIndexDiscriminatorContext(std::unique_ptr<ProjectionExecAgg> proj,
std::string name,
const MatchExpression* filter,
const CollatorInterface* coll)
@@ -169,15 +169,15 @@ private:
/**
* Adds special state for a $** index. When the discriminators are retrieved for a certain
- * path, appropriate discriminators for the allPaths index will be included if it includes the
+ * path, appropriate discriminators for the wildcard index will be included if it includes the
* given path.
*/
- void processAllPathsIndex(const IndexEntry& ie);
+ void processWildcardIndex(const IndexEntry& ie);
// PathDiscriminatorsMap is a map from field path to index name to IndexabilityDiscriminator.
PathDiscriminatorsMap _pathDiscriminatorsMap;
- std::vector<AllPathsIndexDiscriminatorContext> _allPathsIndexDiscriminators;
+ std::vector<WildcardIndexDiscriminatorContext> _wildcardIndexDiscriminators;
};
} // namespace mongo
diff --git a/src/mongo/db/query/plan_cache_indexability_test.cpp b/src/mongo/db/query/plan_cache_indexability_test.cpp
index 6531b5cae30..f0775219d26 100644
--- a/src/mongo/db/query/plan_cache_indexability_test.cpp
+++ b/src/mongo/db/query/plan_cache_indexability_test.cpp
@@ -409,7 +409,7 @@ TEST(PlanCacheIndexabilityTest, CompoundIndexCollationDiscriminator) {
ASSERT(discriminatorsB.find("a_1_b_1") != discriminatorsB.end());
}
-TEST(PlanCacheIndexabilityTest, AllPathsDiscriminator) {
+TEST(PlanCacheIndexabilityTest, WildcardDiscriminator) {
PlanCacheIndexabilityState state;
state.updateDiscriminators({IndexEntry(BSON("a.$**" << 1),
false, // multikey
@@ -419,10 +419,10 @@ TEST(PlanCacheIndexabilityTest, AllPathsDiscriminator) {
nullptr,
BSONObj())});
- const auto unindexedPathDiscriminators = state.buildAllPathsDiscriminators("notIndexed");
+ const auto unindexedPathDiscriminators = state.buildWildcardDiscriminators("notIndexed");
ASSERT_EQ(0U, unindexedPathDiscriminators.size());
- auto discriminatorsA = state.buildAllPathsDiscriminators("a");
+ auto discriminatorsA = state.buildWildcardDiscriminators("a");
ASSERT_EQ(1U, discriminatorsA.size());
ASSERT(discriminatorsA.find("indexName") != discriminatorsA.end());
@@ -431,16 +431,16 @@ TEST(PlanCacheIndexabilityTest, AllPathsDiscriminator) {
ASSERT_TRUE(
disc.isMatchCompatibleWithIndex(parseMatchExpression(fromjson("{a: 'abc'}")).get()));
- // Querying for object values isn't support by allPaths indexes.
+ // Querying for object values isn't support by wildcard indexes.
ASSERT_FALSE(
disc.isMatchCompatibleWithIndex(parseMatchExpression(fromjson("{a: {b: 1}}")).get()));
ASSERT_FALSE(disc.isMatchCompatibleWithIndex(parseMatchExpression(fromjson("{a: {}}")).get()));
ASSERT_FALSE(
disc.isMatchCompatibleWithIndex(parseMatchExpression(fromjson("{a: {$lt: {}}}")).get()));
- // Querying for array values isn't supported by allPaths indexes.
+ // Querying for array values isn't supported by wildcard indexes.
ASSERT_FALSE(
disc.isMatchCompatibleWithIndex(parseMatchExpression(fromjson("{a: [1, 2, 3]}")).get()));
- // Querying for null isn't supported by allPaths indexes.
+ // Querying for null isn't supported by wildcard indexes.
ASSERT_FALSE(
disc.isMatchCompatibleWithIndex(parseMatchExpression(fromjson("{a: null}")).get()));
@@ -470,7 +470,7 @@ TEST(PlanCacheIndexabilityTest, AllPathsDiscriminator) {
parseMatchExpression(fromjson("{a: {$in: [1, 2, null]}}")).get()));
}
-TEST(PlanCacheIndexabilityTest, AllPathsWithCollationDiscriminator) {
+TEST(PlanCacheIndexabilityTest, WildcardWithCollationDiscriminator) {
PlanCacheIndexabilityState state;
IndexEntry entry(BSON("a.$**" << 1),
false, // multikey
@@ -483,10 +483,10 @@ TEST(PlanCacheIndexabilityTest, AllPathsWithCollationDiscriminator) {
entry.collator = &collator;
state.updateDiscriminators({entry});
- const auto unindexedPathDiscriminators = state.buildAllPathsDiscriminators("notIndexed");
+ const auto unindexedPathDiscriminators = state.buildWildcardDiscriminators("notIndexed");
ASSERT_EQ(0U, unindexedPathDiscriminators.size());
- auto discriminatorsA = state.buildAllPathsDiscriminators("a");
+ auto discriminatorsA = state.buildWildcardDiscriminators("a");
ASSERT_EQ(1U, discriminatorsA.size());
ASSERT(discriminatorsA.find("indexName") != discriminatorsA.end());
@@ -500,7 +500,7 @@ TEST(PlanCacheIndexabilityTest, AllPathsWithCollationDiscriminator) {
parseMatchExpression(fromjson("{a: \"hello world\"}"), &collator).get()));
}
-TEST(PlanCacheIndexabilityTest, AllPathsPartialIndexDiscriminator) {
+TEST(PlanCacheIndexabilityTest, WildcardPartialIndexDiscriminator) {
PlanCacheIndexabilityState state;
// Need to keep the filter BSON object around for the duration of the test since the match
@@ -516,7 +516,7 @@ TEST(PlanCacheIndexabilityTest, AllPathsPartialIndexDiscriminator) {
BSONObj());
state.updateDiscriminators({entry});
- auto discriminatorsA = state.buildAllPathsDiscriminators("a");
+ auto discriminatorsA = state.buildWildcardDiscriminators("a");
ASSERT_EQ(1U, discriminatorsA.size());
ASSERT(discriminatorsA.find("indexName") != discriminatorsA.end());
diff --git a/src/mongo/db/query/plan_cache_test.cpp b/src/mongo/db/query/plan_cache_test.cpp
index f72c3ab15dc..f971200edbf 100644
--- a/src/mongo/db/query/plan_cache_test.cpp
+++ b/src/mongo/db/query/plan_cache_test.cpp
@@ -1271,9 +1271,9 @@ TEST_F(CachePlanSelectionTest, AndWithinPolygonWithinCenterSphere) {
}
// $** index
-TEST_F(CachePlanSelectionTest, AllPathsIxScan) {
+TEST_F(CachePlanSelectionTest, WildcardIxScan) {
params.indices.push_back(IndexEntry(BSON("$**" << 1),
- IndexType::INDEX_ALLPATHS,
+ IndexType::INDEX_WILDCARD,
false, // multikey
{}, // multikey paths
{}, // multikeyPathSet
@@ -1966,7 +1966,7 @@ TEST(PlanCacheTest, ComputeKeyCollationIndex) {
planCache.computeKey(*inContainsStringHasCollation));
}
-TEST(PlanCacheTest, ComputeKeyAllPathsIndex) {
+TEST(PlanCacheTest, ComputeKeyWildcardIndex) {
PlanCache planCache;
IndexEntry entry(BSON("a.$**" << 1),
false, // multikey
@@ -2007,8 +2007,8 @@ TEST(PlanCacheTest, ComputeKeyAllPathsIndex) {
ASSERT_EQ(planCache.computeKey(*usesPathWithObject),
planCache.computeKey(*usesPathWithEmptyObject));
- // The query on 'b' should have a completely different plan cache key (both with and without an
- // allPaths index).
+ // The query on 'b' should have a completely different plan cache key (both with and without a
+ // wildcard index).
ASSERT_NE(planCacheWithNoIndexes.computeKey(*usesPathWithScalar),
planCacheWithNoIndexes.computeKey(*doesNotUsePath));
ASSERT_NE(planCache.computeKey(*usesPathWithScalar), planCache.computeKey(*doesNotUsePath));
diff --git a/src/mongo/db/query/planner_access.cpp b/src/mongo/db/query/planner_access.cpp
index 2be774dafcf..026e994b301 100644
--- a/src/mongo/db/query/planner_access.cpp
+++ b/src/mongo/db/query/planner_access.cpp
@@ -45,7 +45,7 @@
#include "mongo/db/query/index_bounds_builder.h"
#include "mongo/db/query/index_tag.h"
#include "mongo/db/query/indexability.h"
-#include "mongo/db/query/planner_allpaths_helpers.h"
+#include "mongo/db/query/planner_wildcard_helpers.h"
#include "mongo/db/query/query_knobs.h"
#include "mongo/db/query/query_planner.h"
#include "mongo/db/query/query_planner_common.h"
@@ -57,7 +57,7 @@ namespace {
using namespace mongo;
-namespace app = ::mongo::all_paths_planning;
+namespace app = ::mongo::wildcard_planning;
namespace dps = ::mongo::dotted_path_support;
/**
@@ -530,10 +530,10 @@ void QueryPlannerAccess::finishTextNode(QuerySolutionNode* node, const IndexEntr
tn->indexPrefix = prefixBob.obj();
}
-void QueryPlannerAccess::finishAllPathsIndexScanNode(QuerySolutionNode* node,
+void QueryPlannerAccess::finishWildcardIndexScanNode(QuerySolutionNode* node,
const IndexEntry& plannerIndex) {
// We should only ever reach this point if we are an IndexScanNode for a $** index.
- invariant(plannerIndex.type == IndexType::INDEX_ALLPATHS);
+ invariant(plannerIndex.type == IndexType::INDEX_WILDCARD);
invariant(node && node->getType() == STAGE_IXSCAN);
// Sanity check the QuerySolutionNode's copy of the IndexEntry.
@@ -676,8 +676,8 @@ void QueryPlannerAccess::finishLeafNode(QuerySolutionNode* node, const IndexEntr
}
// If this is a $** index, update and populate the keyPattern, bounds, and multikeyPaths.
- if (index.type == IndexType::INDEX_ALLPATHS) {
- finishAllPathsIndexScanNode(node, index);
+ if (index.type == IndexType::INDEX_WILDCARD) {
+ finishWildcardIndexScanNode(node, index);
}
// Find the first field in the scan's bounds that was not filled out.
@@ -1068,12 +1068,12 @@ std::unique_ptr<QuerySolutionNode> QueryPlannerAccess::buildIndexedAnd(
andResult = std::move(ixscanNodes[0]);
} else {
// $** indexes are prohibited from participating in either AND_SORTED or AND_HASH.
- const bool allPathsIndexInvolvedInIntersection =
+ const bool wildcardIndexInvolvedInIntersection =
std::any_of(ixscanNodes.begin(), ixscanNodes.end(), [](const auto& ixScan) {
return ixScan->getType() == StageType::STAGE_IXSCAN &&
- static_cast<IndexScanNode*>(ixScan.get())->index.type == INDEX_ALLPATHS;
+ static_cast<IndexScanNode*>(ixScan.get())->index.type == INDEX_WILDCARD;
});
- if (allPathsIndexInvolvedInIntersection) {
+ if (wildcardIndexInvolvedInIntersection) {
return nullptr;
}
diff --git a/src/mongo/db/query/planner_access.h b/src/mongo/db/query/planner_access.h
index cf559315f2b..fec5ef6b793 100644
--- a/src/mongo/db/query/planner_access.h
+++ b/src/mongo/db/query/planner_access.h
@@ -388,7 +388,7 @@ private:
static void finishTextNode(QuerySolutionNode* node, const IndexEntry& index);
- static void finishAllPathsIndexScanNode(QuerySolutionNode* node, const IndexEntry& index);
+ static void finishWildcardIndexScanNode(QuerySolutionNode* node, const IndexEntry& index);
/**
* Add the filter 'match' to the query solution node 'node'. Takes
diff --git a/src/mongo/db/query/planner_ixselect.cpp b/src/mongo/db/query/planner_ixselect.cpp
index 8dd796ac18c..8a7f005d9c1 100644
--- a/src/mongo/db/query/planner_ixselect.cpp
+++ b/src/mongo/db/query/planner_ixselect.cpp
@@ -34,8 +34,8 @@
#include "mongo/base/simple_string_data_comparator.h"
#include "mongo/db/geo/hash.h"
-#include "mongo/db/index/all_paths_key_generator.h"
#include "mongo/db/index/s2_common.h"
+#include "mongo/db/index/wildcard_key_generator.h"
#include "mongo/db/index_names.h"
#include "mongo/db/matcher/expression_algo.h"
#include "mongo/db/matcher/expression_geo.h"
@@ -44,7 +44,7 @@
#include "mongo/db/query/collation/collator_interface.h"
#include "mongo/db/query/index_tag.h"
#include "mongo/db/query/indexability.h"
-#include "mongo/db/query/planner_allpaths_helpers.h"
+#include "mongo/db/query/planner_wildcard_helpers.h"
#include "mongo/db/query/query_planner_common.h"
#include "mongo/util/log.h"
@@ -52,31 +52,31 @@ namespace mongo {
namespace {
-namespace app = ::mongo::all_paths_planning;
+namespace app = ::mongo::wildcard_planning;
std::size_t numPathComponents(StringData path) {
return FieldRef{path}.numParts();
}
/**
- * Given a single allPaths index, and a set of fields which are being queried, create 'mock'
+ * Given a single wildcard index, and a set of fields which are being queried, create 'mock'
* IndexEntry for each of the appropriate fields.
*/
-void expandIndex(const IndexEntry& allPathsIndex,
+void expandIndex(const IndexEntry& wildcardIndex,
const stdx::unordered_set<std::string>& fields,
vector<IndexEntry>* out) {
invariant(out);
- invariant(allPathsIndex.type == INDEX_ALLPATHS);
+ invariant(wildcardIndex.type == INDEX_WILDCARD);
// Should only have one field of the form {"path.$**" : 1}.
- invariant(allPathsIndex.keyPattern.nFields() == 1);
+ invariant(wildcardIndex.keyPattern.nFields() == 1);
// $** indexes do not keep the multikey metadata inside the index catalog entry, as the amount
// of metadata is not bounded. We do not expect IndexEntry objects for $** indexes to have a
// fixed-size vector of multikey metadata until after they are expanded.
- invariant(allPathsIndex.multikeyPaths.empty());
+ invariant(wildcardIndex.multikeyPaths.empty());
- const auto projExec = AllPathsKeyGenerator::createProjectionExec(
- allPathsIndex.keyPattern, allPathsIndex.infoObj.getObjectField("wildcardProjection"));
+ const auto projExec = WildcardKeyGenerator::createProjectionExec(
+ wildcardIndex.keyPattern, wildcardIndex.infoObj.getObjectField("wildcardProjection"));
const auto projectedFields = projExec->applyProjectionToFields(fields);
@@ -91,8 +91,8 @@ void expandIndex(const IndexEntry& allPathsIndex,
// in-memory. Here we convert this set of all multikey paths into a MultikeyPaths vector
// which will indicate to the downstream planning code which components of 'fieldName' are
// multikey.
- auto multikeyPaths = app::buildMultiKeyPathsForExpandedAllPathsIndexEntry(
- queryPath, allPathsIndex.multikeyPathSet);
+ auto multikeyPaths = app::buildMultiKeyPathsForExpandedWildcardIndexEntry(
+ queryPath, wildcardIndex.multikeyPathSet);
// Check whether a query on the current fieldpath is answerable by the $** index, given any
// numerical path components that may be present in the path string.
@@ -109,8 +109,8 @@ void expandIndex(const IndexEntry& allPathsIndex,
invariant(multikeyPaths.size() == 1u);
const bool isMultikey = !multikeyPaths[0].empty();
- IndexEntry entry(BSON(fieldName << allPathsIndex.keyPattern.firstElement()),
- IndexType::INDEX_ALLPATHS,
+ IndexEntry entry(BSON(fieldName << wildcardIndex.keyPattern.firstElement()),
+ IndexType::INDEX_WILDCARD,
isMultikey,
std::move(multikeyPaths),
// Expanded index entries always use the fixed-size multikey paths
@@ -118,17 +118,17 @@ void expandIndex(const IndexEntry& allPathsIndex,
{},
true, // sparse
false, // unique
- {allPathsIndex.identifier.catalogName, fieldName},
- allPathsIndex.filterExpr,
- allPathsIndex.infoObj,
- allPathsIndex.collator);
+ {wildcardIndex.identifier.catalogName, fieldName},
+ wildcardIndex.filterExpr,
+ wildcardIndex.infoObj,
+ wildcardIndex.collator);
invariant("$_path"_sd != fieldName);
out->push_back(std::move(entry));
}
}
-bool canUseAllPathsIndex(BSONElement elt, MatchExpression::MatchType matchType) {
+bool canUseWildcardIndex(BSONElement elt, MatchExpression::MatchType matchType) {
if (elt.type() == BSONType::Object) {
return false;
}
@@ -370,7 +370,7 @@ std::vector<IndexEntry> QueryPlannerIXSelect::expandIndexes(
const std::vector<IndexEntry>& relevantIndices) {
std::vector<IndexEntry> out;
for (auto&& entry : relevantIndices) {
- if (entry.type == IndexType::INDEX_ALLPATHS) {
+ if (entry.type == IndexType::INDEX_WILDCARD) {
expandIndex(entry, fields, &out);
} else {
out.push_back(entry);
@@ -513,7 +513,7 @@ bool QueryPlannerIXSelect::_compatible(const BSONElement& keyPatternElt,
}
}
- if (index.type == IndexType::INDEX_ALLPATHS && !nodeIsSupportedByAllPathsIndex(node)) {
+ if (index.type == IndexType::INDEX_WILDCARD && !nodeIsSupportedByWildcardIndex(node)) {
return false;
}
@@ -652,8 +652,8 @@ bool QueryPlannerIXSelect::nodeIsSupportedBySparseIndex(const MatchExpression* q
return true;
}
-bool QueryPlannerIXSelect::nodeIsSupportedByAllPathsIndex(const MatchExpression* queryExpr) {
- // AllPaths indexes only store index keys for "leaf" nodes in an object. That is, they do not
+bool QueryPlannerIXSelect::nodeIsSupportedByWildcardIndex(const MatchExpression* queryExpr) {
+ // Wildcard indexes only store index keys for "leaf" nodes in an object. That is, they do not
// store keys for nested objects, meaning that any kind of comparison to an object or array
// cannot be answered by the index (including with a $in).
@@ -661,14 +661,14 @@ bool QueryPlannerIXSelect::nodeIsSupportedByAllPathsIndex(const MatchExpression*
const ComparisonMatchExpression* cmpExpr =
static_cast<const ComparisonMatchExpression*>(queryExpr);
- return canUseAllPathsIndex(cmpExpr->getData(), cmpExpr->matchType());
+ return canUseWildcardIndex(cmpExpr->getData(), cmpExpr->matchType());
} else if (queryExpr->matchType() == MatchExpression::MATCH_IN) {
const auto* queryExprIn = static_cast<const InMatchExpression*>(queryExpr);
return std::all_of(
queryExprIn->getEqualities().begin(),
queryExprIn->getEqualities().end(),
- [](const BSONElement& elt) { return canUseAllPathsIndex(elt, MatchExpression::EQ); });
+ [](const BSONElement& elt) { return canUseWildcardIndex(elt, MatchExpression::EQ); });
}
return true;
@@ -766,7 +766,7 @@ void QueryPlannerIXSelect::_rateIndices(MatchExpression* node,
// static
void QueryPlannerIXSelect::stripInvalidAssignments(MatchExpression* node,
const vector<IndexEntry>& indices) {
- stripInvalidAssignmentsToAllPathsIndexes(node, indices);
+ stripInvalidAssignmentsToWildcardIndexes(node, indices);
stripInvalidAssignmentsToTextIndexes(node, indices);
if (MatchExpression::GEO != node->matchType() &&
@@ -955,13 +955,13 @@ void QueryPlannerIXSelect::stripInvalidAssignmentsToPartialIndices(
}
//
-// AllPaths index invalid assignments.
+// Wildcard index invalid assignments.
//
-void QueryPlannerIXSelect::stripInvalidAssignmentsToAllPathsIndexes(
+void QueryPlannerIXSelect::stripInvalidAssignmentsToWildcardIndexes(
MatchExpression* root, const vector<IndexEntry>& indices) {
for (size_t idx = 0; idx < indices.size(); ++idx) {
// Skip over all indexes except $**.
- if (indices[idx].type != IndexType::INDEX_ALLPATHS) {
+ if (indices[idx].type != IndexType::INDEX_WILDCARD) {
continue;
}
// If we have a $** index, check whether we have a TEXT node in the MatchExpression tree.
diff --git a/src/mongo/db/query/planner_ixselect.h b/src/mongo/db/query/planner_ixselect.h
index 01123e652b8..e2591ab3650 100644
--- a/src/mongo/db/query/planner_ixselect.h
+++ b/src/mongo/db/query/planner_ixselect.h
@@ -152,9 +152,9 @@ public:
const std::vector<IndexEntry>& relevantIndices);
/**
- * Check if this match expression is a leaf and is supported by an allPaths index.
+ * Check if this match expression is a leaf and is supported by a wildcard index.
*/
- static bool nodeIsSupportedByAllPathsIndex(const MatchExpression* queryExpr);
+ static bool nodeIsSupportedByWildcardIndex(const MatchExpression* queryExpr);
/*
* Return true if the given match expression can use a sparse index, false otherwise. This will
@@ -245,14 +245,14 @@ private:
const std::vector<IndexEntry>& indices);
/**
- * This function strips RelevantTag assignments to expanded 'allPaths' indexes, in cases where
+ * This function strips RelevantTag assignments to expanded 'wildcard' indexes, in cases where
* the assignment is incompatible with the query.
*
- * Specifically, if the query has a TEXT node with both 'text' and 'allPaths' indexes present,
- * then the 'allPaths' index will mark itself as relevant to the '_fts' path reported by the
- * TEXT node. We therefore remove any such misassigned 'allPaths' tags here.
+ * Specifically, if the query has a TEXT node with both 'text' and 'wildcard' indexes present,
+ * then the 'wildcard' index will mark itself as relevant to the '_fts' path reported by the
+ * TEXT node. We therefore remove any such misassigned 'wildcard' tags here.
*/
- static void stripInvalidAssignmentsToAllPathsIndexes(MatchExpression* root,
+ static void stripInvalidAssignmentsToWildcardIndexes(MatchExpression* root,
const std::vector<IndexEntry>& indices);
/**
diff --git a/src/mongo/db/query/planner_ixselect_test.cpp b/src/mongo/db/query/planner_ixselect_test.cpp
index 20bdf3f3d5a..bb51baa461a 100644
--- a/src/mongo/db/query/planner_ixselect_test.cpp
+++ b/src/mongo/db/query/planner_ixselect_test.cpp
@@ -1288,7 +1288,7 @@ bool indexEntryKeyPatternsMatch(vector<BSONObj>* keyPatterns, vector<IndexEntry>
});
}
-TEST(QueryPlannerIXSelectTest, ExpandAllPathsIndices) {
+TEST(QueryPlannerIXSelectTest, ExpandWildcardIndices) {
const auto indexEntry = makeIndexEntry(BSON("$**" << 1), {});
// Case where no fields are specified.
@@ -1302,15 +1302,15 @@ TEST(QueryPlannerIXSelectTest, ExpandAllPathsIndices) {
std::vector<BSONObj> expectedKeyPatterns = {BSON("fieldA" << 1), BSON("fieldB" << 1)};
ASSERT_TRUE(indexEntryKeyPatternsMatch(&expectedKeyPatterns, &result));
- const auto allPathsIndexWithSubpath = makeIndexEntry(BSON("a.b.$**" << 1), {});
+ const auto wildcardIndexWithSubpath = makeIndexEntry(BSON("a.b.$**" << 1), {});
fields = {"a.b", "a.b.c", "a.d"};
- result = QueryPlannerIXSelect::expandIndexes(fields, {allPathsIndexWithSubpath});
+ result = QueryPlannerIXSelect::expandIndexes(fields, {wildcardIndexWithSubpath});
expectedKeyPatterns = {BSON("a.b" << 1), BSON("a.b.c" << 1)};
ASSERT_TRUE(indexEntryKeyPatternsMatch(&expectedKeyPatterns, &result));
}
-TEST(QueryPlannerIXSelectTest, ExpandAllPathsIndicesInPresenceOfOtherIndices) {
- auto allPathsIndexEntry = makeIndexEntry(BSON("$**" << 1), {});
+TEST(QueryPlannerIXSelectTest, ExpandWildcardIndicesInPresenceOfOtherIndices) {
+ auto wildcardIndexEntry = makeIndexEntry(BSON("$**" << 1), {});
auto aIndexEntry = makeIndexEntry(BSON("fieldA" << 1), {});
auto bIndexEntry = makeIndexEntry(BSON("fieldB" << 1), {});
auto abIndexEntry = makeIndexEntry(BSON("fieldA" << 1 << "fieldB" << 1), {});
@@ -1319,18 +1319,18 @@ TEST(QueryPlannerIXSelectTest, ExpandAllPathsIndicesInPresenceOfOtherIndices) {
std::vector<BSONObj> expectedKeyPatterns = {
BSON("fieldA" << 1), BSON("fieldA" << 1), BSON("fieldB" << 1), BSON("fieldC" << 1)};
- auto result = QueryPlannerIXSelect::expandIndexes(fields, {aIndexEntry, allPathsIndexEntry});
+ auto result = QueryPlannerIXSelect::expandIndexes(fields, {aIndexEntry, wildcardIndexEntry});
ASSERT_TRUE(indexEntryKeyPatternsMatch(&expectedKeyPatterns, &result));
result.clear();
expectedKeyPatterns = {
BSON("fieldB" << 1), BSON("fieldA" << 1), BSON("fieldB" << 1), BSON("fieldC" << 1)};
- result = QueryPlannerIXSelect::expandIndexes(fields, {bIndexEntry, allPathsIndexEntry});
+ result = QueryPlannerIXSelect::expandIndexes(fields, {bIndexEntry, wildcardIndexEntry});
ASSERT_TRUE(indexEntryKeyPatternsMatch(&expectedKeyPatterns, &result));
result.clear();
result =
- QueryPlannerIXSelect::expandIndexes(fields, {aIndexEntry, allPathsIndexEntry, bIndexEntry});
+ QueryPlannerIXSelect::expandIndexes(fields, {aIndexEntry, wildcardIndexEntry, bIndexEntry});
expectedKeyPatterns = {BSON("fieldA" << 1),
BSON("fieldA" << 1),
BSON("fieldB" << 1),
@@ -1339,7 +1339,7 @@ TEST(QueryPlannerIXSelectTest, ExpandAllPathsIndicesInPresenceOfOtherIndices) {
ASSERT_TRUE(indexEntryKeyPatternsMatch(&expectedKeyPatterns, &result));
result.clear();
- result = QueryPlannerIXSelect::expandIndexes(fields, {allPathsIndexEntry, abIndexEntry});
+ result = QueryPlannerIXSelect::expandIndexes(fields, {wildcardIndexEntry, abIndexEntry});
expectedKeyPatterns = {BSON("fieldA" << 1),
BSON("fieldB" << 1),
BSON("fieldC" << 1),
@@ -1349,11 +1349,11 @@ TEST(QueryPlannerIXSelectTest, ExpandAllPathsIndicesInPresenceOfOtherIndices) {
}
TEST(QueryPlannerIXSelectTest, ExpandedIndexEntriesAreCorrectlyMarkedAsMultikeyOrNonMultikey) {
- auto allPathsIndexEntry = makeIndexEntry(BSON("$**" << 1), {}, {FieldRef{"a"}});
+ auto wildcardIndexEntry = makeIndexEntry(BSON("$**" << 1), {}, {FieldRef{"a"}});
const stdx::unordered_set<string> fields = {"a.b", "c.d"};
std::vector<BSONObj> expectedKeyPatterns = {BSON("a.b" << 1), BSON("c.d" << 1)};
- auto result = QueryPlannerIXSelect::expandIndexes(fields, {allPathsIndexEntry});
+ auto result = QueryPlannerIXSelect::expandIndexes(fields, {wildcardIndexEntry});
ASSERT_TRUE(indexEntryKeyPatternsMatch(&expectedKeyPatterns, &result));
for (auto&& entry : result) {
@@ -1371,7 +1371,7 @@ TEST(QueryPlannerIXSelectTest, ExpandedIndexEntriesAreCorrectlyMarkedAsMultikeyO
}
}
-TEST(QueryPlannerIXSelectTest, AllPathsIndexExpansionExcludesIdField) {
+TEST(QueryPlannerIXSelectTest, WildcardIndexExpansionExcludesIdField) {
const auto indexEntry = makeIndexEntry(BSON("$**" << 1), {});
stdx::unordered_set<string> fields = {"_id", "abc", "def"};
@@ -1381,14 +1381,14 @@ TEST(QueryPlannerIXSelectTest, AllPathsIndexExpansionExcludesIdField) {
ASSERT_TRUE(indexEntryKeyPatternsMatch(&expectedKeyPatterns, &result));
}
-TEST(QueryPlannerIXSelectTest, AllPathsIndicesExpandedEntryHasCorrectProperties) {
- auto allPathsIndexEntry = makeIndexEntry(BSON("$**" << 1), {});
- allPathsIndexEntry.identifier = IndexEntry::Identifier("someIndex");
+TEST(QueryPlannerIXSelectTest, WildcardIndicesExpandedEntryHasCorrectProperties) {
+ auto wildcardIndexEntry = makeIndexEntry(BSON("$**" << 1), {});
+ wildcardIndexEntry.identifier = IndexEntry::Identifier("someIndex");
stdx::unordered_set<string> fields = {"abc", "def"};
std::vector<IndexEntry> result =
- QueryPlannerIXSelect::expandIndexes(fields, {allPathsIndexEntry});
+ QueryPlannerIXSelect::expandIndexes(fields, {wildcardIndexEntry});
std::vector<BSONObj> expectedKeyPatterns = {BSON("abc" << 1), BSON("def" << 1)};
ASSERT_TRUE(indexEntryKeyPatternsMatch(&expectedKeyPatterns, &result));
@@ -1400,57 +1400,57 @@ TEST(QueryPlannerIXSelectTest, AllPathsIndicesExpandedEntryHasCorrectProperties)
ASSERT_EQ(ie.multikeyPaths.size(), 1u);
ASSERT_TRUE(ie.multikeyPaths[0].empty());
- // AllPaths indices are always sparse.
+ // Wildcard indices are always sparse.
ASSERT_TRUE(ie.sparse);
- // AllPaths indexes are never unique.
+ // Wildcard indexes are never unique.
ASSERT_FALSE(ie.unique);
ASSERT_EQ(ie.identifier,
- IndexEntry::Identifier(allPathsIndexEntry.identifier.catalogName,
+ IndexEntry::Identifier(wildcardIndexEntry.identifier.catalogName,
ie.keyPattern.firstElementFieldName()));
}
}
-TEST(QueryPlannerIXSelectTest, AllPathsIndicesExcludeNonMatchingKeySubpath) {
- auto allPathsIndexEntry = makeIndexEntry(BSON("subpath.$**" << 1), {});
+TEST(QueryPlannerIXSelectTest, WildcardIndicesExcludeNonMatchingKeySubpath) {
+ auto wildcardIndexEntry = makeIndexEntry(BSON("subpath.$**" << 1), {});
stdx::unordered_set<string> fields = {"abc", "def", "subpath.abc", "subpath.def", "subpath"};
std::vector<IndexEntry> result =
- QueryPlannerIXSelect::expandIndexes(fields, {allPathsIndexEntry});
+ QueryPlannerIXSelect::expandIndexes(fields, {wildcardIndexEntry});
std::vector<BSONObj> expectedKeyPatterns = {
BSON("subpath.abc" << 1), BSON("subpath.def" << 1), BSON("subpath" << 1)};
ASSERT_TRUE(indexEntryKeyPatternsMatch(&expectedKeyPatterns, &result));
}
-TEST(QueryPlannerIXSelectTest, AllPathsIndicesExcludeNonMatchingPathsWithInclusionProjection) {
- auto allPathsIndexEntry = makeIndexEntryWithInfoObj(
+TEST(QueryPlannerIXSelectTest, WildcardIndicesExcludeNonMatchingPathsWithInclusionProjection) {
+ auto wildcardIndexEntry = makeIndexEntryWithInfoObj(
BSON("$**" << 1), {}, BSON("wildcardProjection" << BSON("abc" << 1 << "subpath.abc" << 1)));
stdx::unordered_set<string> fields = {"abc", "def", "subpath.abc", "subpath.def", "subpath"};
std::vector<IndexEntry> result =
- QueryPlannerIXSelect::expandIndexes(fields, {allPathsIndexEntry});
+ QueryPlannerIXSelect::expandIndexes(fields, {wildcardIndexEntry});
std::vector<BSONObj> expectedKeyPatterns = {BSON("abc" << 1), BSON("subpath.abc" << 1)};
ASSERT_TRUE(indexEntryKeyPatternsMatch(&expectedKeyPatterns, &result));
}
-TEST(QueryPlannerIXSelectTest, AllPathsIndicesExcludeNonMatchingPathsWithExclusionProjection) {
- auto allPathsIndexEntry = makeIndexEntryWithInfoObj(
+TEST(QueryPlannerIXSelectTest, WildcardIndicesExcludeNonMatchingPathsWithExclusionProjection) {
+ auto wildcardIndexEntry = makeIndexEntryWithInfoObj(
BSON("$**" << 1), {}, BSON("wildcardProjection" << BSON("abc" << 0 << "subpath.abc" << 0)));
stdx::unordered_set<string> fields = {"abc", "def", "subpath.abc", "subpath.def", "subpath"};
std::vector<IndexEntry> result =
- QueryPlannerIXSelect::expandIndexes(fields, {allPathsIndexEntry});
+ QueryPlannerIXSelect::expandIndexes(fields, {wildcardIndexEntry});
std::vector<BSONObj> expectedKeyPatterns = {
BSON("def" << 1), BSON("subpath.def" << 1), BSON("subpath" << 1)};
ASSERT_TRUE(indexEntryKeyPatternsMatch(&expectedKeyPatterns, &result));
}
-TEST(QueryPlannerIXSelectTest, AllPathsIndicesWithInclusionProjectionAllowIdExclusion) {
- auto allPathsIndexEntry = makeIndexEntryWithInfoObj(
+TEST(QueryPlannerIXSelectTest, WildcardIndicesWithInclusionProjectionAllowIdExclusion) {
+ auto wildcardIndexEntry = makeIndexEntryWithInfoObj(
BSON("$**" << 1),
{},
BSON("wildcardProjection" << BSON("_id" << 0 << "abc" << 1 << "subpath.abc" << 1)));
@@ -1459,13 +1459,13 @@ TEST(QueryPlannerIXSelectTest, AllPathsIndicesWithInclusionProjectionAllowIdExcl
"_id", "abc", "def", "subpath.abc", "subpath.def", "subpath"};
std::vector<IndexEntry> result =
- QueryPlannerIXSelect::expandIndexes(fields, {allPathsIndexEntry});
+ QueryPlannerIXSelect::expandIndexes(fields, {wildcardIndexEntry});
std::vector<BSONObj> expectedKeyPatterns = {BSON("abc" << 1), BSON("subpath.abc" << 1)};
ASSERT_TRUE(indexEntryKeyPatternsMatch(&expectedKeyPatterns, &result));
}
-TEST(QueryPlannerIXSelectTest, AllPathsIndicesWithInclusionProjectionAllowIdInclusion) {
- auto allPathsIndexEntry = makeIndexEntryWithInfoObj(
+TEST(QueryPlannerIXSelectTest, WildcardIndicesWithInclusionProjectionAllowIdInclusion) {
+ auto wildcardIndexEntry = makeIndexEntryWithInfoObj(
BSON("$**" << 1),
{},
BSON("wildcardProjection" << BSON("_id" << 1 << "abc" << 1 << "subpath.abc" << 1)));
@@ -1474,14 +1474,14 @@ TEST(QueryPlannerIXSelectTest, AllPathsIndicesWithInclusionProjectionAllowIdIncl
"_id", "abc", "def", "subpath.abc", "subpath.def", "subpath"};
std::vector<IndexEntry> result =
- QueryPlannerIXSelect::expandIndexes(fields, {allPathsIndexEntry});
+ QueryPlannerIXSelect::expandIndexes(fields, {wildcardIndexEntry});
std::vector<BSONObj> expectedKeyPatterns = {
BSON("_id" << 1), BSON("abc" << 1), BSON("subpath.abc" << 1)};
ASSERT_TRUE(indexEntryKeyPatternsMatch(&expectedKeyPatterns, &result));
}
-TEST(QueryPlannerIXSelectTest, AllPathsIndicesWithExclusionProjectionAllowIdInclusion) {
- auto allPathsIndexEntry = makeIndexEntryWithInfoObj(
+TEST(QueryPlannerIXSelectTest, WildcardIndicesWithExclusionProjectionAllowIdInclusion) {
+ auto wildcardIndexEntry = makeIndexEntryWithInfoObj(
BSON("$**" << 1),
{},
BSON("wildcardProjection" << BSON("_id" << 1 << "abc" << 0 << "subpath.abc" << 0)));
@@ -1490,42 +1490,42 @@ TEST(QueryPlannerIXSelectTest, AllPathsIndicesWithExclusionProjectionAllowIdIncl
"_id", "abc", "def", "subpath.abc", "subpath.def", "subpath"};
std::vector<IndexEntry> result =
- QueryPlannerIXSelect::expandIndexes(fields, {allPathsIndexEntry});
+ QueryPlannerIXSelect::expandIndexes(fields, {wildcardIndexEntry});
std::vector<BSONObj> expectedKeyPatterns = {
BSON("_id" << 1), BSON("def" << 1), BSON("subpath.def" << 1), BSON("subpath" << 1)};
ASSERT_TRUE(indexEntryKeyPatternsMatch(&expectedKeyPatterns, &result));
}
-TEST(QueryPlannerIXSelectTest, AllPathsIndicesIncludeMatchingInternalNodes) {
- auto allPathsIndexEntry = makeIndexEntryWithInfoObj(
+TEST(QueryPlannerIXSelectTest, WildcardIndicesIncludeMatchingInternalNodes) {
+ auto wildcardIndexEntry = makeIndexEntryWithInfoObj(
BSON("$**" << 1), {}, BSON("wildcardProjection" << BSON("_id" << 1 << "subpath" << 1)));
stdx::unordered_set<string> fields = {
"_id", "abc", "def", "subpath.abc", "subpath.def", "subpath"};
std::vector<IndexEntry> result =
- QueryPlannerIXSelect::expandIndexes(fields, {allPathsIndexEntry});
+ QueryPlannerIXSelect::expandIndexes(fields, {wildcardIndexEntry});
std::vector<BSONObj> expectedKeyPatterns = {
BSON("_id" << 1), BSON("subpath.abc" << 1), BSON("subpath.def" << 1), BSON("subpath" << 1)};
ASSERT_TRUE(indexEntryKeyPatternsMatch(&expectedKeyPatterns, &result));
}
-TEST(QueryPlannerIXSelectTest, AllPathsIndexSupported) {
- ASSERT_FALSE(QueryPlannerIXSelect::nodeIsSupportedByAllPathsIndex(
+TEST(QueryPlannerIXSelectTest, WildcardIndexSupported) {
+ ASSERT_FALSE(QueryPlannerIXSelect::nodeIsSupportedByWildcardIndex(
parseMatchExpression(fromjson("{x: {abc: 1}}")).get()));
- ASSERT_FALSE(QueryPlannerIXSelect::nodeIsSupportedByAllPathsIndex(
+ ASSERT_FALSE(QueryPlannerIXSelect::nodeIsSupportedByWildcardIndex(
parseMatchExpression(fromjson("{x: {$lt: {abc: 1}}}")).get()));
- ASSERT_FALSE(QueryPlannerIXSelect::nodeIsSupportedByAllPathsIndex(
+ ASSERT_FALSE(QueryPlannerIXSelect::nodeIsSupportedByWildcardIndex(
parseMatchExpression(fromjson("{x: {$in: [1, 2, 3, {abc: 1}]}}")).get()));
}
-TEST(QueryPlannerIXSelectTest, AllPathsIndexSupportedDoesNotTraverse) {
+TEST(QueryPlannerIXSelectTest, WildcardIndexSupportedDoesNotTraverse) {
// The function will not traverse a node's children.
- ASSERT_TRUE(QueryPlannerIXSelect::nodeIsSupportedByAllPathsIndex(
+ ASSERT_TRUE(QueryPlannerIXSelect::nodeIsSupportedByWildcardIndex(
parseMatchExpression(fromjson("{$or: [{z: {abc: 1}}]}")).get()));
- ASSERT_TRUE(QueryPlannerIXSelect::nodeIsSupportedByAllPathsIndex(
+ ASSERT_TRUE(QueryPlannerIXSelect::nodeIsSupportedByWildcardIndex(
parseMatchExpression(fromjson("{x: 5, y: {abc: 1}}")).get()));
- ASSERT_TRUE(QueryPlannerIXSelect::nodeIsSupportedByAllPathsIndex(
+ ASSERT_TRUE(QueryPlannerIXSelect::nodeIsSupportedByWildcardIndex(
parseMatchExpression(fromjson("{x: {$ne: {abc: 1}}}")).get()));
}
diff --git a/src/mongo/db/query/planner_allpaths_helpers.cpp b/src/mongo/db/query/planner_wildcard_helpers.cpp
index b56de29e577..6f44f0eb50c 100644
--- a/src/mongo/db/query/planner_allpaths_helpers.cpp
+++ b/src/mongo/db/query/planner_wildcard_helpers.cpp
@@ -30,7 +30,7 @@
#include "mongo/platform/basic.h"
-#include "mongo/db/query/planner_allpaths_helpers.h"
+#include "mongo/db/query/planner_wildcard_helpers.h"
#include <vector>
@@ -38,7 +38,7 @@
#include "mongo/util/log.h"
namespace mongo {
-namespace all_paths_planning {
+namespace wildcard_planning {
namespace {
/**
* Compares the path 'fieldNameOrArrayIndexPath' to 'staticComparisonPath', ignoring any array
@@ -136,7 +136,7 @@ FieldRef pathWithoutSpecifiedComponents(const FieldRef& path,
}
} // namespace
-MultikeyPaths buildMultiKeyPathsForExpandedAllPathsIndexEntry(
+MultikeyPaths buildMultiKeyPathsForExpandedWildcardIndexEntry(
const FieldRef& indexedPath, const std::set<FieldRef>& multikeyPathSet) {
FieldRef pathToLookup;
std::set<std::size_t> multikeyPaths;
@@ -155,7 +155,7 @@ std::set<FieldRef> generateFieldNameOrArrayIndexPathSet(const std::set<std::size
// The algorithm is unavoidably O(n2^n), but we enforce that 'n' is never more than single
// digits during the planner's index selection phase.
const auto potentialArrayIndices = findArrayIndexPathComponents(multikeyPaths, queryPath);
- invariant(potentialArrayIndices.size() <= kAllPathsMaxArrayIndexTraversalDepth);
+ invariant(potentialArrayIndices.size() <= kWildcardMaxArrayIndexTraversalDepth);
invariant(potentialArrayIndices.size() < sizeof(size_t) * 8u);
// We iterate over every value [0..2^n), where 'n' is the size of 'potentialArrayIndices',
// treating each value as a 'bitMask' of 'n' bits. Each bit in 'bitMask' represents the
@@ -178,13 +178,13 @@ std::set<FieldRef> generateFieldNameOrArrayIndexPathSet(const std::set<std::size
return paths;
}
-BoundsTightness applyAllPathsIndexScanBoundsTightness(const IndexEntry& index,
+BoundsTightness applyWildcardIndexScanBoundsTightness(const IndexEntry& index,
BoundsTightness tightnessIn) {
// This method should only ever be called for a $** IndexEntry. We expect to be called during
- // planning, *before* finishAllPathsIndexScanNode has been invoked. The IndexEntry should thus
+ // planning, *before* finishWildcardIndexScanNode has been invoked. The IndexEntry should thus
// only have a single keyPattern field and multikeyPath entry, but this is sufficient to
// determine whether it will be necessary to adjust the tightness.
- invariant(index.type == IndexType::INDEX_ALLPATHS);
+ invariant(index.type == IndexType::INDEX_WILDCARD);
invariant(index.keyPattern.nFields() == 1);
invariant(index.multikeyPaths.size() == 1);
@@ -217,10 +217,10 @@ bool validateNumericPathComponents(const MultikeyPaths& multikeyPaths,
// To support $** fieldname-or-array-index semantics, the planner must generate the power set of
// all paths with and without array indices. Because this is O(2^n), we decline to answer
// queries that traverse more than 8 levels of array indices.
- if (arrayIndices.size() > kAllPathsMaxArrayIndexTraversalDepth) {
+ if (arrayIndices.size() > kWildcardMaxArrayIndexTraversalDepth) {
LOG(2) << "Declining to answer query on field '" << queryPath.dottedField()
<< "' with $** index, as it traverses through more than "
- << kAllPathsMaxArrayIndexTraversalDepth << " nested array indices.";
+ << kWildcardMaxArrayIndexTraversalDepth << " nested array indices.";
return false;
}
// If 'includedPaths' is empty, then either the $** projection is an exclusion, or no explicit
@@ -245,5 +245,5 @@ bool validateNumericPathComponents(const MultikeyPaths& multikeyPaths,
return arrayIndices[0] >= includePath->numParts();
}
-} // namespace all_paths_planning
+} // namespace wildcard_planning
} // namespace mongo
diff --git a/src/mongo/db/query/planner_allpaths_helpers.h b/src/mongo/db/query/planner_wildcard_helpers.h
index 4bbb333dead..7e56adb1ba0 100644
--- a/src/mongo/db/query/planner_allpaths_helpers.h
+++ b/src/mongo/db/query/planner_wildcard_helpers.h
@@ -36,7 +36,7 @@
#include "mongo/db/query/query_solution.h"
namespace mongo {
-namespace all_paths_planning {
+namespace wildcard_planning {
using BoundsTightness = IndexBoundsBuilder::BoundsTightness;
@@ -44,13 +44,13 @@ using BoundsTightness = IndexBoundsBuilder::BoundsTightness;
* Specifies the maximum depth of nested array indices through which a query may traverse before a
* $** declines to answer it, due to the exponential complexity of the bounds required.
*/
-static constexpr size_t kAllPathsMaxArrayIndexTraversalDepth = 8u;
+static constexpr size_t kWildcardMaxArrayIndexTraversalDepth = 8u;
/**
* Returns a MultikeyPaths which indicates which components of 'indexedPath' are multikey, by
* looking up multikeyness in 'multikeyPathSet'.
*/
-MultikeyPaths buildMultiKeyPathsForExpandedAllPathsIndexEntry(
+MultikeyPaths buildMultiKeyPathsForExpandedWildcardIndexEntry(
const FieldRef& indexedPath, const std::set<FieldRef>& multikeyPathSet);
/**
@@ -71,7 +71,7 @@ std::set<FieldRef> generateFieldNameOrArrayIndexPathSet(const std::set<std::size
* predicate. Given an IndexEntry representing an expanded $** index, we apply any necessary changes
* to the tightness here.
*/
-BoundsTightness applyAllPathsIndexScanBoundsTightness(const IndexEntry& index,
+BoundsTightness applyWildcardIndexScanBoundsTightness(const IndexEntry& index,
BoundsTightness tightnessIn);
/**
@@ -79,7 +79,7 @@ BoundsTightness applyAllPathsIndexScanBoundsTightness(const IndexEntry& index,
* by the $** index, true otherwise. Specifically, the $** index cannot answer the query if either
* of the following scenarios occur:
*
- * - The query path traverses through more than 'kAllPathsMaxArrayIndexTraversalDepth' nested arrays
+ * - The query path traverses through more than 'kWildcardMaxArrayIndexTraversalDepth' nested arrays
* via explicit array indices.
* - The query path lies along a $** projection through an array index.
*
@@ -97,5 +97,5 @@ bool validateNumericPathComponents(const MultikeyPaths& multikeyPaths,
const std::set<FieldRef>& includedPaths,
const FieldRef& queryPath);
-} // namespace all_paths_planning
+} // namespace wildcard_planning
} // namespace mongo
diff --git a/src/mongo/db/query/query_planner.cpp b/src/mongo/db/query/query_planner.cpp
index c7492757b20..c32d0343a1c 100644
--- a/src/mongo/db/query/query_planner.cpp
+++ b/src/mongo/db/query/query_planner.cpp
@@ -38,7 +38,7 @@
#include "mongo/base/string_data.h"
#include "mongo/bson/simple_bsonelement_comparator.h"
#include "mongo/db/bson/dotted_path_support.h"
-#include "mongo/db/index/all_paths_key_generator.h"
+#include "mongo/db/index/wildcard_key_generator.h"
#include "mongo/db/index_names.h"
#include "mongo/db/matcher/expression_algo.h"
#include "mongo/db/matcher/expression_geo.h"
@@ -150,7 +150,7 @@ static BSONObj getKeyFromQuery(const BSONObj& keyPattern, const BSONObj& query)
static bool indexCompatibleMaxMin(const BSONObj& obj,
const CollatorInterface* queryCollator,
const IndexEntry& indexEntry) {
- if (indexEntry.type == IndexType::INDEX_ALLPATHS) {
+ if (indexEntry.type == IndexType::INDEX_WILDCARD) {
return false;
}
@@ -634,7 +634,7 @@ StatusWith<std::vector<std::unique_ptr<QuerySolution>>> QueryPlanner::plan(
// $** index.
if (relevantIndices.size() > 1) {
for (auto&& entry : relevantIndices) {
- invariant(entry.type == IndexType::INDEX_ALLPATHS);
+ invariant(entry.type == IndexType::INDEX_WILDCARD);
}
}
}
@@ -856,7 +856,7 @@ StatusWith<std::vector<std::unique_ptr<QuerySolution>>> QueryPlanner::plan(
// desired behavior when an index is hinted that is not relevant to the query. In the case that
// $** index is hinted, we do not want this behavior.
if (!hintedIndex.isEmpty() && relevantIndices.size() == 1) {
- if (0 == out.size() && relevantIndices.front().type != IndexType::INDEX_ALLPATHS) {
+ if (0 == out.size() && relevantIndices.front().type != IndexType::INDEX_WILDCARD) {
// Push hinted index solution to output list if found. It is possible to end up without
// a solution in the case where a filtering QueryPlannerParams argument, such as
// NO_BLOCKING_SORT, leads to its exclusion.
diff --git a/src/mongo/db/query/query_planner_collation_test.cpp b/src/mongo/db/query/query_planner_collation_test.cpp
index e30d0bf6b59..bf6020f4df4 100644
--- a/src/mongo/db/query/query_planner_collation_test.cpp
+++ b/src/mongo/db/query/query_planner_collation_test.cpp
@@ -559,7 +559,7 @@ TEST_F(QueryPlannerTest, NoSortStageWhenMinMaxIndexCollationDoesNotMatchButBound
assertSolutionExists("{fetch: {node: {ixscan: {pattern: {a: 1, b: 1, c: 1}}}}}");
}
-TEST_F(QueryPlannerTest, StringComparisonWithUnequalCollatorsAndAllPathsIndexResultsInCollscan) {
+TEST_F(QueryPlannerTest, StringComparisonWithUnequalCollatorsAndWildcardIndexResultsInCollscan) {
CollatorInterfaceMock alwaysEqualCollator(CollatorInterfaceMock::MockType::kAlwaysEqual);
addIndex(fromjson("{'$**': 1}"), &alwaysEqualCollator);
@@ -570,7 +570,7 @@ TEST_F(QueryPlannerTest, StringComparisonWithUnequalCollatorsAndAllPathsIndexRes
assertSolutionExists("{cscan: {dir: 1}}");
}
-TEST_F(QueryPlannerTest, StringComparisonWithEqualCollatorsAndAllPathsIndexUsesIndex) {
+TEST_F(QueryPlannerTest, StringComparisonWithEqualCollatorsAndWildcardIndexUsesIndex) {
params.options &= ~QueryPlannerParams::INCLUDE_COLLSCAN;
CollatorInterfaceMock reverseStringCollator(CollatorInterfaceMock::MockType::kReverseString);
diff --git a/src/mongo/db/query/query_planner_all_paths_index_test.cpp b/src/mongo/db/query/query_planner_wildcard_index_test.cpp
index 9685d312b63..0ca171bd08e 100644
--- a/src/mongo/db/query/query_planner_all_paths_index_test.cpp
+++ b/src/mongo/db/query/query_planner_wildcard_index_test.cpp
@@ -38,7 +38,7 @@ const std::string kIndexName = "indexName";
* A specialization of the QueryPlannerTest fixture which makes it easy to present the planner with
* a view of the available $** indexes.
*/
-class QueryPlannerAllPathsTest : public QueryPlannerTest {
+class QueryPlannerWildcardTest : public QueryPlannerTest {
protected:
void setUp() final {
QueryPlannerTest::setUp();
@@ -48,7 +48,7 @@ protected:
params.options &= ~QueryPlannerParams::INCLUDE_COLLSCAN;
}
- void addAllPathsIndex(BSONObj keyPattern,
+ void addWildcardIndex(BSONObj keyPattern,
const std::set<std::string>& multikeyPathSet = {},
BSONObj wildcardProjection = BSONObj{},
MatchExpression* partialFilterExpr = nullptr) {
@@ -63,7 +63,7 @@ protected:
BSONObj infoObj = BSON("wildcardProjection" << wildcardProjection);
params.indices.push_back(IndexEntry{std::move(keyPattern),
- IndexType::INDEX_ALLPATHS,
+ IndexType::INDEX_WILDCARD,
isMultikey,
{}, // multikeyPaths
std::move(multikeyFieldRefs),
@@ -80,7 +80,7 @@ protected:
// Null comparison and existence tests.
//
-TEST_F(QueryPlannerAllPathsTest, ExistsTrueQueriesUseAllPathsIndexes) {
+TEST_F(QueryPlannerWildcardTest, ExistsTrueQueriesUseWildcardIndexes) {
addIndex(BSON("$**" << 1));
runQuery(fromjson("{x: {$exists: true}}"));
@@ -89,7 +89,7 @@ TEST_F(QueryPlannerAllPathsTest, ExistsTrueQueriesUseAllPathsIndexes) {
assertSolutionExists("{fetch: {node: {ixscan: {pattern: {$_path: 1, x: 1}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, ExistsFalseQueriesDontUseAllPathsIndexes) {
+TEST_F(QueryPlannerWildcardTest, ExistsFalseQueriesDontUseWildcardIndexes) {
addIndex(BSON("$**" << 1));
runQuery(fromjson("{x: {$exists: false}}"));
@@ -98,7 +98,7 @@ TEST_F(QueryPlannerAllPathsTest, ExistsFalseQueriesDontUseAllPathsIndexes) {
assertSolutionExists("{cscan: {dir: 1}}");
}
-TEST_F(QueryPlannerAllPathsTest, EqualsNullQueriesDontUseAllPathsIndexes) {
+TEST_F(QueryPlannerWildcardTest, EqualsNullQueriesDontUseWildcardIndexes) {
addIndex(BSON("$**" << 1));
runQuery(fromjson("{x: {$eq: null}}"));
@@ -107,7 +107,7 @@ TEST_F(QueryPlannerAllPathsTest, EqualsNullQueriesDontUseAllPathsIndexes) {
assertSolutionExists("{cscan: {dir: 1}}");
}
-TEST_F(QueryPlannerAllPathsTest, NotEqualsNullQueriesDontUseAllPathsIndexes) {
+TEST_F(QueryPlannerWildcardTest, NotEqualsNullQueriesDontUseWildcardIndexes) {
addIndex(BSON("$**" << 1));
runQuery(fromjson("{x: {$ne: null}}"));
@@ -116,7 +116,7 @@ TEST_F(QueryPlannerAllPathsTest, NotEqualsNullQueriesDontUseAllPathsIndexes) {
assertSolutionExists("{cscan: {dir: 1}}");
}
-TEST_F(QueryPlannerAllPathsTest, NotEqualsNullAndExistsQueriesUseAllPathsIndexes) {
+TEST_F(QueryPlannerWildcardTest, NotEqualsNullAndExistsQueriesUseWildcardIndexes) {
addIndex(BSON("$**" << 1));
runQuery(fromjson("{x: {$ne: null, $exists: true}}"));
@@ -125,7 +125,7 @@ TEST_F(QueryPlannerAllPathsTest, NotEqualsNullAndExistsQueriesUseAllPathsIndexes
assertSolutionExists("{fetch: {node: {ixscan: {pattern: {$_path: 1, x: 1}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, EqualsNullAndExistsQueriesUseAllPathsIndexes) {
+TEST_F(QueryPlannerWildcardTest, EqualsNullAndExistsQueriesUseWildcardIndexes) {
addIndex(BSON("$**" << 1));
runQuery(fromjson("{x: {$eq: null, $exists: true}}"));
@@ -134,7 +134,7 @@ TEST_F(QueryPlannerAllPathsTest, EqualsNullAndExistsQueriesUseAllPathsIndexes) {
assertSolutionExists("{fetch: {node: {ixscan: {pattern: {$_path: 1, x: 1}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, EmptyBoundsWithAllPathsIndexes) {
+TEST_F(QueryPlannerWildcardTest, EmptyBoundsWithWildcardIndexes) {
addIndex(BSON("$**" << 1));
runQuery(fromjson("{x: {$lte: 5, $gte: 10}}"));
@@ -147,8 +147,8 @@ TEST_F(QueryPlannerAllPathsTest, EmptyBoundsWithAllPathsIndexes) {
// Multikey planning tests.
//
-TEST_F(QueryPlannerAllPathsTest, MultiplePredicatesOverMultikeyFieldNoElemMatch) {
- addAllPathsIndex(BSON("$**" << 1), {"a"});
+TEST_F(QueryPlannerWildcardTest, MultiplePredicatesOverMultikeyFieldNoElemMatch) {
+ addWildcardIndex(BSON("$**" << 1), {"a"});
runQuery(fromjson("{a: {$gt: 0, $lt: 9}}"));
assertNumSolutions(2U);
@@ -162,8 +162,8 @@ TEST_F(QueryPlannerAllPathsTest, MultiplePredicatesOverMultikeyFieldNoElemMatch)
"bounds: {'$_path': [['a','a',true,true]], a: [[0,Infinity,false,true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, MultiplePredicatesOverMultikeyFieldWithElemMatch) {
- addAllPathsIndex(BSON("$**" << 1), {"a"});
+TEST_F(QueryPlannerWildcardTest, MultiplePredicatesOverMultikeyFieldWithElemMatch) {
+ addWildcardIndex(BSON("$**" << 1), {"a"});
runQuery(fromjson("{a: {$elemMatch: {$gt: 0, $lt: 9}}}"));
assertNumSolutions(1U);
@@ -173,8 +173,8 @@ TEST_F(QueryPlannerAllPathsTest, MultiplePredicatesOverMultikeyFieldWithElemMatc
"bounds: {'$_path': [['a','a',true,true]], a: [[0,9,false,false]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, MultiplePredicatesOverNonMultikeyFieldWithMultikeyIndex) {
- addAllPathsIndex(BSON("$**" << 1), {"b"});
+TEST_F(QueryPlannerWildcardTest, MultiplePredicatesOverNonMultikeyFieldWithMultikeyIndex) {
+ addWildcardIndex(BSON("$**" << 1), {"b"});
runQuery(fromjson("{a: {$gt: 0, $lt: 9}}"));
assertNumSolutions(1U);
@@ -183,8 +183,8 @@ TEST_F(QueryPlannerAllPathsTest, MultiplePredicatesOverNonMultikeyFieldWithMulti
"bounds: {'$_path': [['a','a',true,true]], a: [[0,9,false,false]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, MultiplePredicatesOverNestedFieldWithFirstComponentMultikey) {
- addAllPathsIndex(BSON("$**" << 1), {"a"});
+TEST_F(QueryPlannerWildcardTest, MultiplePredicatesOverNestedFieldWithFirstComponentMultikey) {
+ addWildcardIndex(BSON("$**" << 1), {"a"});
runQuery(fromjson("{'a.b': {$gt: 0, $lt: 9}}"));
assertNumSolutions(2U);
@@ -198,8 +198,8 @@ TEST_F(QueryPlannerAllPathsTest, MultiplePredicatesOverNestedFieldWithFirstCompo
"bounds: {'$_path': [['a.b','a.b',true,true]], 'a.b': [[0,Infinity,false,true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, MultiplePredicatesOverNestedFieldWithElemMatchObject) {
- addAllPathsIndex(BSON("$**" << 1), {"a"});
+TEST_F(QueryPlannerWildcardTest, MultiplePredicatesOverNestedFieldWithElemMatchObject) {
+ addWildcardIndex(BSON("$**" << 1), {"a"});
runQuery(fromjson("{a: {$elemMatch: {b: {$gt: 0, $lt: 9}}}}"));
assertNumSolutions(1U);
@@ -209,9 +209,9 @@ TEST_F(QueryPlannerAllPathsTest, MultiplePredicatesOverNestedFieldWithElemMatchO
"bounds: {'$_path': [['a.b','a.b',true,true]], 'a.b': [[0,9,false,false]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest,
+TEST_F(QueryPlannerWildcardTest,
MultiplePredicatesOverNestedFieldWithElemMatchObjectBothComponentsMultikey) {
- addAllPathsIndex(BSON("$**" << 1), {"a", "a.b"});
+ addWildcardIndex(BSON("$**" << 1), {"a", "a.b"});
runQuery(fromjson("{a: {$elemMatch: {b: {$gt: 0, $lt: 9}}}}"));
assertNumSolutions(2U);
@@ -225,8 +225,8 @@ TEST_F(QueryPlannerAllPathsTest,
"bounds: {'$_path': [['a.b','a.b',true,true]], 'a.b': [[0,Infinity,false,true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, MultiplePredicatesOverNestedFieldWithTwoElemMatches) {
- addAllPathsIndex(BSON("$**" << 1), {"a", "a.b"});
+TEST_F(QueryPlannerWildcardTest, MultiplePredicatesOverNestedFieldWithTwoElemMatches) {
+ addWildcardIndex(BSON("$**" << 1), {"a", "a.b"});
runQuery(fromjson("{a: {$elemMatch: {b: {$elemMatch: {$gt: 0, $lt: 9}}}}}"));
assertNumSolutions(1U);
@@ -236,8 +236,8 @@ TEST_F(QueryPlannerAllPathsTest, MultiplePredicatesOverNestedFieldWithTwoElemMat
"bounds: {'$_path': [['a.b','a.b',true,true]], 'a.b': [[0,9,false,false]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, ElemMatchOnInnermostMultikeyPathPermitsTightBounds) {
- addAllPathsIndex(BSON("$**" << 1), {"a", "a.b", "a.b.c"});
+TEST_F(QueryPlannerWildcardTest, ElemMatchOnInnermostMultikeyPathPermitsTightBounds) {
+ addWildcardIndex(BSON("$**" << 1), {"a", "a.b", "a.b.c"});
runQuery(fromjson("{'a.b.c': {$elemMatch: {'d.e.f': {$gt: 0, $lt: 9}}}}"));
assertNumSolutions(1U);
@@ -248,8 +248,8 @@ TEST_F(QueryPlannerAllPathsTest, ElemMatchOnInnermostMultikeyPathPermitsTightBou
"'a.b.c.d.e.f': [[0,9,false,false]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, AllPredsEligibleForIndexUseGenerateCandidatePlans) {
- addAllPathsIndex(BSON("a.$**" << 1), {"a.b", "a.c"});
+TEST_F(QueryPlannerWildcardTest, AllPredsEligibleForIndexUseGenerateCandidatePlans) {
+ addWildcardIndex(BSON("a.$**" << 1), {"a.b", "a.c"});
runQuery(
fromjson("{'a.b': {$gt: 0, $lt: 9}, 'a.c': {$gt: 11, $lt: 20}, d: {$gt: 31, $lt: 40}}"));
@@ -272,8 +272,8 @@ TEST_F(QueryPlannerAllPathsTest, AllPredsEligibleForIndexUseGenerateCandidatePla
"bounds: {'$_path': [['a.b','a.b',true,true]], 'a.b': [[0,Infinity,false,true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, RangeIndexScan) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, RangeIndexScan) {
+ addWildcardIndex(BSON("$**" << 1));
runQuery(fromjson("{a: {$gt: 0, $lt: 9}}"));
assertNumSolutions(1U);
@@ -283,8 +283,8 @@ TEST_F(QueryPlannerAllPathsTest, RangeIndexScan) {
"bounds: {'$_path': [['a','a',true,true]], a: [[0,9,false,false]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, RangeIndexScanEmptyRange) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, RangeIndexScanEmptyRange) {
+ addWildcardIndex(BSON("$**" << 1));
runQuery(fromjson("{a: {$gt: 9, $lt: 0}}"));
assertNumSolutions(1U);
@@ -294,8 +294,8 @@ TEST_F(QueryPlannerAllPathsTest, RangeIndexScanEmptyRange) {
"bounds: {'$_path': [['a','a',true,true]], 'a': []}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, RangeIndexScanMinKeyMaxKey) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, RangeIndexScanMinKeyMaxKey) {
+ addWildcardIndex(BSON("$**" << 1));
runQuery(fromjson("{a: {$gt: {$minKey: 1}, $lt: {$maxKey: 1}}}"));
assertNumSolutions(1U);
@@ -306,8 +306,8 @@ TEST_F(QueryPlannerAllPathsTest, RangeIndexScanMinKeyMaxKey) {
"'MaxKey', true, true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, RangeIndexScanNestedField) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, RangeIndexScanNestedField) {
+ addWildcardIndex(BSON("$**" << 1));
runQuery(fromjson("{'a.b': {$gt: 0, $lt: 9}}"));
assertNumSolutions(1U);
@@ -317,8 +317,8 @@ TEST_F(QueryPlannerAllPathsTest, RangeIndexScanNestedField) {
"bounds: {'$_path': [['a.b','a.b',true,true]], 'a.b': [[0,9,false,false]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, EqualityIndexScan) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, EqualityIndexScan) {
+ addWildcardIndex(BSON("$**" << 1));
runQuery(fromjson("{a: {$eq: 5}}"));
assertNumSolutions(1U);
@@ -328,8 +328,8 @@ TEST_F(QueryPlannerAllPathsTest, EqualityIndexScan) {
"bounds: {'$_path': [['a','a',true,true]], a: [[5,5,true,true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, EqualityIndexScanOverNestedField) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, EqualityIndexScanOverNestedField) {
+ addWildcardIndex(BSON("$**" << 1));
runQuery(fromjson("{'a.b': {$eq: 5}}"));
assertNumSolutions(1U);
@@ -339,8 +339,8 @@ TEST_F(QueryPlannerAllPathsTest, EqualityIndexScanOverNestedField) {
"bounds: {'$_path': [['a.b','a.b',true,true]], 'a.b': [[5,5,true,true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, ExprEqCanUseIndex) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, ExprEqCanUseIndex) {
+ addWildcardIndex(BSON("$**" << 1));
runQuery(fromjson("{a: {$_internalExprEq: 1}}"));
assertNumSolutions(1U);
@@ -349,8 +349,8 @@ TEST_F(QueryPlannerAllPathsTest, ExprEqCanUseIndex) {
"bounds: {'$_path': [['a','a',true,true]], a: [[1,1,true,true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, ExprEqCanUseSparseIndexForEqualityToNull) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, ExprEqCanUseSparseIndexForEqualityToNull) {
+ addWildcardIndex(BSON("$**" << 1));
runQuery(fromjson("{a: {$_internalExprEq: null}}"));
assertNumSolutions(1U);
@@ -360,7 +360,7 @@ TEST_F(QueryPlannerAllPathsTest, ExprEqCanUseSparseIndexForEqualityToNull) {
"[null,null,true,true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, PrefixRegex) {
+TEST_F(QueryPlannerWildcardTest, PrefixRegex) {
addIndex(BSON("$**" << 1));
runQuery(fromjson("{a: /^foo/}"));
@@ -371,7 +371,7 @@ TEST_F(QueryPlannerAllPathsTest, PrefixRegex) {
"a: [['foo','fop',true,false], [/^foo/,/^foo/,true,true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, NonPrefixRegex) {
+TEST_F(QueryPlannerWildcardTest, NonPrefixRegex) {
addIndex(BSON("$**" << 1));
runQuery(fromjson("{a: /foo/}"));
@@ -382,8 +382,8 @@ TEST_F(QueryPlannerAllPathsTest, NonPrefixRegex) {
"a: [['',{},true,false], [/foo/,/foo/,true,true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, GreaterThan) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, GreaterThan) {
+ addWildcardIndex(BSON("$**" << 1));
runQuery(fromjson("{a: {$gt: 5}}"));
assertNumSolutions(1U);
@@ -393,8 +393,8 @@ TEST_F(QueryPlannerAllPathsTest, GreaterThan) {
"bounds: {'$_path': [['a','a',true,true]], a: [[5,Infinity,false,true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, GreaterThanEqualTo) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, GreaterThanEqualTo) {
+ addWildcardIndex(BSON("$**" << 1));
runQuery(fromjson("{a: {$gte: 5}}"));
assertNumSolutions(1U);
@@ -404,8 +404,8 @@ TEST_F(QueryPlannerAllPathsTest, GreaterThanEqualTo) {
"bounds: {'$_path': [['a','a',true,true]], a: [[5,Infinity,true,true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, LessThan) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, LessThan) {
+ addWildcardIndex(BSON("$**" << 1));
runQuery(fromjson("{a: {$lt: 5}}"));
assertNumSolutions(1U);
@@ -415,8 +415,8 @@ TEST_F(QueryPlannerAllPathsTest, LessThan) {
"bounds: {'$_path': [['a','a',true,true]], a: [[-Infinity,5,true,false]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, LessThanEqualTo) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, LessThanEqualTo) {
+ addWildcardIndex(BSON("$**" << 1));
runQuery(fromjson("{a: {$lte: 5}}"));
assertNumSolutions(1U);
@@ -426,8 +426,8 @@ TEST_F(QueryPlannerAllPathsTest, LessThanEqualTo) {
"bounds: {'$_path': [['a','a',true,true]], a: [[-Infinity,5,true,true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, Mod) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, Mod) {
+ addWildcardIndex(BSON("$**" << 1));
runQuery(fromjson("{a: {$mod: [2, 0]}}"));
assertNumSolutions(1U);
@@ -437,8 +437,8 @@ TEST_F(QueryPlannerAllPathsTest, Mod) {
"bounds: {'$_path': [['a','a',true,true]], a: [[NaN,Infinity, true, true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, ExistsTrue) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, ExistsTrue) {
+ addWildcardIndex(BSON("$**" << 1));
runQuery(fromjson("{x: {$exists: true}}"));
assertNumSolutions(1U);
@@ -449,16 +449,16 @@ TEST_F(QueryPlannerAllPathsTest, ExistsTrue) {
"[['MinKey','MaxKey',true,true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, ExistsFalseDoesNotUseIndex) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, ExistsFalseDoesNotUseIndex) {
+ addWildcardIndex(BSON("$**" << 1));
runQuery(fromjson("{x: {$exists: false}}"));
assertNumSolutions(1U);
assertSolutionExists("{cscan: {dir: 1}}");
}
-TEST_F(QueryPlannerAllPathsTest, AndEqualityWithTwoPredicatesIndexesOnePath) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, AndEqualityWithTwoPredicatesIndexesOnePath) {
+ addWildcardIndex(BSON("$**" << 1));
runQuery(fromjson("{a: 5, b: 10}"));
assertNumSolutions(2U);
@@ -468,8 +468,8 @@ TEST_F(QueryPlannerAllPathsTest, AndEqualityWithTwoPredicatesIndexesOnePath) {
"bounds: {'$_path': [['a','a',true,true]], a: [[5,5,true,true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, OrEqualityWithTwoPredicatesUsesTwoPaths) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, OrEqualityWithTwoPredicatesUsesTwoPaths) {
+ addWildcardIndex(BSON("$**" << 1));
runQuery(fromjson("{$or: [{a: 5}, {b: 10}]}"));
assertNumSolutions(1U);
@@ -482,8 +482,8 @@ TEST_F(QueryPlannerAllPathsTest, OrEqualityWithTwoPredicatesUsesTwoPaths) {
;
}
-TEST_F(QueryPlannerAllPathsTest, OrWithOneRegularAndOneAllPathsIndexPathUsesTwoIndexes) {
- addAllPathsIndex(BSON("a.$**" << 1));
+TEST_F(QueryPlannerWildcardTest, OrWithOneRegularAndOneWildcardIndexPathUsesTwoIndexes) {
+ addWildcardIndex(BSON("a.$**" << 1));
addIndex(BSON("b" << 1));
runQuery(fromjson("{$or: [{a: 5}, {b: 10}]}"));
@@ -497,8 +497,8 @@ TEST_F(QueryPlannerAllPathsTest, OrWithOneRegularAndOneAllPathsIndexPathUsesTwoI
;
}
-TEST_F(QueryPlannerAllPathsTest, BasicSkip) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, BasicSkip) {
+ addWildcardIndex(BSON("$**" << 1));
runQuerySkipNToReturn(BSON("a" << 5), 8, 0);
assertNumSolutions(1U);
@@ -508,8 +508,8 @@ TEST_F(QueryPlannerAllPathsTest, BasicSkip) {
"bounds: {'$_path': [['a','a',true,true]], a: [[5,5,true,true]]}}}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, CoveredSkip) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, CoveredSkip) {
+ addWildcardIndex(BSON("$**" << 1));
runQuerySortProjSkipNToReturn(fromjson("{a: 5}"), BSONObj(), fromjson("{_id: 0, a: 1}"), 8, 0);
assertNumSolutions(1U);
@@ -519,8 +519,8 @@ TEST_F(QueryPlannerAllPathsTest, CoveredSkip) {
"bounds: {'$_path': [['a','a',true,true]], a: [[5,5,true,true]]}}}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, BasicLimit) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, BasicLimit) {
+ addWildcardIndex(BSON("$**" << 1));
runQuerySkipNToReturn(BSON("a" << 5), 0, -5);
assertNumSolutions(1U);
@@ -530,8 +530,8 @@ TEST_F(QueryPlannerAllPathsTest, BasicLimit) {
"bounds: {'$_path': [['a','a',true,true]], a: [[5,5,true,true]]}}}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, BasicCovering) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, BasicCovering) {
+ addWildcardIndex(BSON("$**" << 1));
runQuerySortProj(fromjson("{ x : {$gt: 1}}"), BSONObj(), fromjson("{_id: 0, x: 1}"));
assertNumSolutions(1U);
@@ -540,8 +540,8 @@ TEST_F(QueryPlannerAllPathsTest, BasicCovering) {
"bounds: {'$_path': [['x','x',true,true]], x: [[1,Infinity,false,true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, DottedFieldCovering) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, DottedFieldCovering) {
+ addWildcardIndex(BSON("$**" << 1));
runQuerySortProj(fromjson("{'a.b': 5}"), BSONObj(), fromjson("{_id: 0, 'a.b': 1}"));
assertNumSolutions(1U);
@@ -551,9 +551,9 @@ TEST_F(QueryPlannerAllPathsTest, DottedFieldCovering) {
"bounds: {'$_path': [['a.b','a.b',true,true]], 'a.b': [[5,5,true,true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, CoveredIxscanForCountOnIndexedPath) {
+TEST_F(QueryPlannerWildcardTest, CoveredIxscanForCountOnIndexedPath) {
params.options = QueryPlannerParams::IS_COUNT;
- addAllPathsIndex(BSON("$**" << 1));
+ addWildcardIndex(BSON("$**" << 1));
runQuery(fromjson("{a: 5}"));
assertNumSolutions(1U);
@@ -562,8 +562,8 @@ TEST_F(QueryPlannerAllPathsTest, CoveredIxscanForCountOnIndexedPath) {
"bounds: {'$_path': [['a','a',true,true]], 'a': [[5,5,true,true]]}}}");
}
-TEST_F(QueryPlannerAllPathsTest, InBasic) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, InBasic) {
+ addWildcardIndex(BSON("$**" << 1));
runQuery(fromjson("{a: {$in: [1, 2]}}"));
assertNumSolutions(1U);
@@ -573,8 +573,8 @@ TEST_F(QueryPlannerAllPathsTest, InBasic) {
"bounds: {'$_path': [['a','a',true,true]], a: [[1,1,true,true],[2,2,true,true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, EqualsEmptyArray) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, EqualsEmptyArray) {
+ addWildcardIndex(BSON("$**" << 1));
runQuery(fromjson("{a: []}"));
assertNumSolutions(1U);
@@ -584,29 +584,29 @@ TEST_F(QueryPlannerAllPathsTest, EqualsEmptyArray) {
"[[undefined,undefined,true,true],[[],[],true,true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, EqualsNonEmptyArray) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, EqualsNonEmptyArray) {
+ addWildcardIndex(BSON("$**" << 1));
runQuery(fromjson("{a: [1]}"));
assertHasOnlyCollscan();
}
-TEST_F(QueryPlannerAllPathsTest, EqualsNestedEmptyArray) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, EqualsNestedEmptyArray) {
+ addWildcardIndex(BSON("$**" << 1));
runQuery(fromjson("{a: [[]]}"));
assertHasOnlyCollscan();
}
-TEST_F(QueryPlannerAllPathsTest, EqualsArrayWithValue) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, EqualsArrayWithValue) {
+ addWildcardIndex(BSON("$**" << 1));
runQuery(fromjson("{a: [[1]]}"));
assertHasOnlyCollscan();
}
-TEST_F(QueryPlannerAllPathsTest, InEmptyArray) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, InEmptyArray) {
+ addWildcardIndex(BSON("$**" << 1));
runQuery(fromjson("{a: {$in: [[]]}}"));
assertNumSolutions(1U);
@@ -616,22 +616,22 @@ TEST_F(QueryPlannerAllPathsTest, InEmptyArray) {
"[[undefined,undefined,true,true],[[],[],true,true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, InNonEmptyArray) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, InNonEmptyArray) {
+ addWildcardIndex(BSON("$**" << 1));
runQuery(fromjson("{a: {$in: [[1]]}}"));
assertHasOnlyCollscan();
}
-TEST_F(QueryPlannerAllPathsTest, InNestedEmptyArray) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, InNestedEmptyArray) {
+ addWildcardIndex(BSON("$**" << 1));
runQuery(fromjson("{a: {$in: [[[]]]}}"));
assertHasOnlyCollscan();
}
-TEST_F(QueryPlannerAllPathsTest, InArrayWithValue) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, InArrayWithValue) {
+ addWildcardIndex(BSON("$**" << 1));
runQuery(fromjson("{a: {$in: [[[1]]]}}"));
assertHasOnlyCollscan();
@@ -639,8 +639,8 @@ TEST_F(QueryPlannerAllPathsTest, InArrayWithValue) {
// Logically equivalent to the preceding $in query.
// Indexed solution should be the same.
-TEST_F(QueryPlannerAllPathsTest, InBasicOrEquivalent) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, InBasicOrEquivalent) {
+ addWildcardIndex(BSON("$**" << 1));
runQuery(fromjson("{$or: [{a: 1}, {a: 2}]}"));
assertNumSolutions(1U);
@@ -650,10 +650,10 @@ TEST_F(QueryPlannerAllPathsTest, InBasicOrEquivalent) {
"bounds: {'$_path': [['a','a',true,true]], a: [[1,1,true,true],[2,2,true,true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, PartialIndexCanAnswerPredicateOnFilteredField) {
+TEST_F(QueryPlannerWildcardTest, PartialIndexCanAnswerPredicateOnFilteredField) {
auto filterObj = fromjson("{a: {$gt: 0}}");
auto filterExpr = QueryPlannerTest::parseMatchExpression(filterObj);
- addAllPathsIndex(BSON("$**" << 1), {}, BSONObj{}, filterExpr.get());
+ addWildcardIndex(BSON("$**" << 1), {}, BSONObj{}, filterExpr.get());
runQuery(fromjson("{a: {$gte: 5}}"));
assertNumSolutions(1U);
@@ -677,12 +677,12 @@ TEST_F(QueryPlannerAllPathsTest, PartialIndexCanAnswerPredicateOnFilteredField)
"bounds: {'$_path': [['a','a',true,true]], a: [[1,10,true,true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, PartialIndexDoesNotAnswerPredicatesExcludedByFilter) {
+TEST_F(QueryPlannerWildcardTest, PartialIndexDoesNotAnswerPredicatesExcludedByFilter) {
// Must keep 'filterObj' around since match expressions will store pointers into the BSON they
// were parsed from.
auto filterObj = fromjson("{a: {$gt: 0}}");
auto filterExpr = QueryPlannerTest::parseMatchExpression(filterObj);
- addAllPathsIndex(BSON("$**" << 1), {}, BSONObj{}, filterExpr.get());
+ addWildcardIndex(BSON("$**" << 1), {}, BSONObj{}, filterExpr.get());
runQuery(fromjson("{a: {$gte: -1}}"));
assertHasOnlyCollscan();
@@ -694,10 +694,10 @@ TEST_F(QueryPlannerAllPathsTest, PartialIndexDoesNotAnswerPredicatesExcludedByFi
assertHasOnlyCollscan();
}
-TEST_F(QueryPlannerAllPathsTest, PartialIndexCanAnswerPredicateOnUnrelatedField) {
+TEST_F(QueryPlannerWildcardTest, PartialIndexCanAnswerPredicateOnUnrelatedField) {
auto filterObj = fromjson("{a: {$gt: 0}}");
auto filterExpr = QueryPlannerTest::parseMatchExpression(filterObj);
- addAllPathsIndex(BSON("$**" << 1), {}, BSONObj{}, filterExpr.get());
+ addWildcardIndex(BSON("$**" << 1), {}, BSONObj{}, filterExpr.get());
// Test when the field query is not included by the partial filter expression.
runQuery(fromjson("{b: {$gte: -1}, a: {$gte: 5}}"));
@@ -712,10 +712,10 @@ TEST_F(QueryPlannerAllPathsTest, PartialIndexCanAnswerPredicateOnUnrelatedField)
"bounds: {'$_path': [['a','a',true,true]], a: [[5,Infinity,true,true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, PartialIndexWithExistsTrueFilterCanAnswerExistenceQuery) {
+TEST_F(QueryPlannerWildcardTest, PartialIndexWithExistsTrueFilterCanAnswerExistenceQuery) {
auto filterObj = fromjson("{x: {$exists: true}}");
auto filterExpr = QueryPlannerTest::parseMatchExpression(filterObj);
- addAllPathsIndex(BSON("$**" << 1), {}, BSONObj{}, filterExpr.get());
+ addWildcardIndex(BSON("$**" << 1), {}, BSONObj{}, filterExpr.get());
runQuery(fromjson("{x: {$exists: true}}"));
assertNumSolutions(1U);
@@ -730,7 +730,7 @@ TEST_F(QueryPlannerAllPathsTest, PartialIndexWithExistsTrueFilterCanAnswerExiste
// Index intersection tests.
//
-TEST_F(QueryPlannerAllPathsTest, AllPathsIndexDoesNotParticipateInIndexIntersection) {
+TEST_F(QueryPlannerWildcardTest, WildcardIndexDoesNotParticipateInIndexIntersection) {
// Enable both AND_SORTED and AND_HASH index intersection for this test.
params.options |= QueryPlannerParams::INDEX_INTERSECTION;
internalQueryPlannerEnableHashIntersection.store(true);
@@ -764,7 +764,7 @@ TEST_F(QueryPlannerAllPathsTest, AllPathsIndexDoesNotParticipateInIndexIntersect
"{filter: null, pattern: {a:1}}},{ixscan: {filter: null, pattern: {b:1}}}]}}}}");
// Now add a $** index and re-run the tests.
- addAllPathsIndex(BSON("$**" << 1));
+ addWildcardIndex(BSON("$**" << 1));
// First re-run the AND_SORTED test.
runQuery(fromjson("{a:10, b:10}"));
@@ -804,17 +804,17 @@ TEST_F(QueryPlannerAllPathsTest, AllPathsIndexDoesNotParticipateInIndexIntersect
}
//
-// AllPaths and $text index tests.
+// Wildcard and $text index tests.
//
-TEST_F(QueryPlannerAllPathsTest, AllPathsIndexDoesNotSupplyCandidatePlanForTextSearch) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, WildcardIndexDoesNotSupplyCandidatePlanForTextSearch) {
+ addWildcardIndex(BSON("$**" << 1));
addIndex(BSON("a" << 1 << "_fts"
<< "text"
<< "_ftsx"
<< 1));
- // Confirm that the allPaths index generates candidate plans for queries which do not include a
+ // Confirm that the wildcard index generates candidate plans for queries which do not include a
// $text predicate.
runQuery(fromjson("{a: 10, b: 10}"));
assertNumSolutions(2U);
@@ -823,7 +823,7 @@ TEST_F(QueryPlannerAllPathsTest, AllPathsIndexDoesNotSupplyCandidatePlanForTextS
assertSolutionExists(
"{fetch: {filter: {a: 10}, node: {ixscan: {filter: null, pattern: {'$_path': 1, b: 1}}}}}");
- // Confirm that the allPaths index does not produce any candidate plans when a query includes a
+ // Confirm that the wildcard index does not produce any candidate plans when a query includes a
// $text predicate, even for non-$text predicates which may be present in the query.
runQuery(fromjson("{a: 10, b: 10, $text: {$search: 'banana'}}"));
assertNumSolutions(1U);
@@ -831,10 +831,10 @@ TEST_F(QueryPlannerAllPathsTest, AllPathsIndexDoesNotSupplyCandidatePlanForTextS
"{fetch: {filter: {b: 10}, node: {text: {prefix: {a: 10}, search: 'banana'}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, AllPathsDoesNotSupportNegationPredicate) {
- // AllPaths indexes can't support negation queries because they are sparse, and {a: {$ne: 5}}
+TEST_F(QueryPlannerWildcardTest, WildcardDoesNotSupportNegationPredicate) {
+ // Wildcard indexes can't support negation queries because they are sparse, and {a: {$ne: 5}}
// will match documents which don't have an "a" field.
- addAllPathsIndex(BSON("$**" << 1));
+ addWildcardIndex(BSON("$**" << 1));
runQuery(fromjson("{a: {$ne: 5}}"));
assertHasOnlyCollscan();
@@ -842,11 +842,11 @@ TEST_F(QueryPlannerAllPathsTest, AllPathsDoesNotSupportNegationPredicate) {
assertHasOnlyCollscan();
}
-TEST_F(QueryPlannerAllPathsTest,
- AllPathsDoesNotSupportNegationPredicateInsideElemMatchMultiKeyPath) {
- // Logically, there's no reason a (sparse) allPaths index could not support a negation inside a
+TEST_F(QueryPlannerWildcardTest,
+ WildcardDoesNotSupportNegationPredicateInsideElemMatchMultiKeyPath) {
+ // Logically, there's no reason a (sparse) wildcard index could not support a negation inside a
// "$elemMatch value", but it is not something we've implemented.
- addAllPathsIndex(BSON("$**" << 1), {"a"});
+ addWildcardIndex(BSON("$**" << 1), {"a"});
runQuery(fromjson("{a: {$elemMatch: {$ne: 5}}}"));
assertHasOnlyCollscan();
@@ -854,11 +854,11 @@ TEST_F(QueryPlannerAllPathsTest,
assertHasOnlyCollscan();
}
-TEST_F(QueryPlannerAllPathsTest, AllPathsDoesNotSupportNegationPredicateInsideElemMatch) {
+TEST_F(QueryPlannerWildcardTest, WildcardDoesNotSupportNegationPredicateInsideElemMatch) {
// Test the case where we use $elemMatch on a path which isn't even multikey. In this case,
// we'd know up front that the results would be empty, but this is not an optimization we
// support.
- addAllPathsIndex(BSON("$**" << 1));
+ addWildcardIndex(BSON("$**" << 1));
runQuery(fromjson("{a: {$elemMatch: {$ne: 5}}}"));
assertHasOnlyCollscan();
@@ -870,7 +870,7 @@ TEST_F(QueryPlannerAllPathsTest, AllPathsDoesNotSupportNegationPredicateInsideEl
// Hinting with all paths index tests.
//
-TEST_F(QueryPlannerTest, ChooseAllPathsIndexHint) {
+TEST_F(QueryPlannerTest, ChooseWildcardIndexHint) {
addIndex(BSON("$**" << 1));
addIndex(BSON("x" << 1));
@@ -880,21 +880,21 @@ TEST_F(QueryPlannerTest, ChooseAllPathsIndexHint) {
assertSolutionExists("{fetch: {node: {ixscan: {pattern: {$_path: 1, x: 1}}}}}");
}
-TEST_F(QueryPlannerTest, ChooseAllPathsIndexHintByName) {
- StringData allPaths = "allPaths";
+TEST_F(QueryPlannerTest, ChooseWildcardIndexHintByName) {
+ StringData wildcard = "wildcard";
CollatorInterface* nullCollator = nullptr;
- addIndex(BSON("$**" << 1), nullCollator, allPaths);
+ addIndex(BSON("$**" << 1), nullCollator, wildcard);
addIndex(BSON("x" << 1));
runQueryHint(fromjson("{x: {$eq: 1}}"),
BSON("$hint"
- << "allPaths"));
+ << "wildcard"));
assertNumSolutions(1U);
assertSolutionExists("{fetch: {node: {ixscan: {pattern: {$_path: 1, x: 1}}}}}");
}
-TEST_F(QueryPlannerTest, ChooseAllPathsIndexHintWithPath) {
+TEST_F(QueryPlannerTest, ChooseWildcardIndexHintWithPath) {
addIndex(BSON("x.$**" << 1));
addIndex(BSON("x" << 1));
@@ -904,7 +904,7 @@ TEST_F(QueryPlannerTest, ChooseAllPathsIndexHintWithPath) {
assertSolutionExists("{fetch: {node: {ixscan: {pattern: {$_path: 1, x: 1}}}}}");
}
-TEST_F(QueryPlannerTest, ChooseAllPathsIndexHintWithOr) {
+TEST_F(QueryPlannerTest, ChooseWildcardIndexHintWithOr) {
addIndex(BSON("$**" << 1));
addIndex(BSON("x" << 1 << "y" << 1));
@@ -916,7 +916,7 @@ TEST_F(QueryPlannerTest, ChooseAllPathsIndexHintWithOr) {
" {ixscan: {pattern: {$_path: 1, y: 1}}}]}}}}");
}
-TEST_F(QueryPlannerTest, ChooseAllPathsIndexHintWithCompoundIndex) {
+TEST_F(QueryPlannerTest, ChooseWildcardIndexHintWithCompoundIndex) {
addIndex(BSON("$**" << 1));
addIndex(BSON("x" << 1 << "y" << 1));
@@ -927,7 +927,7 @@ TEST_F(QueryPlannerTest, ChooseAllPathsIndexHintWithCompoundIndex) {
assertSolutionExists("{fetch: {node: {ixscan: {pattern: {$_path: 1, y: 1}}}}}");
}
-TEST_F(QueryPlannerTest, QueryNotInAllPathsIndexHint) {
+TEST_F(QueryPlannerTest, QueryNotInWildcardIndexHint) {
addIndex(BSON("a.$**" << 1));
addIndex(BSON("x" << 1));
@@ -935,13 +935,13 @@ TEST_F(QueryPlannerTest, QueryNotInAllPathsIndexHint) {
assertNumSolutions(0U);
}
-TEST_F(QueryPlannerTest, AllPathsIndexDoesNotExist) {
+TEST_F(QueryPlannerTest, WildcardIndexDoesNotExist) {
addIndex(BSON("x" << 1));
runInvalidQueryHint(fromjson("{x: {$eq: 1}}"), BSON("$**" << 1));
}
-TEST_F(QueryPlannerTest, AllPathsIndexHintWithPartialFilter) {
+TEST_F(QueryPlannerTest, WildcardIndexHintWithPartialFilter) {
auto filterObj = fromjson("{a: {$gt: 100}}");
auto filterExpr = QueryPlannerTest::parseMatchExpression(filterObj);
addIndex(BSON("$**" << 1), filterExpr.get());
@@ -950,7 +950,7 @@ TEST_F(QueryPlannerTest, AllPathsIndexHintWithPartialFilter) {
assertNumSolutions(0U);
}
-TEST_F(QueryPlannerTest, MultipleAllPathsIndexesHintWithPartialFilter) {
+TEST_F(QueryPlannerTest, MultipleWildcardIndexesHintWithPartialFilter) {
auto filterObj = fromjson("{a: {$gt: 100}, b: {$gt: 100}}");
auto filterExpr = QueryPlannerTest::parseMatchExpression(filterObj);
addIndex(BSON("$**" << 1), filterExpr.get());
@@ -959,7 +959,7 @@ TEST_F(QueryPlannerTest, MultipleAllPathsIndexesHintWithPartialFilter) {
assertNumSolutions(0U);
}
-TEST_F(QueryPlannerAllPathsTest, AllPathsIndexesDoNotSupportObjectEquality) {
+TEST_F(QueryPlannerWildcardTest, WildcardIndexesDoNotSupportObjectEquality) {
addIndex(BSON("$**" << 1));
runQuery(fromjson("{x: {abc: 1}}"));
@@ -974,7 +974,7 @@ TEST_F(QueryPlannerAllPathsTest, AllPathsIndexesDoNotSupportObjectEquality) {
assertSolutionExists("{fetch: {node: {ixscan: {pattern: {$_path: 1, x: 1}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, AllPathsIndexesDoNotSupportObjectInequality) {
+TEST_F(QueryPlannerWildcardTest, WildcardIndexesDoNotSupportObjectInequality) {
addIndex(BSON("$**" << 1));
runQuery(fromjson("{x: {$lt: {abc: 1}}}"));
@@ -1007,7 +1007,7 @@ TEST_F(QueryPlannerAllPathsTest, AllPathsIndexesDoNotSupportObjectInequality) {
assertSolutionExists("{fetch: {node: {ixscan: {pattern: {$_path: 1, x: 1}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, AllPathsIndexesDoNotSupportInWithUnsupportedValues) {
+TEST_F(QueryPlannerWildcardTest, WildcardIndexesDoNotSupportInWithUnsupportedValues) {
addIndex(BSON("$**" << 1));
runQuery(fromjson("{x: {$in: [1, 2, 3, {abc: 1}]}}"));
@@ -1018,7 +1018,7 @@ TEST_F(QueryPlannerAllPathsTest, AllPathsIndexesDoNotSupportInWithUnsupportedVal
assertHasOnlyCollscan();
}
-TEST_F(QueryPlannerAllPathsTest, AllPathsIndexesSupportElemMatchWithNull) {
+TEST_F(QueryPlannerWildcardTest, WildcardIndexesSupportElemMatchWithNull) {
addIndex(BSON("$**" << 1));
// Simple case.
@@ -1026,14 +1026,14 @@ TEST_F(QueryPlannerAllPathsTest, AllPathsIndexesSupportElemMatchWithNull) {
assertNumSolutions(1U);
assertSolutionExists("{fetch: {node: {ixscan: {pattern: {$_path: 1, x: 1}}}}}");
- // null inside an $in inside an $elemMatch is supported by the allPaths index, since it means
+ // null inside an $in inside an $elemMatch is supported by the wildcard index, since it means
// we're searching for an explicit null value.
runQuery(fromjson("{x: {$elemMatch: {$in: [1, 2, 3, null]}}}"));
assertNumSolutions(1U);
assertSolutionExists("{fetch: {node: {ixscan: {pattern: {$_path: 1, x: 1}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, AllPathsIndexesDoNotSupportElemMatchWithUnsupportedValues) {
+TEST_F(QueryPlannerWildcardTest, WildcardIndexesDoNotSupportElemMatchWithUnsupportedValues) {
runQuery(fromjson("{x: {$elemMatch: {$eq: ['a', 'b', 'c']}}}"));
assertHasOnlyCollscan();
@@ -1045,13 +1045,13 @@ TEST_F(QueryPlannerAllPathsTest, AllPathsIndexesDoNotSupportElemMatchWithUnsuppo
assertHasOnlyCollscan();
}
-TEST_F(QueryPlannerAllPathsTest, AllPathsIndexesDoNotSupportElemMatchObject) {
+TEST_F(QueryPlannerWildcardTest, WildcardIndexesDoNotSupportElemMatchObject) {
runQuery(fromjson("{x: {$elemMatch: {a: 1}}}"));
assertHasOnlyCollscan();
}
-TEST_F(QueryPlannerAllPathsTest, AllPathsIndexCanProvideNonBlockingSort) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, WildcardIndexCanProvideNonBlockingSort) {
+ addWildcardIndex(BSON("$**" << 1));
runQuerySortProj(fromjson("{a: 1}"), BSON("a" << 1), BSONObj());
assertNumSolutions(1U);
@@ -1060,9 +1060,9 @@ TEST_F(QueryPlannerAllPathsTest, AllPathsIndexCanProvideNonBlockingSort) {
"bounds: {'$_path': [['a','a',true,true]], a: [[1,1,true,true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest,
- AllPathsIndexCanProvideNonBlockingSortWhenFilterIncludesAdditionalFields) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest,
+ WildcardIndexCanProvideNonBlockingSortWhenFilterIncludesAdditionalFields) {
+ addWildcardIndex(BSON("$**" << 1));
runQuerySortProj(fromjson("{a: {$gte: 3}, b: 1}"), BSON("a" << 1), BSONObj());
assertNumSolutions(2U);
@@ -1079,8 +1079,8 @@ TEST_F(QueryPlannerAllPathsTest,
"bounds: {'$_path': [['b','b',true,true]], b: [[1, 1, true, true]]}}}}}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, AllPathsIndexMustUseBlockingSortWithElemMatch) {
- addAllPathsIndex(BSON("$**" << 1), {"a"});
+TEST_F(QueryPlannerWildcardTest, WildcardIndexMustUseBlockingSortWithElemMatch) {
+ addWildcardIndex(BSON("$**" << 1), {"a"});
runQuerySortProj(fromjson("{a: {$elemMatch: {$eq: 1}}}"), BSON("a" << 1), BSONObj());
assertNumSolutions(1U);
@@ -1091,8 +1091,8 @@ TEST_F(QueryPlannerAllPathsTest, AllPathsIndexMustUseBlockingSortWithElemMatch)
"bounds: {'$_path': [['a','a',true,true]], a: [[1, 1, true, true]]}}}}}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, AllPathsIndexMustUseBlockingSortWithCompoundSort) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, WildcardIndexMustUseBlockingSortWithCompoundSort) {
+ addWildcardIndex(BSON("$**" << 1));
runQuerySortProj(fromjson("{a: {$lte: 3}}"), BSON("a" << 1 << "b" << 1), BSONObj());
assertNumSolutions(1U);
@@ -1103,8 +1103,8 @@ TEST_F(QueryPlannerAllPathsTest, AllPathsIndexMustUseBlockingSortWithCompoundSor
"bounds: {'$_path': [['a','a',true,true]], a: [[-Infinity, 3, true, true]]}}}}}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, AllPathsIndexMustUseBlockingSortWithExistsQueries) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, WildcardIndexMustUseBlockingSortWithExistsQueries) {
+ addWildcardIndex(BSON("$**" << 1));
runQuerySortProj(fromjson("{a: {$exists: true}}"), BSON("a" << 1), BSONObj());
assertNumSolutions(1U);
@@ -1116,7 +1116,7 @@ TEST_F(QueryPlannerAllPathsTest, AllPathsIndexMustUseBlockingSortWithExistsQueri
"true]]}}}}}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, AllPathsIndexMustUseBlockingSortWhenFilterNotPresent) {
+TEST_F(QueryPlannerWildcardTest, WildcardIndexMustUseBlockingSortWhenFilterNotPresent) {
// Since there's no filter on the field that we're sorting by, we cannot use an index scan to
// answer the query as $** indexes are sparse.
runQuerySortProj(BSONObj(), fromjson("{a: 1}"), BSONObj());
@@ -1125,8 +1125,8 @@ TEST_F(QueryPlannerAllPathsTest, AllPathsIndexMustUseBlockingSortWhenFilterNotPr
"{cscan: {dir: 1}}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, AllPathsIndexMustUseBlockingSortWhenFilterDoesNotIncludeSortKey) {
- addAllPathsIndex(BSON("$**" << 1));
+TEST_F(QueryPlannerWildcardTest, WildcardIndexMustUseBlockingSortWhenFilterDoesNotIncludeSortKey) {
+ addWildcardIndex(BSON("$**" << 1));
runQuerySortProj(fromjson("{b: 1, c: 1}"), fromjson("{a: 1}"), BSONObj());
assertNumSolutions(2U);
@@ -1142,8 +1142,8 @@ TEST_F(QueryPlannerAllPathsTest, AllPathsIndexMustUseBlockingSortWhenFilterDoesN
"bounds: {'$_path': [['c','c',true,true]], c: [[1, 1, true, true]]}}}}}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, AllPathsIndexMustUseBlockingSortWhenFieldIsNotIncluded) {
- addAllPathsIndex(BSON("$**" << 1), {}, BSON("b" << 0));
+TEST_F(QueryPlannerWildcardTest, WildcardIndexMustUseBlockingSortWhenFieldIsNotIncluded) {
+ addWildcardIndex(BSON("$**" << 1), {}, BSON("b" << 0));
runQuerySortProj(fromjson("{b: 1}"), fromjson("{b: 1}"), BSONObj());
assertNumSolutions(1U);
@@ -1158,8 +1158,8 @@ TEST_F(QueryPlannerAllPathsTest, AllPathsIndexMustUseBlockingSortWhenFieldIsNotI
// Field name or array index tests.
//
-TEST_F(QueryPlannerAllPathsTest, CannotAnswerQueryThroughArrayIndexProjection) {
- addAllPathsIndex(BSON("$**" << 1), {"a"}, fromjson("{'a.0': 1, 'a.b': 1}"));
+TEST_F(QueryPlannerWildcardTest, CannotAnswerQueryThroughArrayIndexProjection) {
+ addWildcardIndex(BSON("$**" << 1), {"a"}, fromjson("{'a.0': 1, 'a.b': 1}"));
// Queries whose path lies along a projected array index cannot be answered.
runQuery(fromjson("{'a.0': 10}"));
@@ -1171,8 +1171,8 @@ TEST_F(QueryPlannerAllPathsTest, CannotAnswerQueryThroughArrayIndexProjection) {
assertSolutionExists("{cscan: {dir: 1}}");
}
-TEST_F(QueryPlannerAllPathsTest, CanAnswerQueryOnNonProjectedArrayIndex) {
- addAllPathsIndex(BSON("$**" << 1), {"a", "c"}, fromjson("{'a.0': 1, b: 1, c: 1}"));
+TEST_F(QueryPlannerWildcardTest, CanAnswerQueryOnNonProjectedArrayIndex) {
+ addWildcardIndex(BSON("$**" << 1), {"a", "c"}, fromjson("{'a.0': 1, b: 1, c: 1}"));
// Queries on fields that are not projected array indices can be answered, even when such a
// projection is present in the 'starPathsTempName' spec.
@@ -1191,8 +1191,8 @@ TEST_F(QueryPlannerAllPathsTest, CanAnswerQueryOnNonProjectedArrayIndex) {
"[[10,10,true,true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, ShouldGenerateAllPotentialPathBoundsForArrayIndexQueries) {
- addAllPathsIndex(BSON("a.$**" << 1), {"a", "a.b"});
+TEST_F(QueryPlannerWildcardTest, ShouldGenerateAllPotentialPathBoundsForArrayIndexQueries) {
+ addWildcardIndex(BSON("a.$**" << 1), {"a", "a.b"});
// A numeric path component immediately following a multikey path may represent an array index,
// a fieldname, or both. The $** index does not record array indices explicitly, so for all such
@@ -1221,8 +1221,8 @@ TEST_F(QueryPlannerAllPathsTest, ShouldGenerateAllPotentialPathBoundsForArrayInd
"['a.b.c','a.b.c',true,true]], 'a.0.b.1.c': [[10,10,true,true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, ShouldAddAllPredicatesToFetchFilterForArrayIndexQueries) {
- addAllPathsIndex(BSON("$**" << 1), {"a", "a.b"});
+TEST_F(QueryPlannerWildcardTest, ShouldAddAllPredicatesToFetchFilterForArrayIndexQueries) {
+ addWildcardIndex(BSON("$**" << 1), {"a", "a.b"});
// Ordinarily, a query such as {'a': {$gt: 0, $lt: 5}} on a multikey field 'a' produces an EXACT
// IXSCAN on one of the predicates and a FETCH filter on the other. For fieldname-or-array-index
@@ -1302,8 +1302,8 @@ TEST_F(QueryPlannerAllPathsTest, ShouldAddAllPredicatesToFetchFilterForArrayInde
"[[10,20,false,false]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, ShouldOnlyBuildSpecialBoundsForMultikeyPaths) {
- addAllPathsIndex(BSON("a.$**" << 1), {"a.b", "a.b.c.d"});
+TEST_F(QueryPlannerWildcardTest, ShouldOnlyBuildSpecialBoundsForMultikeyPaths) {
+ addWildcardIndex(BSON("a.$**" << 1), {"a.b", "a.b.c.d"});
// 'a' is not multikey, so 'a.0' refers specifically to a fieldname rather than an array index,
// and special bounds will not be generated.
@@ -1350,8 +1350,8 @@ TEST_F(QueryPlannerAllPathsTest, ShouldOnlyBuildSpecialBoundsForMultikeyPaths) {
"['a.b.c.d.e','a.b.c.d.e',true,true]], 'a.b.1.c.d.3.e':[[10,10,true,true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, ShouldGenerateSpecialBoundsForNumericMultikeyPaths) {
- addAllPathsIndex(BSON("a.$**" << 1), {"a.b", "a.b.0"});
+TEST_F(QueryPlannerWildcardTest, ShouldGenerateSpecialBoundsForNumericMultikeyPaths) {
+ addWildcardIndex(BSON("a.$**" << 1), {"a.b", "a.b.0"});
// 'a.b.0' is itself a multikey path, but since 'a.b' is multikey 'b.0' may refer to an array
// element of 'b'. We generate special bounds for 'b.0'.
@@ -1380,8 +1380,8 @@ TEST_F(QueryPlannerAllPathsTest, ShouldGenerateSpecialBoundsForNumericMultikeyPa
"['a.b.1.c','a.b.1.c',true,true]], 'a.b.1.1.c': [[10,10,true,true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, ShouldNotGenerateSpecialBoundsForFieldNamesWithLeadingZeroes) {
- addAllPathsIndex(BSON("a.$**" << 1), {"a.b"});
+TEST_F(QueryPlannerWildcardTest, ShouldNotGenerateSpecialBoundsForFieldNamesWithLeadingZeroes) {
+ addWildcardIndex(BSON("a.$**" << 1), {"a.b"});
// 'a.b' is multikey, but '01' is not eligible for consideration as a numeric array index; it is
// always strictly a field name. We therefore do not generate special bounds.
@@ -1392,8 +1392,8 @@ TEST_F(QueryPlannerAllPathsTest, ShouldNotGenerateSpecialBoundsForFieldNamesWith
"bounds: {'$_path': [['a.b.01','a.b.01',true,true]], 'a.b.01': [[10,10,true,true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, InitialNumericPathComponentIsAlwaysFieldName) {
- addAllPathsIndex(BSON("$**" << 1), {"0"}, fromjson("{'0': 1}"));
+TEST_F(QueryPlannerWildcardTest, InitialNumericPathComponentIsAlwaysFieldName) {
+ addWildcardIndex(BSON("$**" << 1), {"0"}, fromjson("{'0': 1}"));
// '0' is multikey, but the first component in a path can never be an array index since it must
// always be a field name. We therefore do not generate special bounds for '0.b'.
@@ -1412,8 +1412,8 @@ TEST_F(QueryPlannerAllPathsTest, InitialNumericPathComponentIsAlwaysFieldName) {
"'0.1.b': [[10,10,true,true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, ShouldGenerateSpecialBoundsForNullAndExistenceQueries) {
- addAllPathsIndex(BSON("a.$**" << 1), {"a", "a.b", "a.b.2", "a.b.2.3", "a.b.2.3.4"});
+TEST_F(QueryPlannerWildcardTest, ShouldGenerateSpecialBoundsForNullAndExistenceQueries) {
+ addWildcardIndex(BSON("a.$**" << 1), {"a", "a.b", "a.b.2", "a.b.2.3", "a.b.2.3.4"});
runQuery(fromjson("{'a.0.b': {$exists: true}}"));
assertNumSolutions(1U);
@@ -1453,8 +1453,8 @@ TEST_F(QueryPlannerAllPathsTest, ShouldGenerateSpecialBoundsForNullAndExistenceQ
"'a.0.b.2.3.4': [[{$minKey: 1},{$maxKey: 1},true,true]]}}}}}");
}
-TEST_F(QueryPlannerAllPathsTest, ShouldDeclineToAnswerQueriesThatTraverseTooManyArrays) {
- addAllPathsIndex(BSON("$**" << 1),
+TEST_F(QueryPlannerWildcardTest, ShouldDeclineToAnswerQueriesThatTraverseTooManyArrays) {
+ addWildcardIndex(BSON("$**" << 1),
{"a",
"a.b",
"a.b.c",
diff --git a/src/mongo/db/query/query_solution.cpp b/src/mongo/db/query/query_solution.cpp
index 142e9a061fd..567cb958e0a 100644
--- a/src/mongo/db/query/query_solution.cpp
+++ b/src/mongo/db/query/query_solution.cpp
@@ -561,7 +561,7 @@ bool IndexScanNode::hasField(const string& field) const {
for (auto&& elt : index.keyPattern) {
// For $** indexes, the keyPattern is prefixed by a virtual field, '$_path'. We therefore
// skip the first keyPattern field when deciding whether we can provide the requested field.
- if (index.type == IndexType::INDEX_ALLPATHS && !keyPatternFieldIndex) {
+ if (index.type == IndexType::INDEX_WILDCARD && !keyPatternFieldIndex) {
invariant(elt.fieldNameStringData() == "$_path"_sd);
++keyPatternFieldIndex;
continue;