Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
3 tasks done
jyoon17 opened this issue Mar 30, 2016 · 2 comments
Closed
3 tasks done

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

jyoon17 opened this issue Mar 30, 2016 · 2 comments

Comments

@jyoon17
Copy link

jyoon17 commented Mar 30, 2016

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"
            ]
          }
        }
      ]
    }
@drew-gross
Copy link
Contributor

I've managed to reproduce this and am working on a fix.

@drew-gross
Copy link
Contributor

PS: thanks a lot for the extremely detailed bug report. I'm going to start pointing to this as a "perfect" bug report.

flovilmart added a commit that referenced this issue Mar 31, 2016
Point to #1271 as how to write a good issue report
flovilmart added a commit that referenced this issue Mar 31, 2016
@HemanParbhakar HemanParbhakar mentioned this issue Dec 24, 2016
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants