Skip to content

Commit

Permalink
feat(aggregation): fail aggregation on explain + readConcern/writeCon…
Browse files Browse the repository at this point in the history
…cern

Aggregation should fail if you try to use the explain flag while you
have a readConcern and/or writeConcern.

BREAKING CHANGE:
If you use aggregation, and try to use the explain flag while you
have a readConcern or writeConcern, your query will fail
  • Loading branch information
daprahamian authored and mbroadst committed Dec 4, 2017
1 parent 40f5872 commit e0ca1b4
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 1 deletion.
7 changes: 6 additions & 1 deletion lib/collection.js
Original file line number Diff line number Diff line change
Expand Up @@ -2475,7 +2475,12 @@ Collection.prototype.aggregate = function(pipeline, options, callback) {
options = getReadPreference(this, options, this.s.db, this);

// If explain has been specified add it
if (options.explain) command.explain = options.explain;
if (options.explain) {
if (command.readConcern || command.writeConcern) {
throw toError('"explain" cannot be used on an aggregate call with readConcern/writeConcern');
}
command.explain = options.explain;
}

if (typeof options.comment === 'string') command.comment = options.comment;

Expand Down
52 changes: 52 additions & 0 deletions test/functional/aggregation_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -942,6 +942,58 @@ describe('Aggregation', function() {
}
});

it('should fail if you try to use explain flag with readConcern/writeConcern', {
metadata: {
requires: {
mongodb: '>3.6.0',
topology: 'single'
}
},

test: function(done) {
var databaseName = this.configuration.db;
var client = this.configuration.newClient(this.configuration.writeConcernMax(), {
poolSize: 1
});

const testCases = [
{readConcern: {level: 'local'}},
{writeConcern: {j: true},},
{readConcern: {level: 'local'}, writeConcern: {j: true}},
];

client.connect(function(err, client) {
const wrapup = (err) => {
client.close();
done(err);
};

const db = client.db(databaseName);

Promise.all(testCases.map((testCase) => {
const stringifiedTestCase = JSON.stringify(testCase);
const collection = db.collection('foo');
Object.assign(collection.s, testCase);
try {
const promise = collection.aggregate([
{$project: {_id: 0}},
{$out: 'bar'}
], {explain: true}).toArray().then(() => {
throw new Error('Expected aggregation to not succeed for options ' + stringifiedTestCase)
}, () => {
throw new Error('Expected aggregation to fail on client instead of server for options ' + stringifiedTestCase)
});

return promise;
} catch (e) {
expect(e).to.exist;
return Promise.resolve();
}
})).then(() => wrapup(), wrapup);
});
}
});

/**
* Correctly call the aggregation framework to return a cursor with batchSize 1 and get the first result using next
*
Expand Down

0 comments on commit e0ca1b4

Please sign in to comment.