Skip to content

Query of type "whereKey matchesKey inQuery" returns 'improper usage of $select' error #371

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

Closed
haparicio opened this issue Feb 12, 2016 · 16 comments · Fixed by #809
Closed
Labels
type:bug Impaired feature or lacking behavior that is likely assumed

Comments

@haparicio
Copy link

Hi.

I've been using a query in a iOS app, that worked fine with parse hosted services,
but after trying with a local parse server it returns the error improper usage of $select error.

For NDA reasons, I had to change the names of the classes, attributes, tokens and keys in this ticket.

This is the query I'm using:

override func queryForTable() -> PFQuery {
    let query = PFQuery(className: "C1");
    let auxQuery = PFQuery(className: "C1");
    query.whereKey("A1", matchesKey: "A2", inQuery: auxQuery);
    query.includeKey("A3");
    query.includeKey("A2");
    query.orderByDescending("createdAt");

    return query;
}

A1 and A2 are pointers to objects of the same type. I tried the same query with simple types,
but the error still happens. If I comment the whereKey line, the query works perfectly and I get my results.

I ran the parse server with VERBOSE=1 and this is what I got:

GET /parse/classes/C1 { host: 'localhost:1337',
  'x-parse-client-version': 'i1.12.0',
  accept: '*/*',
  'x-parse-session-token': 'a-valid-session-token',
  'x-parse-application-id': 'my-application-id',
  'x-parse-client-key': 'my-client-key',
  'x-parse-installation-id': 'my-installation-id',
  'x-parse-os-version': '9.2 (15D21)',
  'accept-language': 'en-us',
  'accept-encoding': 'gzip, deflate',
  'content-type': 'application/json; charset=utf-8',
  'content-length': '169',
  'user-agent': 'projname/1 CFNetwork/758.2.8 Darwin/15.3.0',
  connection: 'keep-alive',
  'x-parse-app-build-version': '1',
  'x-parse-app-display-version': '1.0' } {
  "where": {
    "A1": {
      "$select": {
        "query": {
          "className": "C1"
        },
        "key": "A2"
      }
    }
  },
  "include": "A3,A2",
  "order": "-createdAt",
  "limit": "3"
}
error: ParseError { code: 102, message: 'improper usage of $select' }

After this, I tried running the queries manually with curl requests. I tried querying
my local parse server and the hosted service. This is the result:

> curl -X GET -H "X-Parse-Application-Id: my-application-id"  -H "X-Parse-REST-API-Key: my-rest-api-key"  -G  --data-urlencode 'where={"A1": {"$select": {"query": {"className": "C1"},"key": "A2"}}}' --data-urlencode 'include=A3,A2'  --data-urlencode 'limit=3' --data-urlencode 'order=-createdAt'  http://localhost:1337/parse/classes/C1
{"code":102,"error":"improper usage of $select"}
> curl -X GET -H "X-Parse-Application-Id: my-application-id"  -H "X-Parse-REST-API-Key: my-rest-api-key"  -G  --data-urlencode 'where={"A1": {"$select": {"query": {"className": "C1"},"key": "A2"}}}' --data-urlencode 'include=A3,A2'  --data-urlencode 'limit=3' --data-urlencode 'order=-createdAt'  https://api.parse.com/1/classes/C1
{"results":[{"createdAt":"2016-02-10T22:36:04.828Z","A4":10,"objectId":"sgFcN9g3d5", ...]}}

