Vincit / objection.js

An SQL-friendly ORM for Node.js
https://vincit.github.io/objection.js
MIT License
7.23k stars 638 forks source link

SQL clause precedence? #55

Closed theganyo closed 8 years ago

theganyo commented 8 years ago

I'm having an issue with precedence of SQL statements. I have something like this:

  Resource
    .query()
    .first()
    .where('id', id)
    .whereJsonSupersetOf('data:permissions', [{ actor: user.id, action: action }])
    .orWhereJsonSupersetOf('data:permissions', [{ actor: user2.id, action: action }])

Which emits SQL like this:

select * from "Resource" where "folderId" = ? and ( "data"#>'{permissions}' )::jsonb @> ?::jsonb or ( "data"#>'{permissions}' )::jsonb @> ?::jsonb

But that's not quite correct... I really need parenthesis around the JSON permission checks. In other words, I'd like to see the ultimate SQL look like this:

select * from "Resource" where "folderId" = ? and ( ( "data"#>'{permissions}' )::jsonb @> ?::jsonb or ( "data"#>'{permissions}' )::jsonb @> ?::jsonb )

Is there a way to force precedence / add parentheses?

Thanks! Scott

koskimas commented 8 years ago

Have you tried this:

  Resource
    .query()
    .first()
    .where('id', id)
    .where(function (builder) {
      builder
        .whereJsonSupersetOf('data:permissions', [{ actor: user.id, action: action }])
        .orWhereJsonSupersetOf('data:permissions', [{ actor: user2.id, action: action }]);
    });

You can add parentheses using functions like this.

theganyo commented 8 years ago

No, I hadn't. It works like a champ! Thanks so much! Was that documented and I just missed it?

koskimas commented 8 years ago

No, not really :D. The documentation is a bit crap at the moment, but I'm writing a new one as we speak. It is documented in knex.js documentation. Objection.js query builder attempts to be 100% compatible with knex query builder, so you can always use knex's docs.

theganyo commented 8 years ago

Ah. I actually did look at Knex docs as well, but I missed that "Grouped Chain" means precedence. :)

Thanks again!