diff options
author | Ian Boros <ian.boros@10gen.com> | 2018-09-13 18:08:53 -0400 |
---|---|---|
committer | Ian Boros <ian.boros@10gen.com> | 2018-09-17 18:46:38 -0400 |
commit | 590fdc69d78ecbca005381781a9e520bd023a43d (patch) | |
tree | ca9f0fc4d29a9ae665c974d90bcb697680a37749 | |
parent | 0780841a51470b33105ec2b0a7831531b82d0a8d (diff) | |
download | mongo-590fdc69d78ecbca005381781a9e520bd023a43d.tar.gz |
SERVER-36945 Tests for allPaths indexes not supporting negations
-rw-r--r-- | src/mongo/db/query/query_planner_all_paths_index_test.cpp | 35 | ||||
-rw-r--r-- | src/mongo/db/query/query_planner_test.cpp | 28 |
2 files changed, 63 insertions, 0 deletions
diff --git a/src/mongo/db/query/query_planner_all_paths_index_test.cpp b/src/mongo/db/query/query_planner_all_paths_index_test.cpp index 7ea870083f8..bed49a69514 100644 --- a/src/mongo/db/query/query_planner_all_paths_index_test.cpp +++ b/src/mongo/db/query/query_planner_all_paths_index_test.cpp @@ -767,6 +767,41 @@ 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}} + // will match documents which don't have an "a" field. + addAllPathsIndex(BSON("$**" << 1)); + runQuery(fromjson("{a: {$ne: 5}}")); + assertHasOnlyCollscan(); + + runQuery(fromjson("{a: {$not: {$gt: 3, $lt: 5}}}")); + assertHasOnlyCollscan(); +} + +TEST_F(QueryPlannerAllPathsTest, + AllPathsDoesNotSupportNegationPredicateInsideElemMatchMultiKeyPath) { + // Logically, there's no reason a (sparse) allPaths index could not support a negation inside a + // "$elemMatch value", but it is not something we've implemented. + addAllPathsIndex(BSON("$**" << 1), {"a"}); + runQuery(fromjson("{a: {$elemMatch: {$ne: 5}}}")); + assertHasOnlyCollscan(); + + runQuery(fromjson("{a: {$elemMatch: {$not: {$gt: 3, $lt: 5}}}}")); + assertHasOnlyCollscan(); +} + +TEST_F(QueryPlannerAllPathsTest, AllPathsDoesNotSupportNegationPredicateInsideElemMatch) { + // 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)); + runQuery(fromjson("{a: {$elemMatch: {$ne: 5}}}")); + assertHasOnlyCollscan(); + + runQuery(fromjson("{a: {$elemMatch: {$not: {$gt: 3, $lt: 5}}}}")); + assertHasOnlyCollscan(); +} + // TODO SERVER-35335: Add testing for Min/Max. // TODO SERVER-36517: Add testing for DISTINCT_SCAN. // TODO SERVER-35331: Add testing for hints. diff --git a/src/mongo/db/query/query_planner_test.cpp b/src/mongo/db/query/query_planner_test.cpp index 8acccd4da85..2fc05b9f918 100644 --- a/src/mongo/db/query/query_planner_test.cpp +++ b/src/mongo/db/query/query_planner_test.cpp @@ -2528,6 +2528,34 @@ TEST_F(QueryPlannerTest, ExprEqCanUseSparseIndexForEqualityToNull) { "{a: 1}, bounds: {a: [[undefined,undefined,true,true], [null,null,true,true]]}}}}}"); } +TEST_F(QueryPlannerTest, NegationCannotUseSparseIndex) { + // Sparse indexes can't support negation queries because they are sparse, and {a: {$ne: 5}} + // will match documents which don't have an "a" field. + addIndex(fromjson("{a: 1}"), + false, // multikey + true // sparse + ); + runQuery(fromjson("{a: {$ne: 5}}")); + assertHasOnlyCollscan(); + + runQuery(fromjson("{a: {$not: {$gt: 3, $lt: 5}}}")); + assertHasOnlyCollscan(); +} + +TEST_F(QueryPlannerTest, NegationInElemMatchDoesNotUseSparseIndex) { + // Logically, there's no reason a sparse index could not support a negation inside a + // "$elemMatch value", but it is not something we've implemented. + addIndex(fromjson("{a: 1}"), + true, // multikey + true // sparse + ); + runQuery(fromjson("{a: {$elemMatch: {$ne: 5}}}")); + assertHasOnlyCollscan(); + + runQuery(fromjson("{a: {$elemMatch: {$not: {$gt: 3, $lt: 5}}}}")); + assertHasOnlyCollscan(); +} + // // Regex // |