Commit 355c5edd authored by Anssi Kääriäinen's avatar Anssi Kääriäinen Committed by Tim Graham
Browse files

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

Thanks to charettes and priidukull for investigating the issue, and to
kurevin for the report.
parent 8ca9bc5e
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -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
        )