diff options
author | Alexander Ignatyev <alexander.ignatyev@mongodb.com> | 2023-02-03 17:08:27 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2023-02-03 18:45:08 +0000 |
commit | c8126be2786a012b8c70ae701b175fd367feabff (patch) | |
tree | 0dc969ec5baf6485493e19700436091ea6b2f3b4 | |
parent | 40f676658dceddecc10f4303f1b752d184623740 (diff) | |
download | mongo-c8126be2786a012b8c70ae701b175fd367feabff.tar.gz |
SERVER-72465: Support CWI in validateNumericPathComponents function
-rw-r--r-- | src/mongo/db/query/planner_wildcard_helpers.cpp | 12 | ||||
-rw-r--r-- | src/mongo/db/query/planner_wildcard_helpers_test.cpp | 26 |
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 |