Skip to content

Queries on relation fields with multiple ins do not work correctly. #1271

Closed
@jyoon17

Description

@jyoon17

For implementation related questions or technical support, please refer to the Stack Overflow and Server Fault communities.

Make sure these boxes are checked before submitting your issue -- thanks for reporting issues back to Parse Server!

Steps to reproduce

  • See "queries on relation fields with multiple ins" case in ParseRelation.spec.js

    • The expected number of results must be zero not two. The case is incorrect.
    it("queries on relation fields with multiple ins", (done) => {
        var ChildObject = Parse.Object.extend("ChildObject");
        var childObjects = [];
        for (var i = 0; i < 10; i++) {
          childObjects.push(new ChildObject({x: i}));
        }
    
        Parse.Object.saveAll(childObjects).then(() => {
          var ParentObject = Parse.Object.extend("ParentObject");
          var parent = new ParentObject();
          parent.set("x", 4);
          var relation = parent.relation("child");
          relation.add(childObjects[0]);
          relation.add(childObjects[1]);
          relation.add(childObjects[2]);
          var parent2 = new ParentObject();
          parent2.set("x", 3);
          var relation2 = parent2.relation("child");
          relation2.add(childObjects[4]);
          relation2.add(childObjects[5]);
          relation2.add(childObjects[6]);
    
          var otherChild2 = parent2.relation("otherChild");
          otherChild2.add(childObjects[0]);
          otherChild2.add(childObjects[1]);
          otherChild2.add(childObjects[2]);
    
          var parents = [];
          parents.push(parent);
          parents.push(parent2);
          return Parse.Object.saveAll(parents);
        }).then(() => {
          var query = new Parse.Query(ParentObject);
          var objects = [];
          objects.push(childObjects[0]);
          query.containedIn("child", objects);
          query.containedIn("otherChild", [childObjects[0]]);
          return query.find();
        }).then((list) => {
          equal(list.length, 2, "There should be 2 results");
          done();
        });
      });

Logs/Trace

  • The actual REST request generated by the case

    {
      "where": {
        "child": {
          "$in": [
            {
              "__type": "Pointer",
              "className": "ChildObject",
              "objectId": "t4EmF6vnq5"
            }
          ]
        },
        "otherChild": {
          "$in": [
            {
              "__type": "Pointer",
              "className": "ChildObject",
              "objectId": "t4EmF6vnq5"
            }
          ]
        }
      },
      "_method": "GET"
    }

Causes

DatabaseController.prototype.addInObjectIdsIds = function(ids, query) {
  if (typeof query.objectId == 'string') {
    // Add equality op as we are sure
    // we had a constraint on that one
    query.objectId = {'$eq': query.objectId};
  }
  query.objectId = query.objectId || {};
  let queryIn =  [].concat(query.objectId['$in'] || [], ids || []);
  // make a set and spread to remove duplicates
  // replace the $in operator as other constraints
  // may be set
  query.objectId['$in'] = [...new Set(queryIn)];

  return query;
}
  • multiple $ins on different relation fields end up having a merged $in on objectId

    {
      "child": {
        "$in": [
          "pointer to child0"
        ]
      },
      "otherChild": {
        "$in": [
          "pointer to child0"
        ]
      }
    }

    becomes

    {
      "objectId": {
        "$in": [
          "objectId of parent",
          "objectId of parent2"
        ]
      }
    }

    It is supposed to be like

    {
      "$and": [
        {
          "objectId": {
            "$in": [
              "objectId of parent"
            ]
          }
        },
        {
          "objectId": {
            "$in": [
              "objectId of parent2"
            ]
          }
        }
      ]
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions