Skip to content

Commit 2bbbb3c

Browse files
authoredMay 2, 2023
Merge pull request #13348 from Automattic/vkarpov15/gh-13340
fix(query): apply schema-level paths before calculating projection for findOneAndUpdate()
2 parents 523f6ce + f2cf85a commit 2bbbb3c

File tree

3 files changed

+15
-40
lines changed

3 files changed

+15
-40
lines changed
 

‎lib/query.js

+14-38
Original file line numberDiff line numberDiff line change
@@ -2003,9 +2003,13 @@ Query.prototype._optionsForExec = function(model) {
20032003
}
20042004
}
20052005

2006-
const projection = this._fieldsForExec();
2007-
if (projection != null) {
2008-
options.projection = projection;
2006+
this._applyPaths();
2007+
if (this._fields != null) {
2008+
this._fields = this._castFields(this._fields);
2009+
const projection = this._fieldsForExec();
2010+
if (projection != null) {
2011+
options.projection = projection;
2012+
}
20092013
}
20102014

20112015
return options;
@@ -2258,10 +2262,6 @@ Query.prototype._find = wrapThunk(function(callback) {
22582262

22592263
callback = _wrapThunkCallback(this, callback);
22602264

2261-
this._applyPaths();
2262-
this._fields = this._castFields(this._fields);
2263-
2264-
const fields = this._fieldsForExec();
22652265
const mongooseOptions = this._mongooseOptions;
22662266
const _this = this;
22672267
const userProvidedFields = _this._userProvidedFields || {};
@@ -2276,6 +2276,10 @@ Query.prototype._find = wrapThunk(function(callback) {
22762276
lean: mongooseOptions.lean || null
22772277
});
22782278

2279+
const options = this._optionsForExec();
2280+
const filter = this._conditions;
2281+
const fields = options.projection;
2282+
22792283
const cb = (err, docs) => {
22802284
if (err) {
22812285
return callback(err);
@@ -2317,8 +2321,6 @@ Query.prototype._find = wrapThunk(function(callback) {
23172321
});
23182322
};
23192323

2320-
const options = this._optionsForExec();
2321-
const filter = this._conditions;
23222324

23232325
this._collection.collection.find(filter, options, (err, cursor) => {
23242326
if (err != null) {
@@ -2531,8 +2533,6 @@ Query.prototype._findOne = wrapThunk(function(callback) {
25312533
return null;
25322534
}
25332535

2534-
this._applyPaths();
2535-
this._fields = this._castFields(this._fields);
25362536
applyGlobalMaxTimeMS(this.options, this.model);
25372537
applyGlobalDiskUse(this.options, this.model);
25382538

@@ -3852,17 +3852,6 @@ Query.prototype._findOneAndReplace = wrapThunk(function(callback) {
38523852
const filter = this._conditions;
38533853
const options = this._optionsForExec();
38543854
convertNewToReturnDocument(options);
3855-
let fields = null;
3856-
3857-
this._applyPaths();
3858-
if (this._fields != null) {
3859-
options.projection = this._castFields(utils.clone(this._fields));
3860-
fields = options.projection;
3861-
if (fields instanceof Error) {
3862-
callback(fields);
3863-
return null;
3864-
}
3865-
}
38663855

38673856
const runValidators = _getOption(this, 'runValidators', false);
38683857
if (runValidators === false) {
@@ -3991,7 +3980,6 @@ Query.prototype._findAndModify = function(type, callback) {
39913980
const model = this.model;
39923981
const schema = model.schema;
39933982
const _this = this;
3994-
let fields;
39953983

39963984
const castedQuery = castQuery(this);
39973985
if (castedQuery instanceof Error) {
@@ -4062,18 +4050,6 @@ Query.prototype._findAndModify = function(type, callback) {
40624050
}
40634051
}
40644052

4065-
this._applyPaths();
4066-
if (this._fields) {
4067-
this._fields = this._castFields(this._fields);
4068-
fields = this._fieldsForExec();
4069-
if (fields != null) {
4070-
opts.projection = fields;
4071-
}
4072-
if (opts.projection instanceof Error) {
4073-
return callback(opts.projection);
4074-
}
4075-
}
4076-
40774053
if (opts.sort) convertSortToArray(opts);
40784054

40794055
const cb = function(err, doc, res) {
@@ -5442,6 +5418,9 @@ Query.prototype._castFields = function _castFields(fields) {
54425418
*/
54435419

54445420
Query.prototype._applyPaths = function applyPaths() {
5421+
if (!this.model) {
5422+
return;
5423+
}
54455424
this._fields = this._fields || {};
54465425
helpers.applyPaths(this._fields, this.model.schema);
54475426

@@ -5500,9 +5479,6 @@ Query.prototype._applyPaths = function applyPaths() {
55005479
*/
55015480

55025481
Query.prototype.cursor = function cursor(opts) {
5503-
this._applyPaths();
5504-
this._fields = this._castFields(this._fields);
5505-
55065482
if (opts) {
55075483
this.setOptions(opts);
55085484
}

‎test/model.findOneAndReplace.test.js

-1
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,6 @@ describe('model: findOneAndReplace:', function() {
371371
const schema = new Schema({ name: String, age: { type: Number, select: false } });
372372
const Model = db.model('Test', schema);
373373

374-
375374
const doc = await Model.findOneAndReplace({}, { name: 'Jean-Luc Picard', age: 59 }, {
376375
upsert: true,
377376
returnOriginal: false

‎test/query.test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1268,7 +1268,7 @@ describe('Query', function() {
12681268
const q = new Query();
12691269
q.hint(hint);
12701270

1271-
const options = q._optionsForExec({ schema: { options: {} } });
1271+
const options = q._optionsForExec();
12721272
assert.equal(JSON.stringify(options), a);
12731273
done();
12741274
});

0 commit comments

Comments
 (0)
Please sign in to comment.