summaryrefslogtreecommitdiff
path: root/src/mongo/db/ops
diff options
context:
space:
mode:
authorGeert Bosch <geert@mongodb.com>2014-09-15 15:10:03 -0400
committerGeert Bosch <geert@mongodb.com>2014-09-22 13:44:55 -0400
commitd16ed5e1c2f73d4d529221045385e16e3bec7e44 (patch)
tree99d88bd9c61f9836da881fd9b5bc94fcd2627eba /src/mongo/db/ops
parentad1dafb013342faae7e998586a0c35b70ba75636 (diff)
downloadmongo-d16ed5e1c2f73d4d529221045385e16e3bec7e44.tar.gz
SERVER-14668 update stage doesn't create collection, update executor does if needed
Diffstat (limited to 'src/mongo/db/ops')
-rw-r--r--src/mongo/db/ops/update_executor.cpp24
1 files changed, 23 insertions, 1 deletions
diff --git a/src/mongo/db/ops/update_executor.cpp b/src/mongo/db/ops/update_executor.cpp
index b2f96860bb6..455e1148186 100644
--- a/src/mongo/db/ops/update_executor.cpp
+++ b/src/mongo/db/ops/update_executor.cpp
@@ -38,6 +38,7 @@
#include "mongo/db/ops/update_request.h"
#include "mongo/db/query/canonical_query.h"
#include "mongo/db/query/get_executor.h"
+#include "mongo/db/repl/oplog.h"
#include "mongo/util/assert_util.h"
#include "mongo/util/log.h"
@@ -100,9 +101,30 @@ namespace mongo {
const NamespaceString& nsString = _request->getNamespaceString();
UpdateLifecycle* lifecycle = _request->getLifecycle();
+ validateUpdate(nsString.ns().c_str(), _request->getUpdates(), _request->getQuery());
+
Collection* collection = db->getCollection(_request->getOpCtx(), nsString.ns());
- validateUpdate(nsString.ns().c_str(), _request->getUpdates(), _request->getQuery());
+ // The update stage does not create its own collection. As such, if the update is
+ // an upsert, create the collection that the update stage inserts into beforehand.
+ if (_request->isUpsert()) {
+ if (!collection) {
+ OperationContext* const txn = _request->getOpCtx();
+ WriteUnitOfWork wuow(txn);
+ invariant(txn->lockState()->isWriteLocked());
+ invariant(db->createCollection(txn, nsString.ns()));
+
+ if (!_request->isFromReplication()) {
+ repl::logOp(txn,
+ "c",
+ (db->name() + ".$cmd").c_str(),
+ BSON("create" << (nsString.coll())));
+ }
+ wuow.commit();
+ collection = db->getCollection(_request->getOpCtx(), nsString.ns());
+ }
+ invariant(collection);
+ }
// TODO: This seems a bit circuitious.
_opDebug->updateobj = _request->getUpdates();