[Sqlalchemy-tickets] Issue #4248: PostgreSQL: Insufficient parenthesis-wrapping for (boolean) resul
Brought to you by:
zzzeek
From: Robert S. <iss...@bi...> - 2018-05-08 16:39:03
|
New issue 4248: PostgreSQL: Insufficient parenthesis-wrapping for (boolean) result of `IS NULL` https://bitbucket.org/zzzeek/sqlalchemy/issues/4248/postgresql-insufficient-parenthesis Robert Scott: Using sqlalchemy 1.1.4 with postgresql 9.6. The result of an `IS NULL` comparison is a boolean and in postgres it is usable as such - for instance the following works: ``` db=> SELECT (123 IS NULL) = ('blah' IS NULL); ?column? ---------- t (1 row) ``` However the following fails due to operator precedence: ``` db=> SELECT 1 IS NULL = 'blah' IS NULL; ERROR: invalid input syntax for type boolean: "blah" LINE 1: SELECT 1 IS NULL = 'blah' IS NULL; ``` sqlalchemy 1.1.4 unfortunately doesn't include these parentheses: ``` >>> str(db.session.query((User.id == None) == (User.name == None))) 'SELECT users.id IS NULL = users.name IS NULL AS anon_1 \nFROM users' ``` which of course fails in a similar way. Luckily this wrapping *is* performed correctly for the result of equalities: ``` >>> str(db.session.query((User.id == 123) == (User.name == "blah"))) 'SELECT (users.id = %(id_1)s) = (users.name = %(name_1)s) AS anon_1 \nFROM users' ``` and also the workaround of manually casting the result to a boolean works fine: ``` >>> str(db.session.query(db.cast(User.id == None, db.Boolean) == db.cast(User.name == None, db.Boolean))) 'SELECT CAST(users.id IS NULL AS BOOLEAN) = CAST(users.name IS NULL AS BOOLEAN) AS anon_1 \nFROM users' ``` |