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

doesNotMatchKeyInQuery and equalTo doesn't work in single query if used for same column #3678

Closed
xor22h opened this issue Mar 30, 2017 · 14 comments
Labels
type:bug Impaired feature or lacking behavior that is likely assumed

Comments

@xor22h
Copy link

xor22h commented Mar 30, 2017

Issue Description

Trying to make query by using doesNotMatchKeyInQuery() and equalTo() on same column fails to produce correct output;

Steps to reproduce

 var query = new Parse.Query("Posts");
 query.equalTo("author", SOME_USER_POINTER);

var banListQuery = new Parse.Query("UserBlockList");
banListQuery.equalTo("blockedUser", req.user);

query.doesNotMatchKeyInQuery("author", "blockedBy", banListQuery);
query.include("author");
query.find();

Expected Results

Return post of user provided in equalTo() only if requester (req.user) is not blocked by post author;

Actual Outcome

equalTo() takes bigger priority and post is returned even if post author has req.user blocked;
Note: not having equalTo() seems to work correctly, blocked users don't see the content;

Environment Setup

  • Server

    • parse-server version (Be specific! Don't say 'latest'.) : 2.3.7
    • Operating System: Ubuntu 16.04
    • Hardware: 8 x Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz (1 Socket), 8GB Ram
    • Localhost or remote server? (AWS, Heroku, Azure, Digital Ocean, etc): Remote server at OVH
  • Database

    • MongoDB version: 3.2.12
    • Storage engine: wiredTiger
    • Hardware: 8 x Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz (1 Socket), 12GB Ram
    • Localhost or remote server? (AWS, mLab, ObjectRocket, Digital Ocean, etc): OVH

Logs/Trace

Include all relevant logs. You can turn on additional logging by configuring VERBOSE=1 in your environment.

@xor22h
Copy link
Author

xor22h commented Mar 30, 2017

Failing test

it("dontSelect and equalTo (#3678)", function(done) {
    var AuthorObject = Parse.Object.extend("Author");
    var BlockedObject = Parse.Object.extend("Blocked");
    var PostObject = Parse.Object.extend("Post");

    var postAuthor = null;
    var requestUser = null;

    return new AuthorObject({ name: "Julius"}).save().then((user) => {
      postAuthor = user;
      return new AuthorObject({ name: "Bob"}).save();
    }).then((user) => {
      requestUser = user;
      var objects = [
        new PostObject({ author: postAuthor, title: "Lorem ipsum" }),
        new PostObject({ author: requestUser, title: "Kafka" }),
        new PostObject({ author: requestUser, title: "Brown fox" }),
        new BlockedObject({ blockedBy: postAuthor, blockedUser: requestUser})
      ];
      return Parse.Object.saveAll(objects);
    }).then(() => {
      var banListQuery = new Parse.Query(BlockedObject);
      banListQuery.equalTo("blockedUser", requestUser);

      return new Parse.Query(PostObject)
        .equalTo("author", postAuthor)
        .doesNotMatchKeyInQuery("author", "blockedBy", banListQuery)
        .find()
        .then((r) => {
          expect(r.length).toEqual(0);
          done();
        }, done.fail);
    })
  });

@flovilmart
Copy link
Contributor

can you open a PR with the failing test? This will help design the fix.

Do you think you can take the fix on?

@xor22h
Copy link
Author

xor22h commented Mar 30, 2017

#3679

@xor22h
Copy link
Author

xor22h commented Mar 31, 2017

It seems that the test passed with postgresql database.

@flovilmart
Copy link
Contributor

Yes, that helps pin-pointing the issue in the adapter and not in an upper layer

@xor22h
Copy link
Author

xor22h commented Apr 5, 2017

@flovilmart any help on start hunting this issue by myself? Where should i start? :) Haven't found a place where it sets $dontSelect to a query;

@xor22h
Copy link
Author

xor22h commented Apr 5, 2017

Also, as we have failing test (not merged yet) maybe we should add BUG label to this issue?

@flovilmart flovilmart added the type:bug Impaired feature or lacking behavior that is likely assumed label Apr 5, 2017
@flovilmart
Copy link
Contributor

Yep most likely.

The issue may be isolated in that method: transformWhere which is responsible for transforming the REST query format to the mongo query format.

As you've shown, the query seems to be properly issued on postgres which makes me think it has to be in there.

@xor22h
Copy link
Author

xor22h commented Apr 7, 2017

It seems the problem might be in RestQuery, not in transformWhere. As transformWhere already receives wrong payload.

RestQuery is actually executing subquery, and adding results to $nin for doesNotMatchKeyInQuery() (pretty much replacing this call with notContainedIn()); Problem is having $eq on same column is handled in wrong way;

If i change .equalTo("author", postAuthor) to .containedIn("author", [postAuthor]) inside test code, it works fine and test passes. (query becomes:

{ '$in': 
   [ { __type: 'Pointer',
       className: 'Author',
       objectId: '7soWP64fAS' } ],
  '$nin': 
   [ { __type: 'Pointer',
       className: 'Author',
       objectId: '7soWP64fAS' } ] }

where with equalTo() it's

{ __type: 'Pointer',
  className: 'Author',
  objectId: 'lP4BRmfU2Q',
  '$nin': 
   [ { __type: 'Pointer',
       className: 'Author',
       objectId: 'lP4BRmfU2Q' } ] }

@flovilmart
Copy link
Contributor

do you have the original payload? if it's probably just a matter of making sure we have:

{ '$eq': { __type: 'Pointer',
  className: 'Author',
  objectId: 'lP4BRmfU2Q' },
  '$nin': 
   [ { __type: 'Pointer',
       className: 'Author',
       objectId: 'lP4BRmfU2Q' } ] }

@khawtf
Copy link

khawtf commented Apr 12, 2017

@flovilmart
Copy link
Contributor

Not sure it's the same issue, this one is when mixing match and equality in the same query. One constraint gets overrides

@khawtf
Copy link

khawtf commented Apr 12, 2017

Hmm looked again. It looks like a comparison between a string(objectId) and a pointer. (Deal)
That is more a new feature then a bug I think.

Out of curiosity I have no clue how such a query would be solved. There is no way you could do a dot notation inside a LinQ statement right

@flovilmart
Copy link
Contributor

So there is also a bug in the JS SDK, is should replace 'key': object with 'key': {$eq: 'object'}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type:bug Impaired feature or lacking behavior that is likely assumed
Projects
None yet
Development

No branches or pull requests

3 participants