summaryrefslogtreecommitdiff
path: root/jstests/aggregation
diff options
context:
space:
mode:
authorMax Hirschhorn <max.hirschhorn@mongodb.com>2016-02-29 10:47:18 -0500
committerRamon Fernandez <ramon@mongodb.com>2016-02-29 15:51:07 -0500
commit139286b38e3d0e1efc1efbe52417310277b3aed8 (patch)
tree7844849bb0c4830c8fbde163171858142984f90d /jstests/aggregation
parente7ec5454e1614826e57563c24f94662a44184283 (diff)
downloadmongo-139286b38e3d0e1efc1efbe52417310277b3aed8.tar.gz
SERVER-22537 Fix DBDirectClient's OperationContext not getting updated.
This fixes an issue where the DBDirectClient used by the $lookup stage would have the previous OperationContext and trigger an invalid memory access when sending a getMore request as it unwinds the results. Calling PipelineProxyStage::doDetachFromOperationContext() now causes the DBDirectClient's OperationContext to be set to nullptr, and PipelineProxyStage::doReattachToOperationContext() causes it to be set to the current OperationContext. (cherry picked from commit e1928f36d21a4193802d7fbdcb8fcd6df58f7aa7)
Diffstat (limited to 'jstests/aggregation')
-rw-r--r--jstests/aggregation/bugs/lookup_unwind_getmore.js55
1 files changed, 55 insertions, 0 deletions
diff --git a/jstests/aggregation/bugs/lookup_unwind_getmore.js b/jstests/aggregation/bugs/lookup_unwind_getmore.js
new file mode 100644
index 00000000000..e15e4155136
--- /dev/null
+++ b/jstests/aggregation/bugs/lookup_unwind_getmore.js
@@ -0,0 +1,55 @@
+/**
+ * Tests that the server correctly handles when the OperationContext of the DBDirectClient used by
+ * the $lookup stage changes as it unwinds the results.
+ *
+ * This test was designed to reproduce SERVER-22537.
+ */
+(function() {
+ 'use strict';
+
+ // We use a batch size of 1 to ensure that the mongo shell issues a getMore when unwinding the
+ // results from the 'dest' collection for the same document in the 'source' collection under a
+ // different OperationContext.
+ const batchSize = 1;
+
+ db.source.drop();
+ db.dest.drop();
+
+ assert.writeOK(db.source.insert({local: 1}));
+
+ // We insert documents in the 'dest' collection such that their combined size is greater than
+ // 16MB in order to ensure that the DBDirectClient used by the $lookup stage issues a getMore
+ // under a different OperationContext.
+ const numMatches = 3;
+ const largeStr = new Array(6 * 1024 * 1024 + 1).join('x');
+
+ for (var i = 0; i < numMatches; ++i) {
+ assert.writeOK(db.dest.insert({foreign: 1, largeStr: largeStr}));
+ }
+
+ var res = db.runCommand({
+ aggregate: 'source',
+ pipeline: [
+ {
+ $lookup: {
+ from: 'dest',
+ localField: 'local',
+ foreignField: 'foreign',
+ as: 'matches',
+ }
+ },
+ {
+ $unwind: {
+ path: '$matches',
+ },
+ },
+ ],
+ cursor: {
+ batchSize: batchSize,
+ },
+ });
+ assert.commandWorked(res);
+
+ var cursor = new DBCommandCursor(db.getMongo(), res, batchSize);
+ assert.eq(numMatches, cursor.itcount());
+})();