Ticket #12252: 12252b.diff
File 12252b.diff, 5.8 KB (added by , 15 years ago) |
---|
-
django/db/models/sql/query.py
407 407 "Cannot combine a unique query with a non-unique query." 408 408 409 409 self.remove_inherited_models() 410 l_tables = set([a for a in self.tables if self.alias_refcount[a]]) 411 r_tables = set([a for a in rhs.tables if rhs.alias_refcount[a]]) 410 412 # Work out how to relabel the rhs aliases, if necessary. 411 413 change_map = {} 412 414 used = set() … … 424 426 first = False 425 427 426 428 # So that we don't exclude valid results in an "or" query combination, 427 # the first join that is exclusive to the lhs (self)must be converted429 # all joins exclusive to either the lhs or the rhs must be converted 428 430 # to an outer join. 429 431 if not conjunction: 430 for alias in self.tables[1:]: 431 if self.alias_refcount[alias] == 1: 432 self.promote_alias(alias, True) 433 break 432 # Update r_tables aliases. 433 for alias in change_map: 434 if alias in r_tables: 435 r_tables.remove(alias) 436 r_tables.add(change_map[alias]) 437 # Find aliases that are exclusive to rhs or lhs. 438 # These are promoted to outer joins. 439 outer_aliases = (l_tables | r_tables) - (l_tables & r_tables) 440 for alias in outer_aliases: 441 self.promote_alias(alias, True) 434 442 435 443 # Now relabel a copy of the rhs where-clause and add it to the current 436 444 # one. -
tests/regressiontests/queries/tests.py
1 1 import unittest 2 from models import Tag, Annotation 3 from django.db.models import Count 2 from models import Tag, Annotation, ObjectA, ObjectB, ObjectC 3 from django.db.models import Count, Q 4 4 5 5 class QuerysetOrderedTests(unittest.TestCase): 6 6 """ … … 24 24 qs = Annotation.objects.annotate(num_notes=Count('notes')) 25 25 self.assertEqual(qs.ordered, False) 26 26 self.assertEqual(qs.order_by('num_notes').ordered, True) 27 28 No newline at end of file 27 28 29 class UnionTests(unittest.TestCase): 30 """ 31 Tests for the union of two querysets. 32 Bug #12252. 33 """ 34 35 def __init__(self, *args, **kwargs): 36 super(UnionTests, self).__init__(*args, **kwargs) 37 38 def setUp(self): 39 # Don't bother setting up if already done 40 if ObjectA.objects.all(): 41 return 42 objectas = [] 43 objectbs = [] 44 objectcs = [] 45 a_info = ['one', 'two', 'three'] 46 for name in a_info: 47 o = ObjectA(name=name) 48 o.save() 49 objectas.append(o) 50 b_info = [('un', 1, objectas[0]), ('deux', 2, objectas[0]), ('trois', 3, objectas[2])] 51 for name, number, objecta in b_info: 52 o = ObjectB(name=name, number=number, objecta=objecta) 53 o.save() 54 objectbs.append(o) 55 c_info = [('ein', objectas[2], objectbs[2]), ('zwei', objectas[1], objectbs[1])] 56 for name, objecta, objectb in c_info: 57 o = ObjectC(name=name, objecta=objecta, objectb=objectb) 58 o.save() 59 objectcs.append(o) 60 61 def check_union(self, model, Q1, Q2): 62 filter = model.objects.filter 63 self.assertEqual(set(filter(Q1) | filter(Q2)), set(filter(Q1 | Q2))) 64 self.assertEqual(set(filter(Q2) | filter(Q1)), set(filter(Q1 | Q2))) 65 66 def test_A_AB(self): 67 Q1 = Q(name='two') 68 Q2 = Q(objectb__name='deux') 69 self.check_union(ObjectA, Q1, Q2) 70 71 def test_A_AB2(self): 72 Q1 = Q(name='two') 73 Q2 = Q(objectb__name='deux', objectb__number=2) 74 self.check_union(ObjectA, Q1, Q2) 75 76 def test_AB_ACB(self): 77 Q1 = Q(objectb__name='deux') 78 Q2 = Q(objectc__objectb__name='deux') 79 self.check_union(ObjectA, Q1, Q2) 80 81 def test_BAB_BAC(self): 82 Q1 = Q(objecta__objectb__name='deux') 83 Q2 = Q(objecta__objectc__name='ein') 84 self.check_union(ObjectB, Q1, Q2) 85 86 def test_BAB_BACB(self): 87 Q1 = Q(objecta__objectb__name='deux') 88 Q2 = Q(objecta__objectc__objectb__name='trois') 89 self.check_union(ObjectB, Q1, Q2) 90 91 def test_BA_BCA__BAB_BAC_BCA(self): 92 Q1 = Q(objecta__name='one', objectc__objecta__name='two') 93 Q2 = Q(objecta__objectc__name='ein', objectc__objecta__name='three', objecta__objectb__name='trois') 94 self.check_union(ObjectB, Q1, Q2) -
tests/regressiontests/queries/models.py
275 275 def __unicode__(self): 276 276 return self.name 277 277 278 # Bug #12252 279 class ObjectA(models.Model): 280 name = models.CharField(max_length=50) 278 281 282 def __unicode__(self): 283 return self.name 284 285 class ObjectB(models.Model): 286 name = models.CharField(max_length=50) 287 objecta = models.ForeignKey(ObjectA) 288 number = models.PositiveSmallIntegerField() 289 290 def __unicode__(self): 291 return self.name 292 293 class ObjectC(models.Model): 294 name = models.CharField(max_length=50) 295 objecta = models.ForeignKey(ObjectA) 296 objectb = models.ForeignKey(ObjectB) 297 298 def __unicode__(self): 299 return self.name 300 301 279 302 __test__ = {'API_TESTS':""" 280 303 >>> # Regression for #13156 -- exists() queries have minimal SQL 281 304 >>> from django.db import connection