
OPERATIONAL DEFECT DATABASE
...

...
When internalQueryEnumerationMaxOrSolutions is set to 0 the database will still generate and consider a plan which contains a "OR" stage. This is the same behavior as when the parameter is set to a value of {{1 }}so it seems incorrect. Further increases to the parameter after that generate additional plans as expected.
xgen-internal-githook commented on Wed, 14 Oct 2020 17:59:36 +0000: Author: {'name': 'Ted Tuckman', 'email': 'ted.tuckman@mongodb.com', 'username': 'TedTuckman'} Message: SERVER-47826 Respect when internalQueryEnumerationMaxOrSolutions is set to zero Branch: master https://github.com/mongodb/mongo/commit/2667abf5f988c9cf9b548e23db961680a24c7a1b
db.foo.drop() db.foo.createIndex({common:1}) db.foo.createIndex({one:1}) db.foo.createIndex({two:1}) // Confirming that with the default setting of 10, a total of 5 plans (4 rejectedPlans) are generated: db.adminCommand({setParameter:1, internalQueryEnumerationMaxOrSolutions:10}) db.foo.find({common:1, $or:[{one:0, two:0},{one:1, two:1}]}).explain().queryPlanner.rejectedPlans.length // Setting this to 0 should result in only a single plan, using the { common: 1 } index, being generated. However there is a rejected "OR" plan: db.adminCommand({setParameter:1, internalQueryEnumerationMaxOrSolutions:0}) db.foo.find({common:1, $or:[{one:0, two:0},{one:1, two:1}]}).explain().queryPlanner.rejectedPlans.length db.foo.find({common:1, $or:[{one:0, two:0},{one:1, two:1}]}).explain().queryPlanner.rejectedPlans[0] // With a value of 1, we get the same result as when it is 0. This is output seems correct for this setting: db.adminCommand({setParameter:1, internalQueryEnumerationMaxOrSolutions:1}) db.foo.find({common:1, $or:[{one:0, two:0},{one:1, two:1}]}).explain().queryPlanner.rejectedPlans.length db.foo.find({common:1, $or:[{one:0, two:0},{one:1, two:1}]}).explain().queryPlanner.rejectedPlans[0] // Further increases to the parameter have the expected increase to the number of plans: db.adminCommand({setParameter:1, internalQueryEnumerationMaxOrSolutions:2}) db.foo.find({common:1, $or:[{one:0, two:0},{one:1, two:1}]}).explain().queryPlanner.rejectedPlans.length db.adminCommand({setParameter:1, internalQueryEnumerationMaxOrSolutions:3}) db.foo.find({common:1, $or:[{one:0, two:0},{one:1, two:1}]}).explain().queryPlanner.rejectedPlans.length db.adminCommand({setParameter:1, internalQueryEnumerationMaxOrSolutions:4}) db.foo.find({common:1, $or:[{one:0, two:0},{one:1, two:1}]}).explain().queryPlanner.rejectedPlans.length Full output from a mongo shell session against a 4.2.2 mongod: > db.foo.drop() true > > db.foo.createIndex({common:1}) { "createdCollectionAutomatically" : true, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 } > db.foo.createIndex({one:1}) { "createdCollectionAutomatically" : false, "numIndexesBefore" : 2, "numIndexesAfter" : 3, "ok" : 1 } > db.foo.createIndex({two:1}) { "createdCollectionAutomatically" : false, "numIndexesBefore" : 3, "numIndexesAfter" : 4, "ok" : 1 } > > > // Confirming that with the default setting of 10, a total of 5 plans (4 rejectedPlans) are generated: > db.adminCommand({setParameter:1, internalQueryEnumerationMaxOrSolutions:10}) { "was" : 10, "ok" : 1 } > db.foo.find({common:1, $or:[{one:0, two:0},{one:1, two:1}]}).explain().queryPlanner.rejectedPlans.length 4 > > > // Setting this to 0 should result in only a single plan, using the { common: 1 } index, being generated. However there is a rejected "OR" plan: > db.adminCommand({setParameter:1, internalQueryEnumerationMaxOrSolutions:0}) { "was" : 10, "ok" : 1 } > db.foo.find({common:1, $or:[{one:0, two:0},{one:1, two:1}]}).explain().queryPlanner.rejectedPlans.length 1 > db.foo.find({common:1, $or:[{one:0, two:0},{one:1, two:1}]}).explain().queryPlanner.rejectedPlans[0] { "stage" : "FETCH", "filter" : { "common" : { "$eq" : 1 } }, "inputStage" : { "stage" : "OR", "inputStages" : [ { "stage" : "FETCH", "filter" : { "two" : { "$eq" : 0 } }, "inputStage" : { "stage" : "IXSCAN", "keyPattern" : { "one" : 1 }, "indexName" : "one_1", "isMultiKey" : false, "multiKeyPaths" : { "one" : [ ] }, "isUnique" : false, "isSparse" : false, "isPartial" : false, "indexVersion" : 2, "direction" : "forward", "indexBounds" : { "one" : [ "[0.0, 0.0]" ] } } }, { "stage" : "FETCH", "filter" : { "one" : { "$eq" : 1 } }, "inputStage" : { "stage" : "IXSCAN", "keyPattern" : { "two" : 1 }, "indexName" : "two_1", "isMultiKey" : false, "multiKeyPaths" : { "two" : [ ] }, "isUnique" : false, "isSparse" : false, "isPartial" : false, "indexVersion" : 2, "direction" : "forward", "indexBounds" : { "two" : [ "[1.0, 1.0]" ] } } } ] } } > > // With a value of 1, we get the same result as when it is 0. But the output now seems correct based on the updated parameter value: > db.adminCommand({setParameter:1, internalQueryEnumerationMaxOrSolutions:1}) { "was" : 0, "ok" : 1 } > db.foo.find({common:1, $or:[{one:0, two:0},{one:1, two:1}]}).explain().queryPlanner.rejectedPlans.length 1 > db.foo.find({common:1, $or:[{one:0, two:0},{one:1, two:1}]}).explain().queryPlanner.rejectedPlans[0] { "stage" : "FETCH", "filter" : { "common" : { "$eq" : 1 } }, "inputStage" : { "stage" : "OR", "inputStages" : [ { "stage" : "FETCH", "filter" : { "two" : { "$eq" : 1 } }, "inputStage" : { "stage" : "IXSCAN", "keyPattern" : { "one" : 1 }, "indexName" : "one_1", "isMultiKey" : false, "multiKeyPaths" : { "one" : [ ] }, "isUnique" : false, "isSparse" : false, "isPartial" : false, "indexVersion" : 2, "direction" : "forward", "indexBounds" : { "one" : [ "[1.0, 1.0]" ] } } }, { "stage" : "FETCH", "filter" : { "one" : { "$eq" : 0 } }, "inputStage" : { "stage" : "IXSCAN", "keyPattern" : { "two" : 1 }, "indexName" : "two_1", "isMultiKey" : false, "multiKeyPaths" : { "two" : [ ] }, "isUnique" : false, "isSparse" : false, "isPartial" : false, "indexVersion" : 2, "direction" : "forward", "indexBounds" : { "two" : [ "[0.0, 0.0]" ] } } } ] } } > > > // Further increases to the parameter have the expected corresponding increase to the number of plans: > db.adminCommand({setParameter:1, internalQueryEnumerationMaxOrSolutions:2}) { "was" : 1, "ok" : 1 } > db.foo.find({common:1, $or:[{one:0, two:0},{one:1, two:1}]}).explain().queryPlanner.rejectedPlans.length 2 > db.adminCommand({setParameter:1, internalQueryEnumerationMaxOrSolutions:3}) { "was" : 2, "ok" : 1 } > db.foo.find({common:1, $or:[{one:0, two:0},{one:1, two:1}]}).explain().queryPlanner.rejectedPlans.length 3 > db.adminCommand({setParameter:1, internalQueryEnumerationMaxOrSolutions:4}) { "was" : 3, "ok" : 1 } > db.foo.find({common:1, $or:[{one:0, two:0},{one:1, two:1}]}).explain().queryPlanner.rejectedPlans.length 4
Click on a version to see all relevant bugs
MongoDB Integration
Learn more about where this data comes from
Bug Scrub Advisor
Streamline upgrades with automated vendor bug scrubs
BugZero Enterprise
Wish you caught this bug sooner? Get proactive today.