summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnssi Kääriäinen <akaariai@gmail.com>2013-02-20 21:52:44 +0200
committerAnssi Kääriäinen <akaariai@gmail.com>2013-02-20 21:57:39 +0200
commit8ad436636fd385abd144274952b0c066885af042 (patch)
tree45d9d45463876519852d971cf71f62c4d620b799
parent8d4342f2c97db93c54a1a5fef26a526caac62df1 (diff)
[1.5.x] Fixed #19672 -- Error in negated Q() filtering
There was a variable overwrite error in negated join filtering. This happened when add_filter() was adding the IS NULL condition to the WHERE clause. This is not a backport from master as there have been some other refactorings which made this patch irrelevant. The patch is from Ian Kelly.
-rw-r--r--django/db/models/sql/query.py8
-rw-r--r--tests/regressiontests/queries/models.py1
-rw-r--r--tests/regressiontests/queries/tests.py12
3 files changed, 15 insertions, 6 deletions
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index 9c2af10e35..e7c8d6caaf 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -1193,15 +1193,15 @@ class Query(object):
self.promote_joins(join_list)
if lookup_type != 'isnull':
if len(join_list) > 1:
- for alias in join_list:
- if self.alias_map[alias].join_type == self.LOUTER:
- j_col = self.alias_map[alias].rhs_join_col
+ for j_alias in join_list:
+ if self.alias_map[j_alias].join_type == self.LOUTER:
+ j_col = self.alias_map[j_alias].rhs_join_col
# The join promotion logic should never produce
# a LOUTER join for the base join - assert that.
assert j_col is not None
entry = self.where_class()
entry.add(
- (Constraint(alias, j_col, None), 'isnull', True),
+ (Constraint(j_alias, j_col, None), 'isnull', True),
AND
)
entry.negate()
diff --git a/tests/regressiontests/queries/models.py b/tests/regressiontests/queries/models.py
index f0178a0256..4ce696c277 100644
--- a/tests/regressiontests/queries/models.py
+++ b/tests/regressiontests/queries/models.py
@@ -64,6 +64,7 @@ class Annotation(models.Model):
class ExtraInfo(models.Model):
info = models.CharField(max_length=100)
note = models.ForeignKey(Note)
+ value = models.IntegerField(null=True)
class Meta:
ordering = ['info']
diff --git a/tests/regressiontests/queries/tests.py b/tests/regressiontests/queries/tests.py
index a6bd2436c1..a2f91e9964 100644
--- a/tests/regressiontests/queries/tests.py
+++ b/tests/regressiontests/queries/tests.py
@@ -51,8 +51,8 @@ class Queries1Tests(BaseQuerysetTest):
# Create these out of order so that sorting by 'id' will be different to sorting
# by 'info'. Helps detect some problems later.
- self.e2 = ExtraInfo.objects.create(info='e2', note=n2)
- e1 = ExtraInfo.objects.create(info='e1', note=self.n1)
+ self.e2 = ExtraInfo.objects.create(info='e2', note=n2, value=41)
+ e1 = ExtraInfo.objects.create(info='e1', note=self.n1, value=42)
self.a1 = Author.objects.create(name='a1', num=1001, extra=e1)
self.a2 = Author.objects.create(name='a2', num=2002, extra=e1)
@@ -880,6 +880,14 @@ class Queries1Tests(BaseQuerysetTest):
Item.objects.filter(Q(tags__name__in=['t4', 't3'])),
[repr(i) for i in Item.objects.filter(~~Q(tags__name__in=['t4', 't3']))])
+ def test_ticket19672(self):
+ self.assertQuerysetEqual(
+ Report.objects.filter(Q(creator__isnull=False) &
+ ~Q(creator__extra__value=41)),
+ ['<Report: r1>']
+ )
+
+
class Queries2Tests(TestCase):
def setUp(self):
Number.objects.create(num=4)