Fixed #15823 - incorrect join condition when combining Q objects
Thanks to dcwatson for the excellent report and patch. git-svn-id: http://code.djangoproject.com/svn/django/trunk@16159 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
970ae01620
commit
db5807bdb1
|
@ -457,7 +457,11 @@ class Query(object):
|
||||||
# An unused alias.
|
# An unused alias.
|
||||||
continue
|
continue
|
||||||
promote = (rhs.alias_map[alias][JOIN_TYPE] == self.LOUTER)
|
promote = (rhs.alias_map[alias][JOIN_TYPE] == self.LOUTER)
|
||||||
new_alias = self.join(rhs.rev_join_map[alias],
|
lhs, table, lhs_col, col = rhs.rev_join_map[alias]
|
||||||
|
# If the left side of the join was already relabeled, use the
|
||||||
|
# updated alias.
|
||||||
|
lhs = change_map.get(lhs, lhs)
|
||||||
|
new_alias = self.join((lhs, table, lhs_col, col),
|
||||||
(conjunction and not first), used, promote, not conjunction)
|
(conjunction and not first), used, promote, not conjunction)
|
||||||
used.add(new_alias)
|
used.add(new_alias)
|
||||||
change_map[alias] = new_alias
|
change_map[alias] = new_alias
|
||||||
|
|
|
@ -31,3 +31,16 @@ class Comment(models.Model):
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.comment_text
|
return self.comment_text
|
||||||
|
|
||||||
|
# Ticket 15823
|
||||||
|
|
||||||
|
class Item(models.Model):
|
||||||
|
title = models.CharField(max_length=100)
|
||||||
|
|
||||||
|
class PropertyValue(models.Model):
|
||||||
|
label = models.CharField(max_length=100)
|
||||||
|
|
||||||
|
class Property(models.Model):
|
||||||
|
item = models.ForeignKey(Item, related_name='props')
|
||||||
|
key = models.CharField(max_length=100)
|
||||||
|
value = models.ForeignKey(PropertyValue, null=True)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
from django.db.models import Q
|
||||||
|
|
||||||
from regressiontests.null_fk.models import *
|
from regressiontests.null_fk.models import *
|
||||||
|
|
||||||
|
@ -40,3 +41,25 @@ class NullFkTests(TestCase):
|
||||||
],
|
],
|
||||||
transform = lambda c: (c.id, c.comment_text, repr(c.post))
|
transform = lambda c: (c.id, c.comment_text, repr(c.post))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_combine_isnull(self):
|
||||||
|
item = Item.objects.create(title='Some Item')
|
||||||
|
pv = PropertyValue.objects.create(label='Some Value')
|
||||||
|
item.props.create(key='a', value=pv)
|
||||||
|
item.props.create(key='b') # value=NULL
|
||||||
|
q1 = Q(props__key='a', props__value=pv)
|
||||||
|
q2 = Q(props__key='b', props__value__isnull=True)
|
||||||
|
|
||||||
|
# Each of these individually should return the item.
|
||||||
|
self.assertEqual(Item.objects.get(q1), item)
|
||||||
|
self.assertEqual(Item.objects.get(q2), item)
|
||||||
|
|
||||||
|
# Logically, qs1 and qs2, and qs3 and qs4 should be the same.
|
||||||
|
qs1 = Item.objects.filter(q1) & Item.objects.filter(q2)
|
||||||
|
qs2 = Item.objects.filter(q2) & Item.objects.filter(q1)
|
||||||
|
qs3 = Item.objects.filter(q1) | Item.objects.filter(q2)
|
||||||
|
qs4 = Item.objects.filter(q2) | Item.objects.filter(q1)
|
||||||
|
|
||||||
|
# Regression test for #15823.
|
||||||
|
self.assertEqual(list(qs1), list(qs2))
|
||||||
|
self.assertEqual(list(qs3), list(qs4))
|
||||||
|
|
Loading…
Reference in New Issue