summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
authorJames Wahlin <james.wahlin@10gen.com>2016-08-25 08:36:22 -0400
committerJames Wahlin <james.wahlin@10gen.com>2016-08-26 16:45:30 -0400
commita4a9a9ad29415239091db171e01f45677464f668 (patch)
tree461bbdd6275712543b617ce6e8b8bbc313ffb9e0 /src/mongo/db
parent752dcf912d5e45c8614ed749e20982e69cc89813 (diff)
downloadmongo-a4a9a9ad29415239091db171e01f45677464f668.tar.gz
SERVER-24771 Support killCursors & mongos getMore on view namespace
Diffstat (limited to 'src/mongo/db')
-rw-r--r--src/mongo/db/commands/killcursors_cmd.cpp22
-rw-r--r--src/mongo/db/commands/list_collections.cpp10
-rw-r--r--src/mongo/db/commands/list_indexes.cpp13
-rw-r--r--src/mongo/db/namespace_string.cpp20
-rw-r--r--src/mongo/db/namespace_string.h12
-rw-r--r--src/mongo/db/namespace_string_test.cpp17
6 files changed, 77 insertions, 17 deletions
diff --git a/src/mongo/db/commands/killcursors_cmd.cpp b/src/mongo/db/commands/killcursors_cmd.cpp
index ac43fa77680..4c85e5f8f99 100644
--- a/src/mongo/db/commands/killcursors_cmd.cpp
+++ b/src/mongo/db/commands/killcursors_cmd.cpp
@@ -32,6 +32,7 @@
#include "mongo/db/catalog/collection.h"
#include "mongo/db/catalog/cursor_manager.h"
#include "mongo/db/commands/killcursors_common.h"
+#include "mongo/db/curop.h"
#include "mongo/db/db_raii.h"
#include "mongo/db/query/killcursors_request.h"
@@ -45,7 +46,7 @@ public:
private:
Status _killCursor(OperationContext* txn, const NamespaceString& nss, CursorId cursorId) final {
- std::unique_ptr<AutoGetCollectionForRead> ctx;
+ std::unique_ptr<AutoGetCollectionOrViewForRead> ctx;
CursorManager* cursorManager;
if (nss.isListIndexesCursorNS() || nss.isListCollectionsCursorNS()) {
@@ -54,8 +55,25 @@ private:
// data within a collection.
cursorManager = CursorManager::getGlobalCursorManager();
} else {
- ctx = stdx::make_unique<AutoGetCollectionForRead>(txn, nss);
+ ctx = stdx::make_unique<AutoGetCollectionOrViewForRead>(txn, nss);
Collection* collection = ctx->getCollection();
+ ViewDefinition* view = ctx->getView();
+ if (view) {
+ Database* db = ctx->getDb();
+ auto resolved = db->getViewCatalog()->resolveView(txn, nss);
+ if (!resolved.isOK()) {
+ return resolved.getStatus();
+ }
+ ctx->releaseLocksForView();
+ Status status = _killCursor(txn, resolved.getValue().getNamespace(), cursorId);
+ {
+ // Set the namespace of the curop back to the view namespace so ctx records
+ // stats on this view namespace on destruction.
+ stdx::lock_guard<Client>(*txn->getClient());
+ CurOp::get(txn)->setNS_inlock(nss.ns());
+ }
+ return status;
+ }
if (!collection) {
return {ErrorCodes::CursorNotFound,
str::stream() << "collection does not exist: " << nss.ns()};
diff --git a/src/mongo/db/commands/list_collections.cpp b/src/mongo/db/commands/list_collections.cpp
index 87a3c8a30e8..d3dce59c032 100644
--- a/src/mongo/db/commands/list_collections.cpp
+++ b/src/mongo/db/commands/list_collections.cpp
@@ -265,12 +265,10 @@ public:
});
}
- const std::string cursorNamespace = str::stream() << dbname << ".$cmd." << getName();
- dassert(NamespaceString(cursorNamespace).isValid());
- dassert(NamespaceString(cursorNamespace).isListCollectionsCursorNS());
+ const NamespaceString cursorNss = NamespaceString::makeListCollectionsNSS(dbname);
auto statusWithPlanExecutor = PlanExecutor::make(
- txn, std::move(ws), std::move(root), cursorNamespace, PlanExecutor::YIELD_MANUAL);
+ txn, std::move(ws), std::move(root), cursorNss.ns(), PlanExecutor::YIELD_MANUAL);
if (!statusWithPlanExecutor.isOK()) {
return appendCommandStatus(result, statusWithPlanExecutor.getStatus());
}
@@ -302,12 +300,12 @@ public:
ClientCursor* cursor =
new ClientCursor(CursorManager::getGlobalCursorManager(),
exec.release(),
- cursorNamespace,
+ cursorNss.ns(),
txn->recoveryUnit()->isReadingFromMajorityCommittedSnapshot());
cursorId = cursor->cursorid();
}
- appendCursorResponseObject(cursorId, cursorNamespace, firstBatch.arr(), &result);
+ appendCursorResponseObject(cursorId, cursorNss.ns(), firstBatch.arr(), &result);
return true;
}
diff --git a/src/mongo/db/commands/list_indexes.cpp b/src/mongo/db/commands/list_indexes.cpp
index fb32aad5a25..a943061a510 100644
--- a/src/mongo/db/commands/list_indexes.cpp
+++ b/src/mongo/db/commands/list_indexes.cpp
@@ -171,14 +171,11 @@ public:
root->pushBack(id);
}
- const std::string cursorNamespace = str::stream() << dbname << ".$cmd." << getName() << "."
- << ns.coll();
- dassert(NamespaceString(cursorNamespace).isValid());
- dassert(NamespaceString(cursorNamespace).isListIndexesCursorNS());
- dassert(ns == NamespaceString(cursorNamespace).getTargetNSForListIndexes());
+ const NamespaceString cursorNss = NamespaceString::makeListIndexesNSS(dbname, ns.coll());
+ dassert(ns == cursorNss.getTargetNSForListIndexes());
auto statusWithPlanExecutor = PlanExecutor::make(
- txn, std::move(ws), std::move(root), cursorNamespace, PlanExecutor::YIELD_MANUAL);
+ txn, std::move(ws), std::move(root), cursorNss.ns(), PlanExecutor::YIELD_MANUAL);
if (!statusWithPlanExecutor.isOK()) {
return appendCommandStatus(result, statusWithPlanExecutor.getStatus());
}
@@ -210,12 +207,12 @@ public:
ClientCursor* cursor =
new ClientCursor(CursorManager::getGlobalCursorManager(),
exec.release(),
- cursorNamespace,
+ cursorNss.ns(),
txn->recoveryUnit()->isReadingFromMajorityCommittedSnapshot());
cursorId = cursor->cursorid();
}
- appendCursorResponseObject(cursorId, cursorNamespace, firstBatch.arr(), &result);
+ appendCursorResponseObject(cursorId, cursorNss.ns(), firstBatch.arr(), &result);
return true;
}
diff --git a/src/mongo/db/namespace_string.cpp b/src/mongo/db/namespace_string.cpp
index 43f02e26bb5..1128552ca67 100644
--- a/src/mongo/db/namespace_string.cpp
+++ b/src/mongo/db/namespace_string.cpp
@@ -34,6 +34,8 @@
#include "mongo/db/namespace_string.h"
+#include "mongo/util/mongoutils/str.h"
+
namespace mongo {
using std::string;
@@ -70,6 +72,7 @@ const string escapeTable[256] = {
const char kConfigCollection[] = "admin.system.version";
+constexpr auto listCollectionsCursorCol = "$cmd.listCollections"_sd;
constexpr auto listIndexesCursorNSPrefix = "$cmd.listIndexes."_sd;
} // namespace
@@ -105,7 +108,7 @@ const StringData NamespaceString::kLocalDb = "local"_sd;
const NamespaceString NamespaceString::kConfigCollectionNamespace(kConfigCollection);
bool NamespaceString::isListCollectionsCursorNS() const {
- return coll() == "$cmd.listCollections"_sd;
+ return coll() == listCollectionsCursorCol;
}
bool NamespaceString::isListIndexesCursorNS() const {
@@ -113,6 +116,21 @@ bool NamespaceString::isListIndexesCursorNS() const {
coll().startsWith(listIndexesCursorNSPrefix);
}
+NamespaceString NamespaceString::makeListCollectionsNSS(StringData dbName) {
+ NamespaceString nss(dbName, StringData(str::stream() << listCollectionsCursorCol));
+ dassert(nss.isValid());
+ dassert(nss.isListCollectionsCursorNS());
+ return nss;
+}
+
+NamespaceString NamespaceString::makeListIndexesNSS(StringData dbName, StringData collectionName) {
+ NamespaceString nss(dbName,
+ StringData(str::stream() << listIndexesCursorNSPrefix << collectionName));
+ dassert(nss.isValid());
+ dassert(nss.isListIndexesCursorNS());
+ return nss;
+}
+
NamespaceString NamespaceString::getTargetNSForListIndexes() const {
dassert(isListIndexesCursorNS());
return NamespaceString(db(), coll().substr(listIndexesCursorNSPrefix.size()));
diff --git a/src/mongo/db/namespace_string.h b/src/mongo/db/namespace_string.h
index 00ef04c4249..e4b3be50075 100644
--- a/src/mongo/db/namespace_string.h
+++ b/src/mongo/db/namespace_string.h
@@ -87,6 +87,18 @@ public:
NamespaceString(StringData dbName, StringData collectionName);
/**
+ * Contructs a NamespaceString representing a listCollections namespace. The format for this
+ * namespace is "<dbName>.$cmd.listCollections".
+ */
+ static NamespaceString makeListCollectionsNSS(StringData dbName);
+
+ /**
+ * Contructs a NamespaceString representing a listIndexes namespace. The format for this
+ * namespace is "<dbName>.$cmd.listIndexes.<collectionName>".
+ */
+ static NamespaceString makeListIndexesNSS(StringData dbName, StringData collectionName);
+
+ /**
* Note that these values are derived from the mmap_v1 implementation and that
* is the only reason they are constrained as such.
*/
diff --git a/src/mongo/db/namespace_string_test.cpp b/src/mongo/db/namespace_string_test.cpp
index cd5e535d7ee..69884bd5ca9 100644
--- a/src/mongo/db/namespace_string_test.cpp
+++ b/src/mongo/db/namespace_string_test.cpp
@@ -255,4 +255,21 @@ TEST(NamespaceStringTest, NamespaceStringParse4) {
ASSERT_EQUALS((string) "abc", ns.db());
ASSERT_EQUALS((string) "", ns.coll());
}
+
+TEST(NamespaceStringTest, makeListCollectionsNSIsCorrect) {
+ NamespaceString ns = NamespaceString::makeListCollectionsNSS("DB");
+ ASSERT_EQUALS("DB", ns.db());
+ ASSERT_EQUALS("$cmd.listCollections", ns.coll());
+ ASSERT(ns.isValid());
+ ASSERT(ns.isListCollectionsCursorNS());
+}
+
+TEST(NamespaceStringTest, makeListIndexesNSIsCorrect) {
+ NamespaceString ns = NamespaceString::makeListIndexesNSS("DB", "COLL");
+ ASSERT_EQUALS("DB", ns.db());
+ ASSERT_EQUALS("$cmd.listIndexes.COLL", ns.coll());
+ ASSERT(ns.isValid());
+ ASSERT(ns.isListIndexesCursorNS());
+ ASSERT_EQUALS(NamespaceString("DB.COLL"), ns.getTargetNSForListIndexes());
+}
}