summaryrefslogtreecommitdiff
path: root/src/mongo/db/commands
diff options
context:
space:
mode:
authorKaloian Manassiev <kaloian.manassiev@mongodb.com>2014-07-09 04:15:56 -0400
committerKaloian Manassiev <kaloian.manassiev@mongodb.com>2014-07-18 15:16:15 -0400
commit9066a06214f115c182c2b83ed40e939e05b9c1f8 (patch)
tree4239137f6521f1d1d77ecc3c3be89b6e6779f7f1 /src/mongo/db/commands
parent3c3d656668e26645492ee3dafb241631352426d4 (diff)
downloadmongo-9066a06214f115c182c2b83ed40e939e05b9c1f8.tar.gz
SERVER-13961 Pass OperationContext into WhereCallbackReal
There are no functional changes in this commit, just preparation for the subsequent one, which will add operation context to the JS execution scope.
Diffstat (limited to 'src/mongo/db/commands')
-rw-r--r--src/mongo/db/commands/count.cpp2
-rw-r--r--src/mongo/db/commands/find_and_modify.cpp9
-rw-r--r--src/mongo/db/commands/geo_near_cmd.cpp2
-rw-r--r--src/mongo/db/commands/group.cpp2
-rw-r--r--src/mongo/db/commands/index_filter_commands.cpp32
-rw-r--r--src/mongo/db/commands/index_filter_commands.h10
-rw-r--r--src/mongo/db/commands/index_filter_commands_test.cpp58
-rw-r--r--src/mongo/db/commands/mr.cpp4
-rw-r--r--src/mongo/db/commands/plan_cache_commands.cpp26
-rw-r--r--src/mongo/db/commands/plan_cache_commands.h16
-rw-r--r--src/mongo/db/commands/plan_cache_commands_test.cpp58
-rw-r--r--src/mongo/db/commands/write_commands/batch_executor.cpp8
12 files changed, 140 insertions, 87 deletions
diff --git a/src/mongo/db/commands/count.cpp b/src/mongo/db/commands/count.cpp
index e630ff21dc9..f68f7488785 100644
--- a/src/mongo/db/commands/count.cpp
+++ b/src/mongo/db/commands/count.cpp
@@ -209,7 +209,7 @@ namespace mongo {
const BSONObj hintObj = hint.empty() ? BSONObj() : BSON("$hint" << hint);
StringData dbnameData(dbname);
- const WhereCallbackReal whereCallback(dbnameData);
+ const WhereCallbackReal whereCallback(txn, dbnameData);
CanonicalQuery* cq;
uassertStatusOK(CanonicalQuery::canonicalize(ns,
diff --git a/src/mongo/db/commands/find_and_modify.cpp b/src/mongo/db/commands/find_and_modify.cpp
index f242327f935..9df4c363b62 100644
--- a/src/mongo/db/commands/find_and_modify.cpp
+++ b/src/mongo/db/commands/find_and_modify.cpp
@@ -142,7 +142,7 @@ namespace mongo {
Collection* collection = cx.db()->getCollection( txn, ns );
- const WhereCallbackReal whereCallback = WhereCallbackReal(StringData(ns));
+ const WhereCallbackReal whereCallback = WhereCallbackReal(txn, StringData(ns));
BSONObj doc;
bool found = false;
@@ -247,7 +247,7 @@ namespace mongo {
}
const NamespaceString requestNs(ns);
- UpdateRequest request(requestNs);
+ UpdateRequest request(txn, requestNs);
request.setQuery(queryModified);
request.setUpdates(update);
@@ -257,8 +257,7 @@ namespace mongo {
// the shard version below, but for now no
UpdateLifecycleImpl updateLifecycle(false, requestNs);
request.setLifecycle(&updateLifecycle);
- UpdateResult res = mongo::update(txn,
- cx.db(),
+ UpdateResult res = mongo::update(cx.db(),
request,
&txn->getCurOp()->debug());
@@ -328,7 +327,7 @@ namespace mongo {
Projection projection;
if (fields) {
- projection.init(fieldsHolder, WhereCallbackReal(StringData(dbname)));
+ projection.init(fieldsHolder, WhereCallbackReal(txn, StringData(dbname)));
if (!projection.includeID()) {
fields = NULL; // do projection in post-processing
}
diff --git a/src/mongo/db/commands/geo_near_cmd.cpp b/src/mongo/db/commands/geo_near_cmd.cpp
index f994004e2b2..7fb6b972efd 100644
--- a/src/mongo/db/commands/geo_near_cmd.cpp
+++ b/src/mongo/db/commands/geo_near_cmd.cpp
@@ -171,7 +171,7 @@ namespace mongo {
CanonicalQuery* cq;
const NamespaceString nss(dbname);
- const WhereCallbackReal whereCallback(nss.db());
+ const WhereCallbackReal whereCallback(txn, nss.db());
if (!CanonicalQuery::canonicalize(ns,
rewritten,
diff --git a/src/mongo/db/commands/group.cpp b/src/mongo/db/commands/group.cpp
index 519a5989dd1..aed8e699e83 100644
--- a/src/mongo/db/commands/group.cpp
+++ b/src/mongo/db/commands/group.cpp
@@ -134,7 +134,7 @@ namespace mongo {
Collection* collection = db->getCollection( txn, ns );
- const WhereCallbackReal whereCallback(StringData(db->name()));
+ const WhereCallbackReal whereCallback(txn, StringData(db->name()));
map<BSONObj,int,BSONObjCmp> map;
list<BSONObj> blah;
diff --git a/src/mongo/db/commands/index_filter_commands.cpp b/src/mongo/db/commands/index_filter_commands.cpp
index e0d5be5255a..139350b3002 100644
--- a/src/mongo/db/commands/index_filter_commands.cpp
+++ b/src/mongo/db/commands/index_filter_commands.cpp
@@ -67,9 +67,11 @@ namespace {
/**
* Retrieves a collection's query settings and plan cache from the database.
*/
- Status getQuerySettingsAndPlanCache(OperationContext* txn, Database* db, const string& ns,
- QuerySettings** querySettingsOut,
- PlanCache** planCacheOut) {
+ static Status getQuerySettingsAndPlanCache(OperationContext* txn,
+ Database* db,
+ const string& ns,
+ QuerySettings** querySettingsOut,
+ PlanCache** planCacheOut) {
invariant(db);
Collection* collection = db->getCollection(txn, ns);
@@ -238,12 +240,15 @@ namespace mongo {
// No collection - do nothing.
return Status::OK();
}
- return clear(querySettings, planCache, ns, cmdObj);
+ return clear(txn, querySettings, planCache, ns, cmdObj);
}
// static
- Status ClearFilters::clear(QuerySettings* querySettings, PlanCache* planCache,
- const std::string& ns, const BSONObj& cmdObj) {
+ Status ClearFilters::clear(OperationContext* txn,
+ QuerySettings* querySettings,
+ PlanCache* planCache,
+ const std::string& ns,
+ const BSONObj& cmdObj) {
invariant(querySettings);
// According to the specification, the planCacheClearFilters command runs in two modes:
@@ -252,7 +257,7 @@ namespace mongo {
// command arguments.
if (cmdObj.hasField("query")) {
CanonicalQuery* cqRaw;
- Status status = PlanCacheCommand::canonicalize(ns, cmdObj, &cqRaw);
+ Status status = PlanCacheCommand::canonicalize(txn, ns, cmdObj, &cqRaw);
if (!status.isOK()) {
return status;
}
@@ -281,7 +286,7 @@ namespace mongo {
querySettings->clearAllowedIndices();
const NamespaceString nss(ns);
- const WhereCallbackReal whereCallback(nss.db());
+ const WhereCallbackReal whereCallback(txn, nss.db());
// Remove corresponding entries from plan cache.
// Admin hints affect the planning process directly. If there were
@@ -328,12 +333,15 @@ namespace mongo {
if (!status.isOK()) {
return status;
}
- return set(querySettings, planCache, ns, cmdObj);
+ return set(txn, querySettings, planCache, ns, cmdObj);
}
// static
- Status SetFilter::set(QuerySettings* querySettings, PlanCache* planCache,
- const string& ns, const BSONObj& cmdObj) {
+ Status SetFilter::set(OperationContext* txn,
+ QuerySettings* querySettings,
+ PlanCache* planCache,
+ const string& ns,
+ const BSONObj& cmdObj) {
// indexes - required
BSONElement indexesElt = cmdObj.getField("indexes");
if (indexesElt.eoo()) {
@@ -362,7 +370,7 @@ namespace mongo {
}
CanonicalQuery* cqRaw;
- Status status = PlanCacheCommand::canonicalize(ns, cmdObj, &cqRaw);
+ Status status = PlanCacheCommand::canonicalize(txn, ns, cmdObj, &cqRaw);
if (!status.isOK()) {
return status;
}
diff --git a/src/mongo/db/commands/index_filter_commands.h b/src/mongo/db/commands/index_filter_commands.h
index f6ba8fa9efb..2f106b16f36 100644
--- a/src/mongo/db/commands/index_filter_commands.h
+++ b/src/mongo/db/commands/index_filter_commands.h
@@ -138,7 +138,10 @@ namespace mongo {
* Namespace argument ns is ignored if we are clearing the entire cache.
* Removes corresponding entries from plan cache.
*/
- static Status clear(QuerySettings* querySettings, PlanCache* planCache, const std::string& ns,
+ static Status clear(OperationContext* txn,
+ QuerySettings* querySettings,
+ PlanCache* planCache,
+ const std::string& ns,
const BSONObj& cmdObj);
};
@@ -167,7 +170,10 @@ namespace mongo {
* Sets index filter for a query shape.
* Removes entry for query shape from plan cache.
*/
- static Status set(QuerySettings* querySettings, PlanCache* planCache, const std::string& ns,
+ static Status set(OperationContext* txn,
+ QuerySettings* querySettings,
+ PlanCache* planCache,
+ const std::string& ns,
const BSONObj& cmdObj);
};
diff --git a/src/mongo/db/commands/index_filter_commands_test.cpp b/src/mongo/db/commands/index_filter_commands_test.cpp
index c3a5fc1d6a5..e892bcee7a8 100644
--- a/src/mongo/db/commands/index_filter_commands_test.cpp
+++ b/src/mongo/db/commands/index_filter_commands_test.cpp
@@ -33,6 +33,7 @@
#include "mongo/db/commands/index_filter_commands.h"
#include "mongo/db/json.h"
+#include "mongo/db/operation_context_noop.h"
#include "mongo/db/query/plan_ranker.h"
#include "mongo/db/query/query_solution.h"
#include "mongo/unittest/unittest.h"
@@ -181,35 +182,39 @@ namespace {
TEST(IndexFilterCommandsTest, ClearFiltersInvalidParameter) {
QuerySettings empty;
PlanCache planCache;
+ OperationContextNoop txn;
+
// If present, query has to be an object.
- ASSERT_NOT_OK(ClearFilters::clear(&empty, &planCache, ns, fromjson("{query: 1234}")));
+ ASSERT_NOT_OK(ClearFilters::clear(&txn, &empty, &planCache, ns, fromjson("{query: 1234}")));
// If present, sort must be an object.
- ASSERT_NOT_OK(ClearFilters::clear(&empty, &planCache, ns,
+ ASSERT_NOT_OK(ClearFilters::clear(&txn, &empty, &planCache, ns,
fromjson("{query: {a: 1}, sort: 1234}")));
// If present, projection must be an object.
- ASSERT_NOT_OK(ClearFilters::clear(&empty, &planCache, ns,
+ ASSERT_NOT_OK(ClearFilters::clear(&txn, &empty, &planCache, ns,
fromjson("{query: {a: 1}, projection: 1234}")));
// Query must pass canonicalization.
- ASSERT_NOT_OK(ClearFilters::clear(&empty, &planCache, ns,
+ ASSERT_NOT_OK(ClearFilters::clear(&txn, &empty, &planCache, ns,
fromjson("{query: {a: {$no_such_op: 1}}}")));
// Sort present without query is an error.
- ASSERT_NOT_OK(ClearFilters::clear(&empty, &planCache, ns, fromjson("{sort: {a: 1}}")));
+ ASSERT_NOT_OK(ClearFilters::clear(&txn, &empty, &planCache, ns, fromjson("{sort: {a: 1}}")));
// Projection present without query is an error.
- ASSERT_NOT_OK(ClearFilters::clear(&empty, &planCache, ns,
+ ASSERT_NOT_OK(ClearFilters::clear(&txn, &empty, &planCache, ns,
fromjson("{projection: {_id: 0, a: 1}}")));
}
TEST(IndexFilterCommandsTest, ClearNonexistentHint) {
QuerySettings querySettings;
PlanCache planCache;
- ASSERT_OK(SetFilter::set(&querySettings, &planCache, ns,
+ OperationContextNoop txn;
+
+ ASSERT_OK(SetFilter::set(&txn, &querySettings, &planCache, ns,
fromjson("{query: {a: 1}, indexes: [{a: 1}]}")));
vector<BSONObj> filters = getFilters(querySettings);
ASSERT_EQUALS(filters.size(), 1U);
// Clear nonexistent hint.
// Command should succeed and cache should remain unchanged.
- ASSERT_OK(ClearFilters::clear(&querySettings, &planCache, ns, fromjson("{query: {b: 1}}")));
+ ASSERT_OK(ClearFilters::clear(&txn, &querySettings, &planCache, ns, fromjson("{query: {b: 1}}")));
filters = getFilters(querySettings);
ASSERT_EQUALS(filters.size(), 1U);
}
@@ -221,46 +226,49 @@ namespace {
TEST(IndexFilterCommandsTest, SetFilterInvalidParameter) {
QuerySettings empty;
PlanCache planCache;
- ASSERT_NOT_OK(SetFilter::set(&empty, &planCache, ns, fromjson("{}")));
+ OperationContextNoop txn;
+
+ ASSERT_NOT_OK(SetFilter::set(&txn, &empty, &planCache, ns, fromjson("{}")));
// Missing required query field.
- ASSERT_NOT_OK(SetFilter::set(&empty, &planCache, ns, fromjson("{indexes: [{a: 1}]}")));
+ ASSERT_NOT_OK(SetFilter::set(&txn, &empty, &planCache, ns, fromjson("{indexes: [{a: 1}]}")));
// Missing required indexes field.
- ASSERT_NOT_OK(SetFilter::set(&empty, &planCache, ns, fromjson("{query: {a: 1}}")));
+ ASSERT_NOT_OK(SetFilter::set(&txn, &empty, &planCache, ns, fromjson("{query: {a: 1}}")));
// Query has to be an object.
- ASSERT_NOT_OK(SetFilter::set(&empty, &planCache, ns,
+ ASSERT_NOT_OK(SetFilter::set(&txn, &empty, &planCache, ns,
fromjson("{query: 1234, indexes: [{a: 1}, {b: 1}]}")));
// Indexes field has to be an array.
- ASSERT_NOT_OK(SetFilter::set(&empty, &planCache, ns,
+ ASSERT_NOT_OK(SetFilter::set(&txn, &empty, &planCache, ns,
fromjson("{query: {a: 1}, indexes: 1234}")));
// Array indexes field cannot empty.
- ASSERT_NOT_OK(SetFilter::set(&empty, &planCache, ns,
+ ASSERT_NOT_OK(SetFilter::set(&txn, &empty, &planCache, ns,
fromjson("{query: {a: 1}, indexes: []}")));
// Elements in indexes have to be objects.
- ASSERT_NOT_OK(SetFilter::set(&empty, &planCache, ns,
+ ASSERT_NOT_OK(SetFilter::set(&txn, &empty, &planCache, ns,
fromjson("{query: {a: 1}, indexes: [{a: 1}, 99]}")));
// Objects in indexes cannot be empty.
- ASSERT_NOT_OK(SetFilter::set(&empty, &planCache, ns,
+ ASSERT_NOT_OK(SetFilter::set(&txn, &empty, &planCache, ns,
fromjson("{query: {a: 1}, indexes: [{a: 1}, {}]}")));
// If present, sort must be an object.
- ASSERT_NOT_OK(SetFilter::set(&empty, &planCache, ns,
+ ASSERT_NOT_OK(SetFilter::set(&txn, &empty, &planCache, ns,
fromjson("{query: {a: 1}, sort: 1234, indexes: [{a: 1}, {b: 1}]}")));
// If present, projection must be an object.
- ASSERT_NOT_OK(SetFilter::set(&empty, &planCache, ns,
+ ASSERT_NOT_OK(SetFilter::set(&txn, &empty, &planCache, ns,
fromjson("{query: {a: 1}, projection: 1234, indexes: [{a: 1}, {b: 1}]}")));
// Query must pass canonicalization.
- ASSERT_NOT_OK(SetFilter::set(&empty, &planCache, ns,
+ ASSERT_NOT_OK(SetFilter::set(&txn, &empty, &planCache, ns,
fromjson("{query: {a: {$no_such_op: 1}}, indexes: [{a: 1}, {b: 1}]}")));
}
TEST(IndexFilterCommandsTest, SetAndClearFilters) {
QuerySettings querySettings;
PlanCache planCache;
+ OperationContextNoop txn;
// Inject query shape into plan cache.
addQueryShapeToPlanCache(&planCache, "{a: 1, b: 1}", "{a: -1}", "{_id: 0, a: 1}");
ASSERT_TRUE(planCacheContains(planCache, "{a: 1, b: 1}", "{a: -1}", "{_id: 0, a: 1}"));
- ASSERT_OK(SetFilter::set(&querySettings, &planCache, ns,
+ ASSERT_OK(SetFilter::set(&txn, &querySettings, &planCache, ns,
fromjson("{query: {a: 1, b: 1}, sort: {a: -1}, projection: {_id: 0, a: 1}, "
"indexes: [{a: 1}]}")));
vector<BSONObj> filters = getFilters(querySettings);
@@ -276,20 +284,20 @@ namespace {
// Replacing the hint for the same query shape ({a: 1, b: 1} and {b: 2, a: 3}
// share same shape) should not change the query settings size.
- ASSERT_OK(SetFilter::set(&querySettings, &planCache, ns,
+ ASSERT_OK(SetFilter::set(&txn, &querySettings, &planCache, ns,
fromjson("{query: {b: 2, a: 3}, sort: {a: -1}, projection: {_id: 0, a: 1}, "
"indexes: [{a: 1, b: 1}]}")));
filters = getFilters(querySettings);
ASSERT_EQUALS(filters.size(), 1U);
// Add hint for different query shape.
- ASSERT_OK(SetFilter::set(&querySettings, &planCache, ns,
+ ASSERT_OK(SetFilter::set(&txn, &querySettings, &planCache, ns,
fromjson("{query: {b: 1}, indexes: [{b: 1}]}")));
filters = getFilters(querySettings);
ASSERT_EQUALS(filters.size(), 2U);
// Add hint for 3rd query shape. This is to prepare for ClearHint tests.
- ASSERT_OK(SetFilter::set(&querySettings, &planCache, ns,
+ ASSERT_OK(SetFilter::set(&txn, &querySettings, &planCache, ns,
fromjson("{query: {a: 1}, indexes: [{a: 1}]}")));
filters = getFilters(querySettings);
ASSERT_EQUALS(filters.size(), 3U);
@@ -299,7 +307,7 @@ namespace {
addQueryShapeToPlanCache(&planCache, "{b: 1}", "{}", "{}");
// Clear single hint.
- ASSERT_OK(ClearFilters::clear(&querySettings, &planCache, ns,
+ ASSERT_OK(ClearFilters::clear(&txn, &querySettings, &planCache, ns,
fromjson("{query: {a: 1}}")));
filters = getFilters(querySettings);
ASSERT_EQUALS(filters.size(), 2U);
@@ -309,7 +317,7 @@ namespace {
ASSERT_TRUE(planCacheContains(planCache, "{b: 1}", "{}", "{}"));
// Clear all filters
- ASSERT_OK(ClearFilters::clear(&querySettings, &planCache, ns, fromjson("{}")));
+ ASSERT_OK(ClearFilters::clear(&txn, &querySettings, &planCache, ns, fromjson("{}")));
filters = getFilters(querySettings);
ASSERT_TRUE(filters.empty());
diff --git a/src/mongo/db/commands/mr.cpp b/src/mongo/db/commands/mr.cpp
index 58360d4cdd0..df0a6e7b9e3 100644
--- a/src/mongo/db/commands/mr.cpp
+++ b/src/mongo/db/commands/mr.cpp
@@ -977,7 +977,7 @@ namespace mongo {
_db.count(_config.incLong, BSONObj(), QueryOption_SlaveOk)));
const NamespaceString nss(_config.incLong);
- const WhereCallbackReal whereCallback(nss.db());
+ const WhereCallbackReal whereCallback(_txn, nss.db());
CanonicalQuery* cq;
verify(CanonicalQuery::canonicalize(_config.incLong,
@@ -1317,7 +1317,7 @@ namespace mongo {
scoped_ptr<Client::Context> ctx(new Client::Context(txn, config.ns, false));
const NamespaceString nss(config.ns);
- const WhereCallbackReal whereCallback(nss.db());
+ const WhereCallbackReal whereCallback(txn, nss.db());
CanonicalQuery* cq;
if (!CanonicalQuery::canonicalize(config.ns,
diff --git a/src/mongo/db/commands/plan_cache_commands.cpp b/src/mongo/db/commands/plan_cache_commands.cpp
index 7436ecc9eea..2a8bb83ef8c 100644
--- a/src/mongo/db/commands/plan_cache_commands.cpp
+++ b/src/mongo/db/commands/plan_cache_commands.cpp
@@ -157,7 +157,9 @@ namespace mongo {
}
// static
- Status PlanCacheCommand::canonicalize(const string& ns, const BSONObj& cmdObj,
+ Status PlanCacheCommand::canonicalize(OperationContext* txn,
+ const string& ns,
+ const BSONObj& cmdObj,
CanonicalQuery** canonicalQueryOut) {
// query - required
BSONElement queryElt = cmdObj.getField("query");
@@ -196,7 +198,7 @@ namespace mongo {
CanonicalQuery* cqRaw;
const NamespaceString nss(ns);
- const WhereCallbackReal whereCallback(nss.db());
+ const WhereCallbackReal whereCallback(txn, nss.db());
Status result = CanonicalQuery::canonicalize(
ns, queryObj, sortObj, projObj, &cqRaw, whereCallback);
@@ -273,11 +275,14 @@ namespace mongo {
// No collection - nothing to do. Return OK status.
return Status::OK();
}
- return clear(planCache, ns, cmdObj);
+ return clear(txn, planCache, ns, cmdObj);
}
// static
- Status PlanCacheClear::clear(PlanCache* planCache, const string& ns, const BSONObj& cmdObj) {
+ Status PlanCacheClear::clear(OperationContext* txn,
+ PlanCache* planCache,
+ const string& ns,
+ const BSONObj& cmdObj) {
invariant(planCache);
// According to the specification, the planCacheClear command runs in two modes:
@@ -286,7 +291,7 @@ namespace mongo {
// command arguments.
if (cmdObj.hasField("query")) {
CanonicalQuery* cqRaw;
- Status status = PlanCacheCommand::canonicalize(ns, cmdObj, &cqRaw);
+ Status status = PlanCacheCommand::canonicalize(txn, ns, cmdObj, &cqRaw);
if (!status.isOK()) {
return status;
}
@@ -346,14 +351,17 @@ namespace mongo {
plansBuilder.doneFast();
return Status::OK();
}
- return list(*planCache, ns, cmdObj, bob);
+ return list(txn, *planCache, ns, cmdObj, bob);
}
// static
- Status PlanCacheListPlans::list(const PlanCache& planCache, const std::string& ns,
- const BSONObj& cmdObj, BSONObjBuilder* bob) {
+ Status PlanCacheListPlans::list(OperationContext* txn,
+ const PlanCache& planCache,
+ const std::string& ns,
+ const BSONObj& cmdObj,
+ BSONObjBuilder* bob) {
CanonicalQuery* cqRaw;
- Status status = canonicalize(ns, cmdObj, &cqRaw);
+ Status status = canonicalize(txn, ns, cmdObj, &cqRaw);
if (!status.isOK()) {
return status;
}
diff --git a/src/mongo/db/commands/plan_cache_commands.h b/src/mongo/db/commands/plan_cache_commands.h
index 507d4fe4927..1a4a49a3c4f 100644
--- a/src/mongo/db/commands/plan_cache_commands.h
+++ b/src/mongo/db/commands/plan_cache_commands.h
@@ -89,7 +89,9 @@ namespace mongo {
/**
* Validatess query shape from command object and returns canonical query.
*/
- static Status canonicalize(const std::string& ns, const BSONObj& cmdObj,
+ static Status canonicalize(OperationContext* txn,
+ const std::string& ns,
+ const BSONObj& cmdObj,
CanonicalQuery** canonicalQueryOut);
private:
@@ -141,7 +143,10 @@ namespace mongo {
* Clears collection's plan cache.
* If query shape is provided, clears plans for that single query shape only.
*/
- static Status clear(PlanCache* planCache, const std::string& ns, const BSONObj& cmdObj);
+ static Status clear(OperationContext* txn,
+ PlanCache* planCache,
+ const std::string& ns,
+ const BSONObj& cmdObj);
};
/**
@@ -166,8 +171,11 @@ namespace mongo {
/**
* Displays the cached plans for a query shape.
*/
- static Status list(const PlanCache& planCache, const std::string& ns,
- const BSONObj& cmdObj, BSONObjBuilder* bob);
+ static Status list(OperationContext* txn,
+ const PlanCache& planCache,
+ const std::string& ns,
+ const BSONObj& cmdObj,
+ BSONObjBuilder* bob);
};
} // namespace mongo
diff --git a/src/mongo/db/commands/plan_cache_commands_test.cpp b/src/mongo/db/commands/plan_cache_commands_test.cpp
index 5a6775cdb74..d2cae74ac12 100644
--- a/src/mongo/db/commands/plan_cache_commands_test.cpp
+++ b/src/mongo/db/commands/plan_cache_commands_test.cpp
@@ -34,6 +34,7 @@
#include <algorithm>
#include "mongo/db/json.h"
+#include "mongo/db/operation_context_noop.h"
#include "mongo/db/query/plan_ranker.h"
#include "mongo/db/query/query_solution.h"
#include "mongo/unittest/unittest.h"
@@ -154,6 +155,8 @@ namespace {
// Plan cache with one entry
PlanCache planCache;
QuerySolution qs;
+ OperationContextNoop txn;
+
qs.cacheData.reset(createSolutionCacheData());
std::vector<QuerySolution*> solns;
solns.push_back(&qs);
@@ -161,7 +164,7 @@ namespace {
ASSERT_EQUALS(getShapes(planCache).size(), 1U);
// Clear cache and confirm number of keys afterwards.
- ASSERT_OK(PlanCacheClear::clear(&planCache, ns, BSONObj()));
+ ASSERT_OK(PlanCacheClear::clear(&txn, &planCache, ns, BSONObj()));
ASSERT_EQUALS(getShapes(planCache).size(), 0U);
}
@@ -173,35 +176,37 @@ namespace {
TEST(PlanCacheCommandsTest, Canonicalize) {
// Invalid parameters
CanonicalQuery* cqRaw;
+ OperationContextNoop txn;
+
// Missing query field
- ASSERT_NOT_OK(PlanCacheCommand::canonicalize(ns, fromjson("{}"), &cqRaw));
+ ASSERT_NOT_OK(PlanCacheCommand::canonicalize(&txn, ns, fromjson("{}"), &cqRaw));
// Query needs to be an object
- ASSERT_NOT_OK(PlanCacheCommand::canonicalize(ns, fromjson("{query: 1}"), &cqRaw));
+ ASSERT_NOT_OK(PlanCacheCommand::canonicalize(&txn, ns, fromjson("{query: 1}"), &cqRaw));
// Sort needs to be an object
- ASSERT_NOT_OK(PlanCacheCommand::canonicalize(ns, fromjson("{query: {}, sort: 1}"),
+ ASSERT_NOT_OK(PlanCacheCommand::canonicalize(&txn, ns, fromjson("{query: {}, sort: 1}"),
&cqRaw));
// Bad query (invalid sort order)
- ASSERT_NOT_OK(PlanCacheCommand::canonicalize(ns, fromjson("{query: {}, sort: {a: 0}}"),
+ ASSERT_NOT_OK(PlanCacheCommand::canonicalize(&txn, ns, fromjson("{query: {}, sort: {a: 0}}"),
&cqRaw));
// Valid parameters
- ASSERT_OK(PlanCacheCommand::canonicalize(ns, fromjson("{query: {a: 1, b: 1}}"), &cqRaw));
+ ASSERT_OK(PlanCacheCommand::canonicalize(&txn, ns, fromjson("{query: {a: 1, b: 1}}"), &cqRaw));
scoped_ptr<CanonicalQuery> query(cqRaw);
// Equivalent query should generate same key.
- ASSERT_OK(PlanCacheCommand::canonicalize(ns, fromjson("{query: {b: 1, a: 1}}"), &cqRaw));
+ ASSERT_OK(PlanCacheCommand::canonicalize(&txn, ns, fromjson("{query: {b: 1, a: 1}}"), &cqRaw));
scoped_ptr<CanonicalQuery> equivQuery(cqRaw);
ASSERT_EQUALS(query->getPlanCacheKey(), equivQuery->getPlanCacheKey());
// Sort query should generate different key from unsorted query.
- ASSERT_OK(PlanCacheCommand::canonicalize(ns,
+ ASSERT_OK(PlanCacheCommand::canonicalize(&txn, ns,
fromjson("{query: {a: 1, b: 1}, sort: {a: 1}}"), &cqRaw));
scoped_ptr<CanonicalQuery> sortQuery(cqRaw);
ASSERT_NOT_EQUALS(query->getPlanCacheKey(), sortQuery->getPlanCacheKey());
// Projected query should generate different key from unprojected query.
- ASSERT_OK(PlanCacheCommand::canonicalize(ns,
+ ASSERT_OK(PlanCacheCommand::canonicalize(&txn, ns,
fromjson("{query: {a: 1, b: 1}, projection: {_id: 0, a: 1}}"), &cqRaw));
scoped_ptr<CanonicalQuery> projectionQuery(cqRaw);
ASSERT_NOT_EQUALS(query->getPlanCacheKey(), projectionQuery->getPlanCacheKey());
@@ -213,22 +218,26 @@ namespace {
TEST(PlanCacheCommandsTest, planCacheClearInvalidParameter) {
PlanCache planCache;
+ OperationContextNoop txn;
+
// Query field type must be BSON object.
- ASSERT_NOT_OK(PlanCacheClear::clear(&planCache, ns, fromjson("{query: 12345}")));
- ASSERT_NOT_OK(PlanCacheClear::clear(&planCache, ns, fromjson("{query: /keyisnotregex/}")));
+ ASSERT_NOT_OK(PlanCacheClear::clear(&txn, &planCache, ns, fromjson("{query: 12345}")));
+ ASSERT_NOT_OK(PlanCacheClear::clear(&txn, &planCache, ns, fromjson("{query: /keyisnotregex/}")));
// Query must pass canonicalization.
- ASSERT_NOT_OK(PlanCacheClear::clear(&planCache, ns,
+ ASSERT_NOT_OK(PlanCacheClear::clear(&txn, &planCache, ns,
fromjson("{query: {a: {$no_such_op: 1}}}")));
// Sort present without query is an error.
- ASSERT_NOT_OK(PlanCacheClear::clear(&planCache, ns, fromjson("{sort: {a: 1}}")));
+ ASSERT_NOT_OK(PlanCacheClear::clear(&txn, &planCache, ns, fromjson("{sort: {a: 1}}")));
// Projection present without query is an error.
- ASSERT_NOT_OK(PlanCacheClear::clear(&planCache, ns,
+ ASSERT_NOT_OK(PlanCacheClear::clear(&txn, &planCache, ns,
fromjson("{projection: {_id: 0, a: 1}}")));
}
TEST(PlanCacheCommandsTest, planCacheClearUnknownKey) {
PlanCache planCache;
- ASSERT_OK(PlanCacheClear::clear(&planCache, ns, fromjson("{query: {a: 1}}")));
+ OperationContextNoop txn;
+
+ ASSERT_OK(PlanCacheClear::clear(&txn, &planCache, ns, fromjson("{query: {a: 1}}")));
}
TEST(PlanCacheCommandsTest, planCacheClearOneKey) {
@@ -260,7 +269,9 @@ namespace {
// Drop {b: 1} from cache. Make sure {a: 1} is still in cache afterwards.
BSONObjBuilder bob;
- ASSERT_OK(PlanCacheClear::clear(&planCache, ns, BSON("query" << cqB->getQueryObj())));
+ OperationContextNoop txn;
+
+ ASSERT_OK(PlanCacheClear::clear(&txn, &planCache, ns, BSON("query" << cqB->getQueryObj())));
vector<BSONObj> shapesAfter = getShapes(planCache);
ASSERT_EQUALS(shapesAfter.size(), 1U);
ASSERT_EQUALS(shapesAfter[0], shapeA);
@@ -308,9 +319,11 @@ namespace {
*/
vector<BSONObj> getPlans(const PlanCache& planCache, const BSONObj& query,
const BSONObj& sort, const BSONObj& projection) {
+ OperationContextNoop txn;
+
BSONObjBuilder bob;
BSONObj cmdObj = BSON("query" << query << "sort" << sort << "projection" << projection);
- ASSERT_OK(PlanCacheListPlans::list(planCache, ns, cmdObj, &bob));
+ ASSERT_OK(PlanCacheListPlans::list(&txn, planCache, ns, cmdObj, &bob));
BSONObj resultObj = bob.obj();
BSONElement plansElt = resultObj.getField("plans");
ASSERT_EQUALS(plansElt.type(), mongo::Array);
@@ -324,21 +337,24 @@ namespace {
TEST(PlanCacheCommandsTest, planCacheListPlansInvalidParameter) {
PlanCache planCache;
BSONObjBuilder ignored;
+ OperationContextNoop txn;
+
// Missing query field is not ok.
- ASSERT_NOT_OK(PlanCacheListPlans::list(planCache, ns, BSONObj(), &ignored));
+ ASSERT_NOT_OK(PlanCacheListPlans::list(&txn, planCache, ns, BSONObj(), &ignored));
// Query field type must be BSON object.
- ASSERT_NOT_OK(PlanCacheListPlans::list(planCache, ns, fromjson("{query: 12345}"),
+ ASSERT_NOT_OK(PlanCacheListPlans::list(&txn, planCache, ns, fromjson("{query: 12345}"),
&ignored));
- ASSERT_NOT_OK(PlanCacheListPlans::list(planCache, ns, fromjson("{query: /keyisnotregex/}"),
+ ASSERT_NOT_OK(PlanCacheListPlans::list(&txn, planCache, ns, fromjson("{query: /keyisnotregex/}"),
&ignored));
}
TEST(PlanCacheCommandsTest, planCacheListPlansUnknownKey) {
// Leave the plan cache empty.
PlanCache planCache;
+ OperationContextNoop txn;
BSONObjBuilder ignored;
- ASSERT_OK(PlanCacheListPlans::list(planCache, ns, fromjson("{query: {a: 1}}"), &ignored));
+ ASSERT_OK(PlanCacheListPlans::list(&txn, planCache, ns, fromjson("{query: {a: 1}}"), &ignored));
}
TEST(PlanCacheCommandsTest, planCacheListPlansOnlyOneSolutionTrue) {
diff --git a/src/mongo/db/commands/write_commands/batch_executor.cpp b/src/mongo/db/commands/write_commands/batch_executor.cpp
index 2f3a39fa3d7..419c01be9c6 100644
--- a/src/mongo/db/commands/write_commands/batch_executor.cpp
+++ b/src/mongo/db/commands/write_commands/batch_executor.cpp
@@ -1088,7 +1088,7 @@ namespace mongo {
WriteOpResult* result ) {
const NamespaceString nsString(updateItem.getRequest()->getNS());
- UpdateRequest request(nsString);
+ UpdateRequest request(txn, nsString);
request.setQuery(updateItem.getUpdate()->getQuery());
request.setUpdates(updateItem.getUpdate()->getUpdateExpr());
request.setMulti(updateItem.getUpdate()->getMulti());
@@ -1115,7 +1115,7 @@ namespace mongo {
Client::Context ctx(txn, nsString.ns(), false /* don't check version */);
try {
- UpdateResult res = executor.execute(txn, ctx.db());
+ UpdateResult res = executor.execute(ctx.db());
const long long numDocsModified = res.numDocsModified;
const long long numMatched = res.numMatched;
@@ -1149,7 +1149,7 @@ namespace mongo {
WriteOpResult* result ) {
const NamespaceString nss( removeItem.getRequest()->getNS() );
- DeleteRequest request( nss );
+ DeleteRequest request(txn, nss);
request.setQuery( removeItem.getDelete()->getQuery() );
request.setMulti( removeItem.getDelete()->getLimit() != 1 );
request.setUpdateOpLog(true);
@@ -1178,7 +1178,7 @@ namespace mongo {
Client::Context writeContext(txn, nss.ns(), false /* don't check version */);
try {
- result->getStats().n = executor.execute(txn, writeContext.db());
+ result->getStats().n = executor.execute(writeContext.db());
}
catch ( const DBException& ex ) {
status = ex.toStatus();