From e74787391e8fdf87d9a92138028911746809bd7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anssi=20K=C3=A4=C3=A4ri=C3=A4inen?= Date: Sun, 1 Jul 2012 22:49:38 +0300 Subject: [PATCH] Fixed a regression introduced in where.as_sql() refactor At least Oracle needs parentheses in negated where conditions, even if there is only single condition negated. Fixed this by reverting to old logic in that part of as_sql() and adding a comment about this. I did not investigate why the parentheses are needed. The original offending commit was bd283aa844b04651b7c8b4e85f48c6dced1678f0. --- django/db/models/sql/where.py | 9 ++++++--- tests/regressiontests/queries/tests.py | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/django/db/models/sql/where.py b/django/db/models/sql/where.py index 70ff5310f7..827046553d 100644 --- a/django/db/models/sql/where.py +++ b/django/db/models/sql/where.py @@ -135,10 +135,13 @@ class WhereNode(tree.Node): conn = ' %s ' % self.connector sql_string = conn.join(result) if sql_string: - if len(result) > 1: - sql_string = '(%s)' % sql_string if self.negated: - sql_string = 'NOT %s' % sql_string + # Note that some backends (Oracle at least) need the + # parentheses even around single experssion in the + # negated case. + sql_string = 'NOT (%s)' % sql_string + elif len(result) > 1: + sql_string = '(%s)' % sql_string return sql_string, result_params def make_atom(self, child, qn, connection): diff --git a/tests/regressiontests/queries/tests.py b/tests/regressiontests/queries/tests.py index 3d2aafd2d9..9bb3a29430 100644 --- a/tests/regressiontests/queries/tests.py +++ b/tests/regressiontests/queries/tests.py @@ -2091,7 +2091,7 @@ class WhereNodeTest(TestCase): w = WhereNode(children=[NothingNode(), self.DummyNode()], connector='OR') self.assertEquals(w.as_sql(qn, connection), ('dummy', [])) w.negate() - self.assertEquals(w.as_sql(qn, connection), ('NOT dummy', [])) + self.assertEquals(w.as_sql(qn, connection), ('NOT (dummy)', [])) def test_empty_nodes(self): qn = connection.ops.quote_name