Skip to content

Commit

Permalink
fix(query): shallow clone $or, $and if merging onto empty query filter
Browse files Browse the repository at this point in the history
Fix #14567
  • Loading branch information
vkarpov15 committed May 8, 2024
1 parent 88afc33 commit dc588ef
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 4 deletions.
16 changes: 12 additions & 4 deletions lib/query.js
Original file line number Diff line number Diff line change
Expand Up @@ -2380,13 +2380,21 @@ Query.prototype.merge = function(source) {
}

opts.omit = {};
if (this._conditions && this._conditions.$and && source.$and) {
if (source.$and) {
opts.omit['$and'] = true;
this._conditions.$and = this._conditions.$and.concat(source.$and);
if (this._conditions && this._conditions.$and) {
this._conditions.$and = this._conditions.$and.concat(source.$and);
} else {
this._conditions.$and = [...source.$and];
}
}
if (this._conditions && this._conditions.$or && source.$or) {
if (source.$or) {
opts.omit['$or'] = true;
this._conditions.$or = this._conditions.$or.concat(source.$or);
if (this._conditions && this._conditions.$or) {
this._conditions.$or = this._conditions.$or.concat(source.$or);
} else {
this._conditions.$or = [...source.$or];
}
}

// plain object
Expand Down
19 changes: 19 additions & 0 deletions test/query.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4054,6 +4054,25 @@ describe('Query', function() {
});
});

it('shallow clones $and, $or if merging with empty filter (gh-14567) (gh-12944)', function() {
const TestModel = db.model(
'Test',
Schema({ name: String, age: Number, active: Boolean })
);

let originalQuery = { $and: [{ active: true }] };
let q = TestModel.countDocuments(originalQuery)
.and([{ age: { $gte: 18 } }]);
assert.deepStrictEqual(originalQuery, { $and: [{ active: true }] });
assert.deepStrictEqual(q.getFilter(), { $and: [{ active: true }, { age: { $gte: 18 } }] });

originalQuery = { $or: [{ active: true }] };
q = TestModel.countDocuments(originalQuery)
.or([{ age: { $gte: 18 } }]);
assert.deepStrictEqual(originalQuery, { $or: [{ active: true }] });
assert.deepStrictEqual(q.getFilter(), { $or: [{ active: true }, { age: { $gte: 18 } }] });
});

it('should avoid sending empty session to MongoDB server (gh-13052)', async function() {
const m = new mongoose.Mongoose();

Expand Down

0 comments on commit dc588ef

Please sign in to comment.