diff options
author | Max Hirschhorn <max.hirschhorn@mongodb.com> | 2016-02-29 10:47:18 -0500 |
---|---|---|
committer | Ramon Fernandez <ramon@mongodb.com> | 2016-02-29 15:51:07 -0500 |
commit | 139286b38e3d0e1efc1efbe52417310277b3aed8 (patch) | |
tree | 7844849bb0c4830c8fbde163171858142984f90d /jstests/aggregation | |
parent | e7ec5454e1614826e57563c24f94662a44184283 (diff) | |
download | mongo-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.js | 55 |
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()); +})(); |