Ticket #12890: 12890.Django-1.2.5.diff

File 12890.Django-1.2.5.diff, 5.5 KB (added by daveycrockett, 13 years ago)

Patch with fix and test case (for v1.2.5)

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

    diff -ur Django-1.2.5/django/db/models/sql/compiler.py Django-1.2.5-patched/django/db/models/sql/compiler.py
    old new  
    449449                result.append('%s%s%s' % (connector, qn(name), alias_str))
    450450            first = False
    451451        for t in self.query.extra_tables:
    452             alias, unused = self.query.table_alias(t)
     452            alias, unused = self.query.table_alias(t, True)
    453453            # Only add the alias if it's not already present (the table_alias()
    454454            # calls increments the refcount, so an alias refcount of one means
    455455            # this is the only reference.
    456456            if alias not in self.query.alias_map or self.query.alias_refcount[alias] == 1:
    457457                connector = not first and ', ' or ''
    458                 result.append('%s%s' % (connector, qn(alias)))
     458                alias_str = (alias != t and ' %s' % alias or '')
     459                result.append('%s%s%s' % (connector, qn(t), alias_str))
    459460                first = False
    460461        return result, []
    461462
  • django/db/models/sql/query.py

    diff -ur Django-1.2.5/django/db/models/sql/query.py Django-1.2.5-patched/django/db/models/sql/query.py
    old new  
    629629
    630630        # Create a new alias for this table.
    631631        if current:
    632             alias = '%s%d' % (self.alias_prefix, len(self.alias_map) + 1)
     632            alias = '%s%d' % (self.alias_prefix, sum([len(li) for li in self.table_map.values()]) + 1)
    633633            current.append(alias)
    634634        else:
    635635            # The first occurence of a table uses the table name directly.
  • tests/regressiontests/queries/models.py

    diff -ur Django-1.2.5/tests/regressiontests/queries/models.py Django-1.2.5-patched/tests/regressiontests/queries/models.py
    old new  
    294294
    295295    def __unicode__(self):
    296296        return u"%s" % self.num
     297   
     298class NestedNode(models.Model):
     299    lft = models.IntegerField()
     300    rght = models.IntegerField()
     301    name = models.CharField(max_length=100)
     302    parent = models.ForeignKey("self", null=True)
     303 No newline at end of file
  • tests/regressiontests/queries/tests.py

    diff -ur Django-1.2.5/tests/regressiontests/queries/tests.py Django-1.2.5-patched/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, NestedNode)
    1818
    1919
    2020class BaseQuerysetTest(TestCase):
     
    16501650                Number.objects.filter(num__in=numbers).count(),
    16511651                2500
    16521652            )
     1653
     1654class ExtraTablesTest(TestCase):
     1655    def test_ticket12890(self):
     1656        """
     1657            This tests that self-joins, using extra(tables=...) work properly.
     1658            In the below example, a simple nested set model is used
     1659            (http://en.wikipedia.org/wiki/Nested_set_model), and the number
     1660            of children of each root node (including the node itself) are
     1661            calculated.
     1662           
     1663            If the aliasing doesn't work properly, this test case will fail
     1664            with an error at the commented line.  The further assertions check
     1665            that the results are also calculated correctly.
     1666        """
     1667        af = NestedNode.objects.create(name='Africa', lft=0, rght=10, parent=None)
     1668        ug = NestedNode.objects.create(name='Uganda', lft=1, rght=3, parent=af)
     1669        kla = NestedNode.objects.create(name='Kampala', lft=2,rght=2,parent=ug)
     1670        rw = NestedNode.objects.create(name='Rwanda', lft=4, rght=4, parent=af)
     1671        tz = NestedNode.objects.create(name='Tanzania', lft=5, rght=9, parent=af)
     1672        zb = NestedNode.objects.create(name='Zanzibar', lft=6, rght=8, parent=tz)
     1673        st = NestedNode.objects.create(name='Stone Town', lft=7, rght=7, parent=zb)
     1674       
     1675        eu = NestedNode.objects.create(name='Europe',lft=11, rght=13,parent=None)
     1676        es = NestedNode.objects.create(name='Spain',lft=12,rght=12,parent=eu)
     1677       
     1678        # The below query will fail with errors unless extra table aliasing is done
     1679        # properly
     1680        extra_query = list(NestedNode.objects\
     1681            .extra(tables=['queries_nestednode'],
     1682                   where=['T2.lft <= queries_nestednode.lft',
     1683                          'T2.rght >= queries_nestednode.rght',
     1684                          'T2.parent_id is NULL'])\
     1685            .extra(select={'continent_name':'T2.name'})\
     1686            .values('continent_name')\
     1687            .annotate(Count('pk')).extra(order_by=['continent_name']))
     1688       
     1689        # make sure the result is correct as well
     1690        self.assertEqual(extra_query[0]['continent_name'], 'Africa')
     1691        self.assertEqual(extra_query[0]['pk__count'], 7)
     1692
     1693        self.assertEqual(extra_query[1]['continent_name'], 'Europe')
     1694        self.assertEqual(extra_query[1]['pk__count'], 2)
Back to Top