浏览代码

Fixed #24605 -- Fixed incorrect reference to alias in subquery.

Thanks to charettes and priidukull for investigating the issue, and to
kurevin for the report.
Anssi Kääriäinen 10 年之前
父节点
当前提交
355c5edd93
共有 5 个文件被更改,包括 55 次插入9 次删除
  1. 2 1
      django/db/models/sql/compiler.py
  2. 6 2
      docs/releases/1.7.8.txt
  3. 2 0
      docs/releases/1.8.1.txt
  4. 15 0
      tests/queries/models.py
  5. 30 6
      tests/queries/tests.py

+ 2 - 1
django/db/models/sql/compiler.py

@@ -347,7 +347,8 @@ class SQLCompiler(object):
         if name in self.quote_cache:
             return self.quote_cache[name]
         if ((name in self.query.alias_map and name not in self.query.table_map) or
-                name in self.query.extra_select or name in self.query.external_aliases):
+                name in self.query.extra_select or (
+                    name in self.query.external_aliases and name not in self.query.table_map)):
             self.quote_cache[name] = name
             return name
         r = self.connection.ops.quote_name(name)

+ 6 - 2
docs/releases/1.7.8.txt

@@ -4,5 +4,9 @@ Django 1.7.8 release notes
 
 *Under development*
 
-Django 1.7.8 fixes database introspection with SQLite 3.8.9 (released April 8,
-2015) (:ticket:`24637`).
+Django 1.7.8 fixes:
+
+* Database introspection with SQLite 3.8.9 (released April 8, 2015)
+  (:ticket:`24637`).
+
+* A database table name quoting regression in 1.7.2 (:ticket:`24605`).

+ 2 - 0
docs/releases/1.8.1.txt

@@ -53,3 +53,5 @@ Bugfixes
 * Fixed queries where an expression was referenced in ``order_by()``, but wasn't
   part of the select clause. An example query is
   ``qs.annotate(foo=F('field')).values('pk').order_by('foo'))`` (:ticket:`24615`).
+
+* Fixed a database table name quoting regression (:ticket:`24605`).

+ 15 - 0
tests/queries/models.py

@@ -713,3 +713,18 @@ class Ticket23605B(models.Model):
 
 class Ticket23605C(models.Model):
     field_c0 = models.FloatField()
+
+
+# db_table names have capital letters to ensure they are quoted in queries.
+class Individual(models.Model):
+    alive = models.BooleanField()
+
+    class Meta:
+        db_table = 'Individual'
+
+
+class RelatedIndividual(models.Model):
+    related = models.ForeignKey(Individual, related_name='related_individual')
+
+    class Meta:
+        db_table = 'RelatedIndividual'

+ 30 - 6
tests/queries/tests.py

@@ -21,16 +21,16 @@ from .models import (
     FK1, X, Annotation, Article, Author, BaseA, Book, CategoryItem,
     CategoryRelationship, Celebrity, Channel, Chapter, Child, ChildObjectA,
     Classroom, Company, Cover, CustomPk, CustomPkTag, Detail, DumbCategory,
-    Eaten, Employment, ExtraInfo, Fan, Food, Identifier, Item, Job,
+    Eaten, Employment, ExtraInfo, Fan, Food, Identifier, Individual, Item, Job,
     JobResponsibilities, Join, LeafA, LeafB, LoopX, LoopZ, ManagedModel,
     Member, ModelA, ModelB, ModelC, ModelD, MyObject, NamedCategory, Node,
     Note, NullableName, Number, ObjectA, ObjectB, ObjectC, OneToOneCategory,
     Order, OrderItem, Page, Paragraph, Person, Plaything, PointerA, Program,
-    ProxyCategory, ProxyObjectA, ProxyObjectB, Ranking, Related, RelatedObject,
-    Report, ReservedName, Responsibility, School, SharedConnection,
-    SimpleCategory, SingleObject, SpecialCategory, Staff, StaffUser, Student,
-    Tag, Task, Ticket21203Child, Ticket21203Parent, Ticket23605A, Ticket23605B,
-    Ticket23605C, TvChef, Valid,
+    ProxyCategory, ProxyObjectA, ProxyObjectB, Ranking, Related,
+    RelatedIndividual, RelatedObject, Report, ReservedName, Responsibility,
+    School, SharedConnection, SimpleCategory, SingleObject, SpecialCategory,
+    Staff, StaffUser, Student, Tag, Task, Ticket21203Child, Ticket21203Parent,
+    Ticket23605A, Ticket23605B, Ticket23605C, TvChef, Valid,
 )
 
 
@@ -3690,3 +3690,27 @@ class TestInvalidValuesRelation(TestCase):
             Annotation.objects.filter(tag='abc')
         with self.assertRaises(ValueError):
             Annotation.objects.filter(tag__in=[123, 'abc'])
+
+
+class TestTicket24605(TestCase):
+    def test_ticket_24605(self):
+        """
+        Subquery table names should be quoted.
+        """
+        i1 = Individual.objects.create(alive=True)
+        RelatedIndividual.objects.create(related=i1)
+        i2 = Individual.objects.create(alive=False)
+        RelatedIndividual.objects.create(related=i2)
+        i3 = Individual.objects.create(alive=True)
+        i4 = Individual.objects.create(alive=False)
+
+        self.assertQuerysetEqual(
+            Individual.objects.filter(Q(alive=False), Q(related_individual__isnull=True)),
+            [i4], lambda x: x
+        )
+        self.assertQuerysetEqual(
+            Individual.objects.exclude(
+                Q(alive=False), Q(related_individual__isnull=True)
+            ).order_by('pk'),
+            [i1, i2, i3], lambda x: x
+        )