Ticket #12252: 12252_1.2.diff

File 12252_1.2.diff, 5.7 KB (added by PhiR, 4 years ago)

patch for 1.2.5 in case anyone needs it (fix is commited in 1.2.X branch)

  • django/db/models/sql/query.py

    diff -ur ../orig/Django-1.2.5/django/db/models/sql/query.py ./django/db/models/sql/query.py
    old new  
    446446            "Cannot combine a unique query with a non-unique query."
    447447
    448448        self.remove_inherited_models()
     449        l_tables = set([a for a in self.tables if self.alias_refcount[a]])
     450        r_tables = set([a for a in rhs.tables if rhs.alias_refcount[a]])
    449451        # Work out how to relabel the rhs aliases, if necessary.
    450452        change_map = {}
    451453        used = set()
     
    463465            first = False
    464466
    465467        # So that we don't exclude valid results in an "or" query combination,
    466         # the first join that is exclusive to the lhs (self) must be converted
     468        # all joins exclusive to either the lhs or the rhs must be converted
    467469        # to an outer join.
    468470        if not conjunction:
    469             for alias in self.tables[1:]:
    470                 if self.alias_refcount[alias] == 1:
    471                     self.promote_alias(alias, True)
    472                     break
     471            # Update r_tables aliases.
     472            for alias in change_map:
     473                if alias in r_tables:
     474                    r_tables.remove(alias)
     475                    r_tables.add(change_map[alias])
     476            # Find aliases that are exclusive to rhs or lhs.
     477            # These are promoted to outer joins.
     478            outer_aliases = (l_tables | r_tables) - (l_tables & r_tables)
     479            for alias in outer_aliases:
     480                self.promote_alias(alias, True)
    473481
    474482        # Now relabel a copy of the rhs where-clause and add it to the current
    475483        # one.
  • tests/regressiontests/queries/models.py

    diff -ur ../orig/Django-1.2.5/tests/regressiontests/queries/models.py ./tests/regressiontests/queries/models.py
    old new  
    294294
    295295    def __unicode__(self):
    296296        return u"%s" % self.num
     297
     298# Bug #12252
     299class ObjectA(models.Model):
     300    name = models.CharField(max_length=50)
     301 
     302    def __unicode__(self):
     303        return self.name
     304
     305class ObjectB(models.Model):
     306    name = models.CharField(max_length=50)
     307    objecta = models.ForeignKey(ObjectA)
     308    number = models.PositiveSmallIntegerField()
     309
     310    def __unicode__(self):
     311        return self.name
     312
     313class ObjectC(models.Model):
     314    name = models.CharField(max_length=50)
     315    objecta = models.ForeignKey(ObjectA)
     316    objectb = models.ForeignKey(ObjectB)
     317
     318    def __unicode__(self):
     319       return self.name
  • tests/regressiontests/queries/tests.py

    diff -ur ../orig/Django-1.2.5/tests/regressiontests/queries/tests.py ./tests/regressiontests/queries/tests.py
    old new  
    1414from models import (Annotation, Article, Author, Celebrity, Child, Cover, Detail,
    1515    DumbCategory, ExtraInfo, Fan, Item, LeafA, LoopX, LoopZ, ManagedModel,
    1616    Member, NamedCategory, Note, Number, Plaything, PointerA, Ranking, Related,
    17     Report, ReservedName, Tag, TvChef, Valid, X, Food, Eaten, Node)
     17    Report, ReservedName, Tag, TvChef, Valid, X, Food, Eaten, Node, ObjectA, ObjectB,
     18    ObjectC)
    1819
    1920
    2021class BaseQuerysetTest(TestCase):
     
    16501651                Number.objects.filter(num__in=numbers).count(),
    16511652                2500
    16521653            )
     1654
     1655class UnionTests(unittest.TestCase):
     1656    """
     1657    Tests for the union of two querysets. Bug #12252.
     1658    """
     1659    def setUp(self):
     1660        objectas = []
     1661        objectbs = []
     1662        objectcs = []
     1663        a_info = ['one', 'two', 'three']
     1664        for name in a_info:
     1665            o = ObjectA(name=name)
     1666            o.save()
     1667            objectas.append(o)
     1668        b_info = [('un', 1, objectas[0]), ('deux', 2, objectas[0]), ('trois', 3, objectas[2])]
     1669        for name, number, objecta in b_info:
     1670            o = ObjectB(name=name, number=number, objecta=objecta)
     1671            o.save()
     1672            objectbs.append(o)
     1673        c_info = [('ein', objectas[2], objectbs[2]), ('zwei', objectas[1], objectbs[1])]
     1674        for name, objecta, objectb in c_info:
     1675            o = ObjectC(name=name, objecta=objecta, objectb=objectb)
     1676            o.save()
     1677            objectcs.append(o)
     1678
     1679    def check_union(self, model, Q1, Q2):
     1680        filter = model.objects.filter
     1681        self.assertEqual(set(filter(Q1) | filter(Q2)), set(filter(Q1 | Q2)))
     1682        self.assertEqual(set(filter(Q2) | filter(Q1)), set(filter(Q1 | Q2)))
     1683
     1684    def test_A_AB(self):
     1685        Q1 = Q(name='two')
     1686        Q2 = Q(objectb__name='deux')
     1687        self.check_union(ObjectA, Q1, Q2)
     1688
     1689    def test_A_AB2(self):
     1690        Q1 = Q(name='two')
     1691        Q2 = Q(objectb__name='deux', objectb__number=2)
     1692        self.check_union(ObjectA, Q1, Q2)
     1693
     1694    def test_AB_ACB(self):
     1695        Q1 = Q(objectb__name='deux')
     1696        Q2 = Q(objectc__objectb__name='deux')
     1697        self.check_union(ObjectA, Q1, Q2)
     1698
     1699    def test_BAB_BAC(self):
     1700        Q1 = Q(objecta__objectb__name='deux')
     1701        Q2 = Q(objecta__objectc__name='ein')
     1702        self.check_union(ObjectB, Q1, Q2)
     1703
     1704    def test_BAB_BACB(self):
     1705        Q1 = Q(objecta__objectb__name='deux')
     1706        Q2 = Q(objecta__objectc__objectb__name='trois')
     1707        self.check_union(ObjectB, Q1, Q2)
     1708
     1709    def test_BA_BCA__BAB_BAC_BCA(self):
     1710        Q1 = Q(objecta__name='one', objectc__objecta__name='two')
     1711        Q2 = Q(objecta__objectc__name='ein', objectc__objecta__name='three', objecta__objectb__name='trois')
     1712        self.check_union(ObjectB, Q1, Q2)
     1713
Back to Top