diff -ru Django-1.3/django/db/models/sql/compiler.py Django-1.3-patched/django/db/models/sql/compiler.py
--- Django-1.3/django/db/models/sql/compiler.py	2011-06-21 15:30:20.155858552 +0300
+++ Django-1.3-patched/django/db/models/sql/compiler.py	2011-06-21 15:46:53.399857085 +0300
@@ -462,13 +462,14 @@
                 result.append('%s%s%s' % (connector, qn(name), alias_str))
             first = False
         for t in self.query.extra_tables:
-            alias, unused = self.query.table_alias(t)
+            alias, unused = self.query.table_alias(t, True)
             # Only add the alias if it's not already present (the table_alias()
             # calls increments the refcount, so an alias refcount of one means
             # this is the only reference.
             if alias not in self.query.alias_map or self.query.alias_refcount[alias] == 1:
                 connector = not first and ', ' or ''
-                result.append('%s%s' % (connector, qn(alias)))
+                alias_str = (alias != t and ' %s' % alias or '')
+                result.append('%s%s%s' % (connector, qn(t), alias_str))
                 first = False
         return result, []
 
diff -ru Django-1.3/django/db/models/sql/query.py Django-1.3-patched/django/db/models/sql/query.py
--- Django-1.3/django/db/models/sql/query.py	2011-06-21 15:30:20.159858921 +0300
+++ Django-1.3-patched/django/db/models/sql/query.py	2011-06-21 15:47:31.679857341 +0300
@@ -643,7 +643,7 @@
 
         # Create a new alias for this table.
         if current:
-            alias = '%s%d' % (self.alias_prefix, len(self.alias_map) + 1)
+            alias = '%s%d' % (self.alias_prefix, sum([len(li) for li in self.table_map.values()]) + 1)
             current.append(alias)
         else:
             # The first occurence of a table uses the table name directly.
diff -ru Django-1.3/tests/regressiontests/queries/models.py Django-1.3-patched/tests/regressiontests/queries/models.py
--- Django-1.3/tests/regressiontests/queries/models.py	2011-06-21 15:34:07.275858569 +0300
+++ Django-1.3-patched/tests/regressiontests/queries/models.py	2011-06-21 15:48:54.303858636 +0300
@@ -317,3 +317,9 @@
 
     def __unicode__(self):
        return self.name
+   
+class NestedNode(models.Model):
+    lft = models.IntegerField()
+    rght = models.IntegerField()
+    name = models.CharField(max_length=100)
+    parent = models.ForeignKey("self", null=True)
diff -ru Django-1.3/tests/regressiontests/queries/tests.py Django-1.3-patched/tests/regressiontests/queries/tests.py
--- Django-1.3/tests/regressiontests/queries/tests.py	2011-06-21 15:34:07.275858569 +0300
+++ Django-1.3-patched/tests/regressiontests/queries/tests.py	2011-06-21 15:49:21.959359059 +0300
@@ -15,7 +15,7 @@
     DumbCategory, ExtraInfo, Fan, Item, LeafA, LoopX, LoopZ, ManagedModel,
     Member, NamedCategory, Note, Number, Plaything, PointerA, Ranking, Related,
     Report, ReservedName, Tag, TvChef, Valid, X, Food, Eaten, Node, ObjectA, ObjectB,
-    ObjectC)
+    ObjectC, NestedNode)
 
 
 class BaseQuerysetTest(TestCase):
@@ -1735,3 +1735,45 @@
         Q1 = Q(objecta__name='one', objectc__objecta__name='two')
         Q2 = Q(objecta__objectc__name='ein', objectc__objecta__name='three', objecta__objectb__name='trois')
         self.check_union(ObjectB, Q1, Q2)
+
+class ExtraTablesTest(TestCase):
+    def test_ticket12890(self):
+        """
+            This tests that self-joins, using extra(tables=...) work properly.
+            In the below example, a simple nested set model is used
+            (http://en.wikipedia.org/wiki/Nested_set_model), and the number
+            of children of each root node (including the node itself) are
+            calculated.
+            
+            If the aliasing doesn't work properly, this test case will fail
+            with an error at the commented line.  The further assertions check
+            that the results are also calculated correctly.
+        """
+        af = NestedNode.objects.create(name='Africa', lft=0, rght=10, parent=None)
+        ug = NestedNode.objects.create(name='Uganda', lft=1, rght=3, parent=af)
+        kla = NestedNode.objects.create(name='Kampala', lft=2,rght=2,parent=ug)
+        rw = NestedNode.objects.create(name='Rwanda', lft=4, rght=4, parent=af)
+        tz = NestedNode.objects.create(name='Tanzania', lft=5, rght=9, parent=af)
+        zb = NestedNode.objects.create(name='Zanzibar', lft=6, rght=8, parent=tz)
+        st = NestedNode.objects.create(name='Stone Town', lft=7, rght=7, parent=zb)
+        
+        eu = NestedNode.objects.create(name='Europe',lft=11, rght=13,parent=None)
+        es = NestedNode.objects.create(name='Spain',lft=12,rght=12,parent=eu)
+        
+        # The below query will fail with errors unless extra table aliasing is done
+        # properly
+        extra_query = list(NestedNode.objects\
+            .extra(tables=['queries_nestednode'],
+                   where=['T2.lft <= queries_nestednode.lft',
+                          'T2.rght >= queries_nestednode.rght',
+                          'T2.parent_id is NULL'])\
+            .extra(select={'continent_name':'T2.name'})\
+            .values('continent_name')\
+            .annotate(Count('pk')).extra(order_by=['continent_name']))
+        
+        # make sure the result is correct as well
+        self.assertEqual(extra_query[0]['continent_name'], 'Africa')
+        self.assertEqual(extra_query[0]['pk__count'], 7)
+
+        self.assertEqual(extra_query[1]['continent_name'], 'Europe')
+        self.assertEqual(extra_query[1]['pk__count'], 2)
