diff options
Diffstat (limited to 'src/mongo/db/query/planner_ixselect_test.cpp')
-rw-r--r-- | src/mongo/db/query/planner_ixselect_test.cpp | 114 |
1 files changed, 73 insertions, 41 deletions
diff --git a/src/mongo/db/query/planner_ixselect_test.cpp b/src/mongo/db/query/planner_ixselect_test.cpp index 93c4f12c821..1df4d714e67 100644 --- a/src/mongo/db/query/planner_ixselect_test.cpp +++ b/src/mongo/db/query/planner_ixselect_test.cpp @@ -65,6 +65,20 @@ unique_ptr<MatchExpression> parseMatchExpression(const BSONObj& obj) { return std::move(status.getValue()); } +using FieldIter = RelevantFieldIndexMap::iterator; +string toString(FieldIter begin, FieldIter end) { + str::stream ss; + ss << "["; + for (FieldIter i = begin; i != end; i++) { + if (i != begin) { + ss << " "; + } + ss << i->first; + } + ss << "]"; + return ss; +} + /** * Utility function to join elements in iterator range with comma */ @@ -88,10 +102,13 @@ string toString(Iter begin, Iter end) { * to QueryPlannerIXSelect::getFields() * Results are compared with expected fields (parsed from expectedFieldsStr) */ -void testGetFields(const char* query, const char* prefix, const char* expectedFieldsStr) { +void testGetFields(const char* query, + const char* prefix, + const char* expectedFieldsStr, + bool sparseSupported = true) { BSONObj obj = fromjson(query); unique_ptr<MatchExpression> expr(parseMatchExpression(obj)); - stdx::unordered_set<string> fields; + RelevantFieldIndexMap fields; QueryPlannerIXSelect::getFields(expr.get(), prefix, &fields); // Verify results @@ -99,7 +116,7 @@ void testGetFields(const char* query, const char* prefix, const char* expectedFi vector<string> expectedFields = StringSplitter::split(expectedFieldsStr, ","); for (vector<string>::const_iterator i = expectedFields.begin(); i != expectedFields.end(); i++) { - if (fields.find(*i) == fields.end()) { + if (fields[*i].isSparse != sparseSupported) { str::stream ss; ss << "getFields(query=" << query << ", prefix=" << prefix << "): unable to find " << *i << " in result: " << toString(fields.begin(), fields.end()); @@ -159,6 +176,12 @@ TEST(QueryPlannerIXSelectTest, GetFieldsArrayNegation) { testGetFields("{a: {$all: [{$elemMatch: {b: {$ne: 1}}}]}}", "", "a.b"); } +TEST(QueryPlannerIXSelectTest, GetFieldsInternalExpr) { + testGetFields("{$expr: {$lt: ['$a', 'r']}}", "", "", false /* sparse supported */); + testGetFields("{$expr: {$eq: ['$a', null]}}", "", "", false /* sparse supported */); + testGetFields("{$expr: {$eq: ['$a', 1]}}", "", "", false /* sparse supported */); +} + /** * Performs a pre-order traversal of expression tree. Validates * that all tagged nodes contain an instance of RelevantTag. @@ -1153,25 +1176,6 @@ TEST(QueryPlannerIXSelectTest, InternalExprEqCanUseTextIndexSuffix) { "{a: {$_internalExprEq: 1}}", "", kSimpleCollator, indices, "a", expectedIndices); } -TEST(QueryPlannerIXSelectTest, InternalExprEqCanUseSparseIndexWithComparisonToNull) { - auto entry = buildSimpleIndexEntry(BSON("a" << 1)); - entry.sparse = true; - std::vector<IndexEntry> indices; - indices.push_back(entry); - std::set<size_t> expectedIndices = {0}; - testRateIndices( - "{a: {$_internalExprEq: null}}", "", kSimpleCollator, indices, "a", expectedIndices); -} - -TEST(QueryPlannerIXSelectTest, InternalExprEqCanUseSparseIndexWithComparisonToNonNull) { - auto entry = buildSimpleIndexEntry(BSON("a" << 1)); - entry.sparse = true; - std::vector<IndexEntry> indices; - indices.push_back(entry); - std::set<size_t> expectedIndices = {0}; - testRateIndices( - "{a: {$_internalExprEq: 1}}", "", kSimpleCollator, indices, "a", expectedIndices); -} TEST(QueryPlannerIXSelectTest, NotEqualsNullCanUseIndex) { auto entry = buildSimpleIndexEntry(BSON("a" << 1)); std::set<size_t> expectedIndices = {0}; @@ -1357,18 +1361,17 @@ TEST(QueryPlannerIXSelectTest, ExpandWildcardIndices) { const auto indexEntry = makeIndexEntry(BSON("$**" << 1), {}); // Case where no fields are specified. - std::vector<IndexEntry> result = - QueryPlannerIXSelect::expandIndexes(stdx::unordered_set<string>(), {indexEntry.first}); + std::vector<IndexEntry> result = QueryPlannerIXSelect::expandIndexes({}, {indexEntry.first}); ASSERT_TRUE(result.empty()); - stdx::unordered_set<string> fields = {"fieldA", "fieldB"}; + RelevantFieldIndexMap fields = {{"fieldA", {true}}, {"fieldB", {true}}}; result = QueryPlannerIXSelect::expandIndexes(fields, {indexEntry.first}); std::vector<BSONObj> expectedKeyPatterns = {BSON("fieldA" << 1), BSON("fieldB" << 1)}; ASSERT_TRUE(indexEntryKeyPatternsMatch(&expectedKeyPatterns, &result)); const auto wildcardIndexWithSubpath = makeIndexEntry(BSON("a.b.$**" << 1), {}); - fields = {"a.b", "a.b.c", "a.d"}; + fields = {{"a.b", {true}}, {"a.b.c", {true}}, {"a.d", {true}}}; result = QueryPlannerIXSelect::expandIndexes(fields, {wildcardIndexWithSubpath.first}); expectedKeyPatterns = {BSON("a.b" << 1), BSON("a.b.c" << 1)}; ASSERT_TRUE(indexEntryKeyPatternsMatch(&expectedKeyPatterns, &result)); @@ -1380,7 +1383,8 @@ TEST(QueryPlannerIXSelectTest, ExpandWildcardIndicesInPresenceOfOtherIndices) { auto bIndexEntry = makeIndexEntry(BSON("fieldB" << 1), {}); auto abIndexEntry = makeIndexEntry(BSON("fieldA" << 1 << "fieldB" << 1), {}); - const stdx::unordered_set<string> fields = {"fieldA", "fieldB", "fieldC"}; + const RelevantFieldIndexMap fields = { + {"fieldA", {true}}, {"fieldB", {true}}, {"fieldC", {true}}}; std::vector<BSONObj> expectedKeyPatterns = { BSON("fieldA" << 1), BSON("fieldA" << 1), BSON("fieldB" << 1), BSON("fieldC" << 1)}; @@ -1418,7 +1422,7 @@ TEST(QueryPlannerIXSelectTest, ExpandWildcardIndicesInPresenceOfOtherIndices) { TEST(QueryPlannerIXSelectTest, ExpandedIndexEntriesAreCorrectlyMarkedAsMultikeyOrNonMultikey) { auto wildcardIndexEntry = makeIndexEntry(BSON("$**" << 1), {}, {FieldRef{"a"}}); - const stdx::unordered_set<string> fields = {"a.b", "c.d"}; + RelevantFieldIndexMap fields = {{"a.b", {true}}, {"c.d", {true}}}; std::vector<BSONObj> expectedKeyPatterns = {BSON("a.b" << 1), BSON("c.d" << 1)}; auto result = QueryPlannerIXSelect::expandIndexes(fields, {wildcardIndexEntry.first}); @@ -1442,7 +1446,7 @@ TEST(QueryPlannerIXSelectTest, ExpandedIndexEntriesAreCorrectlyMarkedAsMultikeyO TEST(QueryPlannerIXSelectTest, WildcardIndexExpansionExcludesIdField) { const auto indexEntry = makeIndexEntry(BSON("$**" << 1), {}); - stdx::unordered_set<string> fields = {"_id", "abc", "def"}; + RelevantFieldIndexMap fields = {{"_id", {true}}, {"abc", {true}}, {"def", {true}}}; std::vector<IndexEntry> result = QueryPlannerIXSelect::expandIndexes(fields, {indexEntry.first}); @@ -1454,7 +1458,7 @@ TEST(QueryPlannerIXSelectTest, WildcardIndicesExpandedEntryHasCorrectProperties) auto wildcardIndexEntry = makeIndexEntry(BSON("$**" << 1), {}); wildcardIndexEntry.first.identifier = IndexEntry::Identifier("someIndex"); - stdx::unordered_set<string> fields = {"abc", "def"}; + RelevantFieldIndexMap fields = {{"abc", {true}}, {"def", {true}}}; std::vector<IndexEntry> result = QueryPlannerIXSelect::expandIndexes(fields, {wildcardIndexEntry.first}); @@ -1484,7 +1488,11 @@ TEST(QueryPlannerIXSelectTest, WildcardIndicesExpandedEntryHasCorrectProperties) TEST(QueryPlannerIXSelectTest, WildcardIndicesExcludeNonMatchingKeySubpath) { auto wildcardIndexEntry = makeIndexEntry(BSON("subpath.$**" << 1), {}); - stdx::unordered_set<string> fields = {"abc", "def", "subpath.abc", "subpath.def", "subpath"}; + RelevantFieldIndexMap fields = {{"abc", {true}}, + {"def", {true}}, + {"subpath.abc", {true}}, + {"subpath.def", {true}}, + {"subpath", {true}}}; std::vector<IndexEntry> result = QueryPlannerIXSelect::expandIndexes(fields, {wildcardIndexEntry.first}); @@ -1500,7 +1508,11 @@ TEST(QueryPlannerIXSelectTest, WildcardIndicesExcludeNonMatchingPathsWithInclusi {}, BSON("wildcardProjection" << BSON("abc" << 1 << "subpath.abc" << 1))); - stdx::unordered_set<string> fields = {"abc", "def", "subpath.abc", "subpath.def", "subpath"}; + RelevantFieldIndexMap fields = {{"abc", {true}}, + {"def", {true}}, + {"subpath.abc", {true}}, + {"subpath.def", {true}}, + {"subpath", {true}}}; std::vector<IndexEntry> result = QueryPlannerIXSelect::expandIndexes(fields, {wildcardIndexEntry.first}); @@ -1515,7 +1527,11 @@ TEST(QueryPlannerIXSelectTest, WildcardIndicesExcludeNonMatchingPathsWithExclusi {}, BSON("wildcardProjection" << BSON("abc" << 0 << "subpath.abc" << 0))); - stdx::unordered_set<string> fields = {"abc", "def", "subpath.abc", "subpath.def", "subpath"}; + RelevantFieldIndexMap fields = {{"abc", {true}}, + {"def", {true}}, + {"subpath.abc", {true}}, + {"subpath.def", {true}}, + {"subpath", {true}}}; std::vector<IndexEntry> result = QueryPlannerIXSelect::expandIndexes(fields, {wildcardIndexEntry.first}); @@ -1531,8 +1547,12 @@ TEST(QueryPlannerIXSelectTest, WildcardIndicesWithInclusionProjectionAllowIdExcl {}, BSON("wildcardProjection" << BSON("_id" << 0 << "abc" << 1 << "subpath.abc" << 1))); - stdx::unordered_set<string> fields = { - "_id", "abc", "def", "subpath.abc", "subpath.def", "subpath"}; + RelevantFieldIndexMap fields = {{"_id", {true}}, + {"abc", {true}}, + {"def", {true}}, + {"subpath.abc", {true}}, + {"subpath.def", {true}}, + {"subpath", {true}}}; std::vector<IndexEntry> result = QueryPlannerIXSelect::expandIndexes(fields, {wildcardIndexEntry.first}); @@ -1547,8 +1567,12 @@ TEST(QueryPlannerIXSelectTest, WildcardIndicesWithInclusionProjectionAllowIdIncl {}, BSON("wildcardProjection" << BSON("_id" << 1 << "abc" << 1 << "subpath.abc" << 1))); - stdx::unordered_set<string> fields = { - "_id", "abc", "def", "subpath.abc", "subpath.def", "subpath"}; + RelevantFieldIndexMap fields = {{"_id", {true}}, + {"abc", {true}}, + {"def", {true}}, + {"subpath.abc", {true}}, + {"subpath.def", {true}}, + {"subpath", {true}}}; std::vector<IndexEntry> result = QueryPlannerIXSelect::expandIndexes(fields, {wildcardIndexEntry.first}); @@ -1564,8 +1588,12 @@ TEST(QueryPlannerIXSelectTest, WildcardIndicesWithExclusionProjectionAllowIdIncl {}, BSON("wildcardProjection" << BSON("_id" << 1 << "abc" << 0 << "subpath.abc" << 0))); - stdx::unordered_set<string> fields = { - "_id", "abc", "def", "subpath.abc", "subpath.def", "subpath"}; + RelevantFieldIndexMap fields = {{"_id", {true}}, + {"abc", {true}}, + {"def", {true}}, + {"subpath.abc", {true}}, + {"subpath.def", {true}}, + {"subpath", {true}}}; std::vector<IndexEntry> result = QueryPlannerIXSelect::expandIndexes(fields, {wildcardIndexEntry.first}); @@ -1578,8 +1606,12 @@ TEST(QueryPlannerIXSelectTest, WildcardIndicesIncludeMatchingInternalNodes) { auto wildcardIndexEntry = makeIndexEntry( BSON("$**" << 1), {}, {}, BSON("wildcardProjection" << BSON("_id" << 1 << "subpath" << 1))); - stdx::unordered_set<string> fields = { - "_id", "abc", "def", "subpath.abc", "subpath.def", "subpath"}; + RelevantFieldIndexMap fields = {{"_id", {true}}, + {"abc", {true}}, + {"def", {true}}, + {"subpath.abc", {true}}, + {"subpath.def", {true}}, + {"subpath", {true}}}; std::vector<IndexEntry> result = QueryPlannerIXSelect::expandIndexes(fields, {wildcardIndexEntry.first}); |