Skip to content

Commit

Permalink
fix(query): correctly handle select('+c') if c is not in schema
Browse files Browse the repository at this point in the history
Fix #7017
  • Loading branch information
vkarpov15 committed Sep 25, 2018
1 parent 5ec10b6 commit 8fea4f8
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 9 deletions.
1 change: 0 additions & 1 deletion lib/query.js
Expand Up @@ -902,7 +902,6 @@ Query.prototype.select = function select() {
fields[field] = include;
userProvidedFields[field] = include;
}

return this;
}

Expand Down
19 changes: 14 additions & 5 deletions lib/queryhelpers.js
Expand Up @@ -241,10 +241,9 @@ exports.applyPaths = function applyPaths(fields, schema) {

analyzeSchema(schema);

let i;
switch (exclude) {
case true:
for (i = 0; i < excluded.length; ++i) {
for (let i = 0; i < excluded.length; ++i) {
fields[excluded[i]] = 0;
}
break;
Expand All @@ -255,14 +254,24 @@ exports.applyPaths = function applyPaths(fields, schema) {
schema.paths['_id'].options.select === false) {
fields._id = 0;
}
for (i = 0; i < selected.length; ++i) {
for (let i = 0; i < selected.length; ++i) {
fields[selected[i]] = 1;
}
break;
case undefined:
if (fields == null) {
break;
}
// Any leftover plus paths must in the schema, so delete them (gh-7017)
for (const key of Object.keys(fields || {})) {
if (key.charAt(0) === '+') {
delete fields[key];
}
}

// user didn't specify fields, implies returning all fields.
// only need to apply excluded fields
for (i = 0; i < excluded.length; ++i) {
// only need to apply excluded fields and delete any plus paths
for (let i = 0; i < excluded.length; ++i) {
fields[excluded[i]] = 0;
}
break;
Expand Down
9 changes: 6 additions & 3 deletions test/schema.select.test.js
Expand Up @@ -397,16 +397,19 @@ describe('schema select option', function() {

return co(function*() {
yield db;
yield db.db.collection('gh7017').insertOne({
yield db.collection('gh7017').insertOne({
a: 'foo',
b: 'bar',
c: 'baz'
});

const doc = yield M.find({}, '+c').then(res => res[0]);
const q = M.find({}).select('+c');
const doc = yield q.then(res => res[0]);
assert.deepEqual(q._fields, { a: 0, b: 0 });

assert.strictEqual(doc.a, void 0);
assert.strictEqual(doc.b, void 0);
assert.equal(doc.c, 'baz');
assert.equal(doc.toObject().c, 'baz');
});
});
});
Expand Down

0 comments on commit 8fea4f8

Please sign in to comment.