(This last result is cut short, again to avoid NDA issues, but it's the right result.)

Do you have any idea of what is wrong here?

Thanks in advance.

@haparicio haparicio changed the title whereKey matchesKey inQuery returns improper usage of $select error Query of type whereKey matchesKey inQuery" returns 'improper usage of $select' error Feb 12, 2016
@haparicio haparicio changed the title Query of type whereKey matchesKey inQuery" returns 'improper usage of $select' error Query of type "whereKey matchesKey inQuery" returns 'improper usage of $select' error Feb 12, 2016
@gfosco gfosco added the type:bug Impaired feature or lacking behavior that is likely assumed label Feb 26, 2016
@gfosco
Copy link
Contributor

gfosco commented Feb 26, 2016

This definitely looks like a bug, sorry for the late review... Any chance you can confirm this still occurs with 2.1.3 @haparicio ?

@haparicio
Copy link
Author

Just updated and confirmed that it is still happening. If I can provide any further data that may help you, please let me know.

@flovilmart
Copy link
Contributor

hi @haparicio is it still occurring with the master branch?

@haparicio
Copy link
Author

I was using your parse-server-example to test this, which, from what I saw, already points to the 2.1.3 version of parse-server. I just cloned the parse-server master branch, and ran it as a standalone parse server, pointing to my migrated database.

The problem still seems to be happening. I tried the problematic query, which still returns the same error, and I tried a simpler query (without a where clause), just to make sure I get a result, and it worked fine.

Again, if I can provide any further information, please let me know.

@flovilmart
Copy link
Contributor

hey @haparicio
I just ran that query:

var query = new Parse.Query("C1");
    var auxQuery = new Parse.Query("C2");
    query.matchesKeyInQuery("A1", "A2", auxQuery);
    query.include("A3");
    query.include("A2");
    query.find().then((result) => {
      done();
    }, (err) => {
      console.error(err);
      done();
    })```

that translated to:
``` 
{
    "A1": {
        "$select": {
            "key": "A2",
            "query": {
                "where": {},
                "className": "C2"
            }
        }
    }
}

and it seems to be fine (running master)

@haparicio
Copy link
Author

Your code translates into a different query than the one I mentioned in my original post. I tried your query with curl, and it does seem to be working. However, my swift code (that uses the objective-c parse lib) still translates to the query that I mentioned in my original post. That query works with hosted parse, but not with local parse.

@flovilmart
Copy link
Contributor

Can you post the swift code? what I shared is just the where clause.

@haparicio
Copy link
Author

The query code is the one I mentioned in the original post:

    override func queryForTable() -> PFQuery {
        print("Querying");
        let query = PFQuery(className: "C1");
        let auxQuery = PFQuery(className: "C1");
        query.whereKey("A1", matchesKey: "A2", inQuery: auxQuery);
        query.includeKey("A3");
        query.includeKey("A2");
        query.orderByDescending("createdAt");

        return query;
    }

Other than this, I can add the functions that are required by the PFQueryTableViewController:

    func configureTable() {
        // Configure the PFQueryTableView
        self.parseClassName = "C1";

        self.textKey = "createdAt";
        self.pullToRefreshEnabled = true;
        self.paginationEnabled = true;
        self.objectsPerPage = 3;
    }


    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> PFTableViewCell? {

        var cell = tableView.dequeueReusableCellWithIdentifier("MyCell") as? ParseCell;
        if(cell == nil) {
            let nib = NSBundle.mainBundle().loadNibNamed("MyCell", owner: self, options: nil)
            cell = nib.first as? ParseCell
        }

        cell?.setupCell(indexPath.row, parseObject: object)

        return cell;
    }

The function setupCell just sets the values of the items in my PFTableViewCell.

I also have a query that counts some items:

    func fillC1ItemCount(parseObject: PFObject?) {
        let query = PFQuery(className: "C1");
        let A2Obj = parseObject!["A2"] as! PFObject;
        let C2Obj = parseObject!["A3"] as! PFObject;

        query.whereKey("A3", equalTo: C2Obj);
        query.whereKey("A2", notEqualTo: A2Obj);
        query.countObjectsInBackgroundWithBlock { (count: Int32, error: NSError?) -> Void in
            if(error == nil) {
                // Make sure it's still the same object (user might have scrolled)
                if(parseObject?.objectId != self.cellObjectId) {
                    return;
                }
                self.C1ItemCount.text = String(count);
            }
            else {
                print("Error counting C1 Items: \(error)");
            }
        }
    }

This query runs after the first query I mentioned, and when the problem occurs, I'm almost sure we don't even reach it, so I think it's not relevant. Just posting it here in case I'm wrong.

Is there any other code that you think could be relevant?

@flovilmart
Copy link
Contributor

so this is working for me, not throwing any error:

// JS code
var query = new Parse.Query("C1");
var auxQuery = new Parse.Query("C1");
query.matchesKeyInQuery("A1", "A2", auxQuery);
query.include("A3");
query.include("A2");```

is the exact equivalent of your code. 

What version of parse-server are you using?

@haparicio
Copy link
Author

I'm using a freshly cloned parse-server from the master branch, which is 2.1.3. I also used your parse-server-example which points to the 2.1.3 version. Both have the same result.

The fact that your JS code is equivalent to my swift code, and they translate to different queries, seems to indicate that the objective-c library is doing the wrong translation, and the problem is not in the parse-server. But the strange thing is that the same query that returns the improper usage of $selecterror with the local parse-server, does work with the hosted parse.

I'm not very comfortable with this query language, so I'm not sure if your translation result is supposed to be the same as my translation result, but if it is, I would say the bug (if it's actually a bug) only happens with my translation result.

@flovilmart
Copy link
Contributor

what point do you see is different? the where clause look the same

@haparicio
Copy link
Author

With just the where clause, my query translates into this:

  "where": {
    "A1": {
      "$select": {
        "query": {
          "className": "C1"
        },
        "key": "A2"
      }
    }
  }

While yours, from what you said, translates into this:

"where": {
    "A1": {
        "$select": {
            "key": "A2",
            "query": {
                "where": {},
                "className": "C1"
            }
        }
    }
}

They're exactly the same except for that "where": {} inside the querypart. As i said, this query works for me, but if I just remove this "where": {} part, it returns the error.

Again, I don't know much about this query language, so I'm not sure if that "where": {} part being there or not is the same thing.

@flovilmart
Copy link
Contributor

Oh alright! Thanks for the troubleshooting! I belive this has an error because parse-server interprets the missing where as an error :)

@haparicio
Copy link
Author

Glad to help. :)

If I can help anymore, please let me know.

@flovilmart
Copy link
Contributor

Just had to remove 1 line :)

@haparicio
Copy link
Author

Those are the best fixes. :)
Thanks for everything!

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

Successfully merging a pull request may close this issue.

3 participants