diff options
author | yarai <yuta.arai@10gen.com> | 2018-09-18 17:13:31 -0400 |
---|---|---|
committer | yarai <yuta.arai@10gen.com> | 2018-09-25 09:49:16 -0400 |
commit | f24bfb54aa2eceea56557d4bddfb08e703ab74fa (patch) | |
tree | f683bc4e14ff56e7d08a2a041cf4703206adbd93 /jstests/noPassthroughWithMongod | |
parent | fbeeccc651d7f88dea0ea36623470d3d46e615db (diff) | |
download | mongo-f24bfb54aa2eceea56557d4bddfb08e703ab74fa.tar.gz |
SERVER-35332 Index filter support for "allPaths" indexes
Diffstat (limited to 'jstests/noPassthroughWithMongod')
-rw-r--r-- | jstests/noPassthroughWithMongod/wildcard_index_filter.js | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/jstests/noPassthroughWithMongod/wildcard_index_filter.js b/jstests/noPassthroughWithMongod/wildcard_index_filter.js new file mode 100644 index 00000000000..3cd0d535e91 --- /dev/null +++ b/jstests/noPassthroughWithMongod/wildcard_index_filter.js @@ -0,0 +1,101 @@ +/** + * Test that $** indexes obey index filter rules. + */ +(function() { + "use strict"; + + load("jstests/libs/analyze_plan.js"); + + const coll = db.wildcard_index_filter; + + // Utility function to list index filters. + function getFilters() { + const res = assert.commandWorked(coll.runCommand('planCacheListFilters')); + assert(res.hasOwnProperty('filters'), 'filters missing from planCacheListFilters result'); + return res.filters; + } + + // Sets an index filter given a query shape then confirms that the expected index was used to + // answer a query. + function assertExpectedIndexAnswersQueryWithFilter( + filterQuery, filterIndexes, query, expectedIndexName, hint) { + // Clear existing cache filters. + assert.commandWorked(coll.runCommand('planCacheClearFilters'), + 'planCacheClearFilters failed'); + + // Make sure that the filter is set correctly. + assert.commandWorked( + coll.runCommand('planCacheSetFilter', {query: filterQuery, indexes: filterIndexes})); + assert.eq(1, + getFilters().length, + 'no change in query settings after successfully setting index filters'); + + // Check that expectedIndex index was used over another index. + let explain; + if (hint == undefined) { + explain = assert.commandWorked(coll.explain("executionStats").find(query).finish()); + } else { + explain = assert.commandWorked( + coll.explain("executionStats").find(query).hint(hint).finish()); + } + + let planStage = getPlanStage(explain.executionStats.executionStages, 'IXSCAN'); + assert.neq(null, planStage); + assert.eq(planStage.indexName, expectedIndexName, tojson(planStage)); + } + + // Required in order to build $** indexes. + assert.commandWorked( + db.adminCommand({setParameter: 1, internalQueryAllowAllPathsIndexes: true})); + + try { + const indexWildcard = {"$**": 1}; + const indexA = {"a": 1}; + assert.commandWorked(coll.createIndex(indexWildcard)); + assert.commandWorked(coll.createIndex(indexA)); + + assert.commandWorked(coll.insert({a: "a"})); + + // Filtering on $** index. $** index is used over another index. + assertExpectedIndexAnswersQueryWithFilter({a: "a"}, [indexWildcard], {a: "a"}, "$**_1"); + + // Filtering on regular index. $** index is not used over another index. + assertExpectedIndexAnswersQueryWithFilter({a: "a"}, [indexA], {a: "a"}, "a_1"); + + assert.commandWorked(coll.insert({a: "a", b: "b"})); + + const indexAB = {"a": 1, "b": 1}; + assert.commandWorked(coll.createIndex(indexAB)); + + // Filtering on $** index. $** index is used over another index for compound query. + assertExpectedIndexAnswersQueryWithFilter( + {a: "a", b: "b"}, [indexWildcard], {a: "a", b: "b"}, "$**_1"); + + // Filtering on regular compound index. Check that $** index is not used over another index + // for compound query. + assertExpectedIndexAnswersQueryWithFilter( + {a: "a", b: "b"}, [indexAB], {a: "a", b: "b"}, "a_1_b_1"); + + // Filtering on $** index while hinting on another index. Index filter is prioritized. + assertExpectedIndexAnswersQueryWithFilter( + {a: "a"}, [indexWildcard], {a: "a"}, "$**_1", indexA); + + // Filtering on regular index while hinting on $** index. Index filter is prioritized. + assertExpectedIndexAnswersQueryWithFilter( + {a: "a"}, [indexA], {a: "a"}, "a_1", indexWildcard); + + // Index filter for $** index does not apply when query does not match filter query shape. + assertExpectedIndexAnswersQueryWithFilter( + {b: "b"}, [indexWildcard], {a: "a"}, "a_1", indexA); + + const indexAWildcard = {"a.$**": 1}; + assert.commandWorked(coll.createIndex(indexAWildcard)); + + // Filtering on a path specified $** index. Check that the $** is used over other indices. + assertExpectedIndexAnswersQueryWithFilter({a: "a"}, [indexAWildcard], {a: "a"}, "a.$**_1"); + } finally { + // Disable $** indexes once the tests have either completed or failed. + assert.commandWorked( + db.adminCommand({setParameter: 1, internalQueryAllowAllPathsIndexes: false})); + } +})();
\ No newline at end of file |