diff --git a/spec/RestQuery.spec.js b/spec/RestQuery.spec.js index ca0cec27f4..dd9d3f11f6 100644 --- a/spec/RestQuery.spec.js +++ b/spec/RestQuery.spec.js @@ -719,6 +719,35 @@ describe('RestQuery.each', () => { expect(resultsTwo.length).toBe(1); }); + it('should not throw when a relation query constraint contains null', async () => { + const objectA = new Parse.Object('Letter', { value: 'A' }); + const object1 = new Parse.Object('Number', { value: '1' }); + await object1.save(); + objectA.relation('numbers').add(object1); + await objectA.save(); + + const config = Config.get('test'); + + for (const [restWhere, expectedCount] of [ + [{ numbers: { $in: [null] } }, 0], + [{ numbers: { $nin: [null] } }, 1], + [{ numbers: { $ne: null, $in: [] } }, 0], + [{ numbers: { $ne: null, $nin: [] } }, 1], + [{ numbers: { $in: [null, object1.toPointer()] } }, 1], + ]) { + const query = await RestQuery({ + method: RestQuery.Method.find, + config, + auth: auth.master(config), + className: 'Letter', + restWhere, + }); + const results = []; + await query.each(result => results.push(result)); + expect(results.length).toBe(expectedCount); + } + }); + it('test afterSave response object is return', done => { Parse.Cloud.beforeSave('TestObject2', function (req) { req.object.set('tobeaddbefore', true); diff --git a/src/Controllers/DatabaseController.js b/src/Controllers/DatabaseController.js index 7ddc6e60e4..bfd99c8ee5 100644 --- a/src/Controllers/DatabaseController.js +++ b/src/Controllers/DatabaseController.js @@ -1130,19 +1130,20 @@ class DatabaseController { if (constraintKey === 'objectId') { relatedIds = [query[key].objectId]; } else if (constraintKey == '$in') { - relatedIds = query[key]['$in'].map(r => r.objectId); + relatedIds = query[key]['$in'].map(r => r?.objectId); } else if (constraintKey == '$nin') { isNegation = true; - relatedIds = query[key]['$nin'].map(r => r.objectId); + relatedIds = query[key]['$nin'].map(r => r?.objectId); } else if (constraintKey == '$ne') { isNegation = true; - relatedIds = [query[key]['$ne'].objectId]; + relatedIds = [query[key]['$ne']?.objectId]; } else { return; } return { isNegation, - relatedIds, + // Null operands cannot match a related object + relatedIds: relatedIds.filter(id => id != null), }; }); } else {