From c08192ae5b7f43fbdc686ce884857dfa8dd99d11 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Fri, 21 Nov 2008 03:49:36 +0000 Subject: [PATCH] - Comparison of many-to-one relation to NULL is properly converted to IS NOT NULL based on not_(). --- CHANGES | 3 +++ lib/sqlalchemy/orm/strategies.py | 4 +++- test/orm/query.py | 12 +++++++++++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index ef177b5ead..8899d280ae 100644 --- a/CHANGES +++ b/CHANGES @@ -15,6 +15,9 @@ CHANGES - Query.add_column() can accept FromClause objects in the same manner as session.query() can. + - Comparison of many-to-one relation to NULL is + properly converted to IS NOT NULL based on not_(). + - sql - Added NotImplementedError for params() method on Insert/Update/Delete constructs. These items diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py index 156712bc77..58aa71c6aa 100644 --- a/lib/sqlalchemy/orm/strategies.py +++ b/lib/sqlalchemy/orm/strategies.py @@ -392,10 +392,12 @@ class LazyLoader(AbstractRelationLoader): binary.left = binary.right binary.right = expression.null() binary.operator = operators.is_ + binary.negate = operators.isnot elif isinstance(binary.right, expression._BindParamClause) and binary.right.key in bind_to_col: binary.right = expression.null() binary.operator = operators.is_ - + binary.negate = operators.isnot + criterion = visitors.cloned_traverse(criterion, {}, {'binary':visit_binary}) if adapt_source: criterion = adapt_source(criterion) diff --git a/test/orm/query.py b/test/orm/query.py index 34372b83ab..6b74b94175 100644 --- a/test/orm/query.py +++ b/test/orm/query.py @@ -353,7 +353,17 @@ class OperatorTest(QueryTest, AssertsCompiledSQL): self.assert_(compiled == fwd_sql or compiled == rev_sql, "\n'" + compiled + "'\n does not match\n'" + fwd_sql + "'\n or\n'" + rev_sql + "'") - + + def test_negated_null(self): + self._test(User.id == None, "users.id IS NULL") + self._test(~(User.id==None), "users.id IS NOT NULL") + self._test(None == User.id, "users.id IS NULL") + self._test(~(None == User.id), "users.id IS NOT NULL") + self._test(Address.user == None, "addresses.user_id IS NULL") + self._test(~(Address.user==None), "addresses.user_id IS NOT NULL") + self._test(None == Address.user, "addresses.user_id IS NULL") + self._test(~(None == Address.user), "addresses.user_id IS NOT NULL") + def test_relation(self): self._test(User.addresses.any(Address.id==17), "EXISTS (SELECT 1 " -- 2.47.3