diff options
Diffstat (limited to 'jstests/core/profile_query_hash.js')
-rw-r--r-- | jstests/core/profile_query_hash.js | 207 |
1 files changed, 102 insertions, 105 deletions
diff --git a/jstests/core/profile_query_hash.js b/jstests/core/profile_query_hash.js index 4c7b3e23ab7..e635c7b6b56 100644 --- a/jstests/core/profile_query_hash.js +++ b/jstests/core/profile_query_hash.js @@ -3,109 +3,106 @@ // Confirms that profile entries for find commands contain the appropriate query hash. (function() { - "use strict"; - - // For getLatestProfilerEntry - load("jstests/libs/profiler.js"); - - const testDB = db.getSiblingDB("query_hash"); - assert.commandWorked(testDB.dropDatabase()); - - const coll = testDB.test; - - // Utility function to list query shapes in cache. The length of the list of query shapes - // returned is used to validate the number of query hashes accumulated. - function getShapes(collection) { - const res = collection.runCommand('planCacheListQueryShapes'); - return res.shapes; - } - - assert.writeOK(coll.insert({a: 1, b: 1})); - assert.writeOK(coll.insert({a: 1, b: 2})); - assert.writeOK(coll.insert({a: 1, b: 2})); - assert.writeOK(coll.insert({a: 2, b: 2})); - - // We need two indices since we do not currently create cache entries for queries with a single - // candidate plan. - assert.commandWorked(coll.createIndex({a: 1})); - assert.commandWorked(coll.createIndex({a: 1, b: 1})); - - assert.commandWorked(testDB.setProfilingLevel(2)); - - // Executes query0 and gets the corresponding system.profile entry. - assert.eq( - 1, - coll.find({a: 1, b: 1}, {a: 1}).sort({a: -1}).comment("Query0 find command").itcount(), - 'unexpected document count'); - const profileObj0 = - getLatestProfilerEntry(testDB, {op: "query", "command.comment": "Query0 find command"}); - assert(profileObj0.hasOwnProperty("planCacheKey"), tojson(profileObj0)); - let shapes = getShapes(coll); - assert.eq(1, shapes.length, 'unexpected number of shapes in planCacheListQueryShapes result'); - - // Executes query1 and gets the corresponding system.profile entry. - assert.eq( - 0, - coll.find({a: 2, b: 1}, {a: 1}).sort({a: -1}).comment("Query1 find command").itcount(), - 'unexpected document count'); - const profileObj1 = - getLatestProfilerEntry(testDB, {op: "query", "command.comment": "Query1 find command"}); - assert(profileObj1.hasOwnProperty("planCacheKey"), tojson(profileObj1)); - - // Since the query shapes are the same, we only expect there to be one query shape present in - // the plan cache commands output. - shapes = getShapes(coll); - assert.eq(1, shapes.length, 'unexpected number of shapes in planCacheListQueryShapes result'); - assert.eq( - profileObj0.planCacheKey, profileObj1.planCacheKey, 'unexpected not matching query hashes'); - - // Test that the planCacheKey is the same in explain output for query0 and query1 as it was - // in system.profile output. - const explainQuery0 = assert.commandWorked(coll.find({a: 1, b: 1}, {a: 1}) - .sort({a: -1}) - .comment("Query0 find command") - .explain("queryPlanner")); - assert.eq(explainQuery0.queryPlanner.planCacheKey, profileObj0.planCacheKey, explainQuery0); - const explainQuery1 = assert.commandWorked(coll.find({a: 2, b: 1}, {a: 1}) - .sort({a: -1}) - .comment("Query1 find command") - .explain("queryPlanner")); - assert.eq(explainQuery1.queryPlanner.planCacheKey, profileObj0.planCacheKey, explainQuery1); - - // Check that the 'planCacheKey' is the same for both query 0 and query 1. - assert.eq(explainQuery0.queryPlanner.planCacheKey, explainQuery1.queryPlanner.planCacheKey); - - // Executes query2 and gets the corresponding system.profile entry. - assert.eq(0, - coll.find({a: 12000, b: 1}).comment("Query2 find command").itcount(), - 'unexpected document count'); - const profileObj2 = - getLatestProfilerEntry(testDB, {op: "query", "command.comment": "Query2 find command"}); - assert(profileObj2.hasOwnProperty("planCacheKey"), tojson(profileObj2)); - - // Query0 and query1 should both have the same query hash for the given indexes. Whereas, query2 - // should have a unique hash. Asserts that a total of two distinct hashes results in two query - // shapes. - shapes = getShapes(coll); - assert.eq(2, shapes.length, 'unexpected number of shapes in planCacheListQueryShapes result'); - assert.neq( - profileObj0.planCacheKey, profileObj2.planCacheKey, 'unexpected matching query hashes'); - - // The planCacheKey in explain should be different for query2 than the hash from query0 and - // query1. - const explainQuery2 = assert.commandWorked( - coll.find({a: 12000, b: 1}).comment("Query2 find command").explain("queryPlanner")); - assert(explainQuery2.queryPlanner.hasOwnProperty("planCacheKey")); - assert.neq(explainQuery2.queryPlanner.planCacheKey, profileObj0.planCacheKey, explainQuery2); - assert.eq(explainQuery2.queryPlanner.planCacheKey, profileObj2.planCacheKey, explainQuery2); - - // Now drop an index. This should change the 'planCacheKey' value for queries, but not the - // 'queryHash'. - assert.commandWorked(coll.dropIndex({a: 1})); - const explainQuery2PostCatalogChange = assert.commandWorked( - coll.find({a: 12000, b: 1}).comment("Query2 find command").explain("queryPlanner")); - assert.eq(explainQuery2.queryPlanner.queryHash, - explainQuery2PostCatalogChange.queryPlanner.queryHash); - assert.neq(explainQuery2.queryPlanner.planCacheKey, - explainQuery2PostCatalogChange.queryPlanner.planCacheKey); +"use strict"; + +// For getLatestProfilerEntry +load("jstests/libs/profiler.js"); + +const testDB = db.getSiblingDB("query_hash"); +assert.commandWorked(testDB.dropDatabase()); + +const coll = testDB.test; + +// Utility function to list query shapes in cache. The length of the list of query shapes +// returned is used to validate the number of query hashes accumulated. +function getShapes(collection) { + const res = collection.runCommand('planCacheListQueryShapes'); + return res.shapes; +} + +assert.writeOK(coll.insert({a: 1, b: 1})); +assert.writeOK(coll.insert({a: 1, b: 2})); +assert.writeOK(coll.insert({a: 1, b: 2})); +assert.writeOK(coll.insert({a: 2, b: 2})); + +// We need two indices since we do not currently create cache entries for queries with a single +// candidate plan. +assert.commandWorked(coll.createIndex({a: 1})); +assert.commandWorked(coll.createIndex({a: 1, b: 1})); + +assert.commandWorked(testDB.setProfilingLevel(2)); + +// Executes query0 and gets the corresponding system.profile entry. +assert.eq(1, + coll.find({a: 1, b: 1}, {a: 1}).sort({a: -1}).comment("Query0 find command").itcount(), + 'unexpected document count'); +const profileObj0 = + getLatestProfilerEntry(testDB, {op: "query", "command.comment": "Query0 find command"}); +assert(profileObj0.hasOwnProperty("planCacheKey"), tojson(profileObj0)); +let shapes = getShapes(coll); +assert.eq(1, shapes.length, 'unexpected number of shapes in planCacheListQueryShapes result'); + +// Executes query1 and gets the corresponding system.profile entry. +assert.eq(0, + coll.find({a: 2, b: 1}, {a: 1}).sort({a: -1}).comment("Query1 find command").itcount(), + 'unexpected document count'); +const profileObj1 = + getLatestProfilerEntry(testDB, {op: "query", "command.comment": "Query1 find command"}); +assert(profileObj1.hasOwnProperty("planCacheKey"), tojson(profileObj1)); + +// Since the query shapes are the same, we only expect there to be one query shape present in +// the plan cache commands output. +shapes = getShapes(coll); +assert.eq(1, shapes.length, 'unexpected number of shapes in planCacheListQueryShapes result'); +assert.eq( + profileObj0.planCacheKey, profileObj1.planCacheKey, 'unexpected not matching query hashes'); + +// Test that the planCacheKey is the same in explain output for query0 and query1 as it was +// in system.profile output. +const explainQuery0 = assert.commandWorked(coll.find({a: 1, b: 1}, {a: 1}) + .sort({a: -1}) + .comment("Query0 find command") + .explain("queryPlanner")); +assert.eq(explainQuery0.queryPlanner.planCacheKey, profileObj0.planCacheKey, explainQuery0); +const explainQuery1 = assert.commandWorked(coll.find({a: 2, b: 1}, {a: 1}) + .sort({a: -1}) + .comment("Query1 find command") + .explain("queryPlanner")); +assert.eq(explainQuery1.queryPlanner.planCacheKey, profileObj0.planCacheKey, explainQuery1); + +// Check that the 'planCacheKey' is the same for both query 0 and query 1. +assert.eq(explainQuery0.queryPlanner.planCacheKey, explainQuery1.queryPlanner.planCacheKey); + +// Executes query2 and gets the corresponding system.profile entry. +assert.eq(0, + coll.find({a: 12000, b: 1}).comment("Query2 find command").itcount(), + 'unexpected document count'); +const profileObj2 = + getLatestProfilerEntry(testDB, {op: "query", "command.comment": "Query2 find command"}); +assert(profileObj2.hasOwnProperty("planCacheKey"), tojson(profileObj2)); + +// Query0 and query1 should both have the same query hash for the given indexes. Whereas, query2 +// should have a unique hash. Asserts that a total of two distinct hashes results in two query +// shapes. +shapes = getShapes(coll); +assert.eq(2, shapes.length, 'unexpected number of shapes in planCacheListQueryShapes result'); +assert.neq(profileObj0.planCacheKey, profileObj2.planCacheKey, 'unexpected matching query hashes'); + +// The planCacheKey in explain should be different for query2 than the hash from query0 and +// query1. +const explainQuery2 = assert.commandWorked( + coll.find({a: 12000, b: 1}).comment("Query2 find command").explain("queryPlanner")); +assert(explainQuery2.queryPlanner.hasOwnProperty("planCacheKey")); +assert.neq(explainQuery2.queryPlanner.planCacheKey, profileObj0.planCacheKey, explainQuery2); +assert.eq(explainQuery2.queryPlanner.planCacheKey, profileObj2.planCacheKey, explainQuery2); + +// Now drop an index. This should change the 'planCacheKey' value for queries, but not the +// 'queryHash'. +assert.commandWorked(coll.dropIndex({a: 1})); +const explainQuery2PostCatalogChange = assert.commandWorked( + coll.find({a: 12000, b: 1}).comment("Query2 find command").explain("queryPlanner")); +assert.eq(explainQuery2.queryPlanner.queryHash, + explainQuery2PostCatalogChange.queryPlanner.queryHash); +assert.neq(explainQuery2.queryPlanner.planCacheKey, + explainQuery2PostCatalogChange.queryPlanner.planCacheKey); })(); |