summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Neupauer <martin.neupauer@mongodb.com>2019-03-01 12:28:39 -0500
committerCharlie Swanson <charlie.swanson@mongodb.com>2019-03-26 13:10:34 -0400
commitef74db9b48a13e1f902ce0eea3c0b5a24ba45ecc (patch)
treeb2231acb557069f00792f1902a2dab46f2f3104a
parentcf44a88076f15fb94587a7c74e186f09974aa73d (diff)
downloadmongo-ef74db9b48a13e1f902ce0eea3c0b5a24ba45ecc.tar.gz
SERVER-39903 notablescan parameter should be ignored for internally used
namespaces (cherry picked from commit 18593fe22c55b7a51c44f04a39d30573b0b01873)
-rw-r--r--jstests/noPassthrough/ignore_notablescan.js36
-rw-r--r--src/mongo/db/query/get_executor.cpp6
2 files changed, 39 insertions, 3 deletions
diff --git a/jstests/noPassthrough/ignore_notablescan.js b/jstests/noPassthrough/ignore_notablescan.js
new file mode 100644
index 00000000000..9b7b0f8d379
--- /dev/null
+++ b/jstests/noPassthrough/ignore_notablescan.js
@@ -0,0 +1,36 @@
+// Test that 'notablescan' parameter does not affect queries internal namespaces.
+// @tags: [uses_transactions]
+(function() {
+ "use strict";
+
+ const dbName = "test";
+ const collName = "coll";
+
+ const rst = new ReplSetTest({nodes: 1, nodeOptions: {setParameter: {notablescan: true}}});
+ rst.startSet();
+ rst.initiate();
+
+ const configDB = rst.getPrimary().getDB("config");
+ const session = rst.getPrimary().getDB(dbName).getMongo().startSession();
+ const primaryDB = session.getDatabase(dbName);
+
+ // Implicitly create the collection outside of the transaction.
+ assert.writeOK(primaryDB.getCollection(collName).insert({x: 1}));
+
+ // Run a transaction so the 'config.transactions' collection is implicitly created.
+ session.startTransaction();
+ assert.writeOK(primaryDB.getCollection(collName).insert({x: 2}));
+ session.commitTransaction();
+
+ // Run a predicate query that would fail if we did not ignore the 'notablescan' flag.
+ assert.eq(configDB.transactions.find({any_nonexistent_field: {$exists: true}}).itcount(), 0);
+
+ // Run the same query against the user created collection honoring the 'notablescan' flag.
+ // This will cause the query to fail as there is no viable query plan. Unfortunately,
+ // the reported query error code is the cryptic 'BadValue'.
+ assert.commandFailedWithCode(
+ primaryDB.runCommand({find: collName, filter: {any_nonexistent_field: {$exists: true}}}),
+ ErrorCodes.BadValue);
+
+ rst.stopSet();
+}());
diff --git a/src/mongo/db/query/get_executor.cpp b/src/mongo/db/query/get_executor.cpp
index fc44f7fd459..4f7f4477081 100644
--- a/src/mongo/db/query/get_executor.cpp
+++ b/src/mongo/db/query/get_executor.cpp
@@ -167,10 +167,10 @@ void fillOutPlannerParams(OperationContext* opCtx,
// overrides this behavior by not outputting a collscan even if there are no indexed
// solutions.
if (storageGlobalParams.noTableScan.load()) {
- const string& ns = canonicalQuery->ns();
+ const auto& nss = canonicalQuery->nss();
// There are certain cases where we ignore this restriction:
- bool ignore = canonicalQuery->getQueryObj().isEmpty() ||
- (string::npos != ns.find(".system.")) || (0 == ns.find("local."));
+ bool ignore =
+ canonicalQuery->getQueryObj().isEmpty() || nss.isSystem() || nss.isOnInternalDb();
if (!ignore) {
plannerParams->options |= QueryPlannerParams::NO_TABLE_SCAN;
}