summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Ignatyev <alexander.ignatyev@mongodb.com>2023-02-03 17:08:27 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2023-02-03 18:45:08 +0000
commitc8126be2786a012b8c70ae701b175fd367feabff (patch)
tree0dc969ec5baf6485493e19700436091ea6b2f3b4
parent40f676658dceddecc10f4303f1b752d184623740 (diff)
downloadmongo-c8126be2786a012b8c70ae701b175fd367feabff.tar.gz
SERVER-72465: Support CWI in validateNumericPathComponents function
-rw-r--r--src/mongo/db/query/planner_wildcard_helpers.cpp12
-rw-r--r--src/mongo/db/query/planner_wildcard_helpers_test.cpp26
2 files changed, 35 insertions, 3 deletions
diff --git a/src/mongo/db/query/planner_wildcard_helpers.cpp b/src/mongo/db/query/planner_wildcard_helpers.cpp
index b3eba5b13a5..998087894f4 100644
--- a/src/mongo/db/query/planner_wildcard_helpers.cpp
+++ b/src/mongo/db/query/planner_wildcard_helpers.cpp
@@ -251,10 +251,20 @@ std::set<FieldRef> generateFieldNameOrArrayIndexPathSet(const MultikeyComponents
bool validateNumericPathComponents(const MultikeyPaths& multikeyPaths,
const std::set<FieldRef>& includedPaths,
const FieldRef& queryPath) {
+ // Find the position of the Wildcard's MultikeyComponents in the paths, we assume that the
+ // wildcard field is the only one that can be multikey.
+ auto wildcardComponent = std::find_if(multikeyPaths.begin(),
+ multikeyPaths.end(),
+ [](const MultikeyComponents& c) { return !c.empty(); });
+ if (wildcardComponent == multikeyPaths.end()) {
+ // If no MultikeyComponents just return.
+ return true;
+ }
+
// Find the positions of all multikey path components in 'queryPath' that have a numerical path
// component immediately after. For a queryPath of 'a.2.b' this will return position 0; that is,
// 'a'. If no such multikey path was found, we are clear to proceed with planning.
- const auto arrayIndices = findArrayIndexPathComponents(multikeyPaths.front(), queryPath);
+ const auto arrayIndices = findArrayIndexPathComponents(*wildcardComponent, queryPath);
if (arrayIndices.empty()) {
return true;
}
diff --git a/src/mongo/db/query/planner_wildcard_helpers_test.cpp b/src/mongo/db/query/planner_wildcard_helpers_test.cpp
index 93ec840e4be..24d4a965661 100644
--- a/src/mongo/db/query/planner_wildcard_helpers_test.cpp
+++ b/src/mongo/db/query/planner_wildcard_helpers_test.cpp
@@ -113,14 +113,14 @@ TEST(PlannerWildcardHelpersTest, Expand_CompoundWildcardIndex_WithProjection) {
IndexEntryMock wildcardIndex{
BSON("e.f" << 1 << "$**" << 1 << "m.n" << 1), BSON("a" << 1), {FieldRef{"a"_sd}}};
- stdx::unordered_set<std::string> fields{"a", "b"};
+ stdx::unordered_set<std::string> fields{"a.c", "b"};
std::vector<IndexEntry> expandedIndexes{};
expandWildcardIndexEntry(*wildcardIndex.indexEntry, fields, &expandedIndexes);
MultikeyPaths expectedMks{{}, {0}, {}};
ASSERT_EQ(1, expandedIndexes.size());
ASSERT_BSONOBJ_EQ(expandedIndexes.front().keyPattern,
- BSON("e.f" << 1 << "a" << 1 << "m.n" << 1));
+ BSON("e.f" << 1 << "a.c" << 1 << "m.n" << 1));
ASSERT_TRUE(expandedIndexes.front().multikey);
ASSERT_EQ(1, expandedIndexes.front().wildcardFieldPos);
ASSERT_EQ(expectedMks, expandedIndexes.front().multikeyPaths);
@@ -159,4 +159,26 @@ TEST(PlannerWildcardHelpersTest, Expand_CompoundWildcardIndex_WithoutProjection)
}
}
+TEST(PlannerWildcardHelpersTest, Expand_CompoundWildcardIndex_NumericComponents) {
+ RAIIServerParameterControllerForTest controller("featureFlagCompoundWildcardIndexes", true);
+
+ IndexEntryMock wildcardIndex{BSON("e.f" << 1 << "$**" << 1 << "m.n" << 1),
+ BSON("a.0" << 1 << "b" << 1),
+ {FieldRef{"a"_sd}}};
+
+ stdx::unordered_set<std::string> fields{"a.0.b", "b"};
+ std::vector<IndexEntry> expandedIndexes{};
+ expandWildcardIndexEntry(*wildcardIndex.indexEntry, fields, &expandedIndexes);
+
+ // Expanded IndexEntry {e.f: 1, a.0.b: 1, m.n: 1} is exclauded since this is the case when the
+ // query path lies along a $** projection through an array index. See comment to
+ // 'validateNumericPathComponents' in planner_wildcard_helper.cpp function for details.
+ MultikeyPaths expectedMks{{}, {}, {}};
+ ASSERT_EQ(1, expandedIndexes.size());
+ ASSERT_BSONOBJ_EQ(expandedIndexes.front().keyPattern,
+ BSON("e.f" << 1 << "b" << 1 << "m.n" << 1));
+ ASSERT_FALSE(expandedIndexes.front().multikey);
+ ASSERT_EQ(expectedMks, expandedIndexes.front().multikeyPaths);
+}
+
} // namespace mongo::wildcard_planning