summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnssi Kääriäinen <anssi.kaariainen@thl.fi>2015-04-16 08:39:31 +0300
committerTim Graham <timograham@gmail.com>2015-04-16 09:32:23 -0400
commitc3a9820251ab06bbe491f11f3112031fb2dad8bd (patch)
treed4c8db01bd8130ab6b0fd16d9375da38710bc63a
parentbcb536004a0c6a60c8c45c28c0a3127ba2321278 (diff)
[1.7.x] Fixed #24605 -- Fixed incorrect reference to alias in subquery.
Thanks to charettes and priidukull for investigating the issue, and to kurevin for the report. Backport of 355c5edd9390caad5725375abca03460805f663b from master
-rw-r--r--django/db/models/sql/compiler.py3
-rw-r--r--docs/releases/1.7.8.txt8
-rw-r--r--tests/queries/models.py15
-rw-r--r--tests/queries/tests.py62
4 files changed, 67 insertions, 21 deletions
diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py
index 90ac90f9ae..e938253145 100644
--- a/django/db/models/sql/compiler.py
+++ b/django/db/models/sql/compiler.py
@@ -56,7 +56,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)
diff --git a/docs/releases/1.7.8.txt b/docs/releases/1.7.8.txt
index 0e5255048a..912171f8da 100644
--- a/docs/releases/1.7.8.txt
+++ b/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`).
diff --git a/tests/queries/models.py b/tests/queries/models.py
index 6e6a0ce5e1..e86793dafd 100644
--- a/tests/queries/models.py
+++ b/tests/queries/models.py
@@ -690,3 +690,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(default=False)
+
+ class Meta:
+ db_table = 'Individual'
+
+
+class RelatedIndividual(models.Model):
+ related = models.ForeignKey(Individual, related_name='related_individual')
+
+ class Meta:
+ db_table = 'RelatedIndividual'
diff --git a/tests/queries/tests.py b/tests/queries/tests.py
index 1c3dd2adda..47eb3c1839 100644
--- a/tests/queries/tests.py
+++ b/tests/queries/tests.py
@@ -1,35 +1,37 @@
from __future__ import unicode_literals
-from collections import OrderedDict
import datetime
-from operator import attrgetter
import pickle
import unittest
import warnings
+from collections import OrderedDict
+from operator import attrgetter
from django.core.exceptions import FieldError
-from django.db import connection, DEFAULT_DB_ALIAS
-from django.db.models import Count, F, Q
-from django.db.models.sql.where import WhereNode, EverythingNode, NothingNode
+from django.db import DEFAULT_DB_ALIAS, connection
+from django.db.models import F, Q, Count
from django.db.models.sql.datastructures import EmptyResultSet
+from django.db.models.sql.where import EverythingNode, NothingNode, WhereNode
from django.test import TestCase, skipUnlessDBFeature
-from django.test.utils import str_prefix, CaptureQueriesContext
+from django.test.utils import CaptureQueriesContext, str_prefix
from django.utils import six
from django.utils.six.moves import range
from .models import (
- Annotation, Article, Author, Celebrity, Child, Cover, Detail, DumbCategory,
- ExtraInfo, Fan, Item, LeafA, Join, LeafB, LoopX, LoopZ, ManagedModel,
- Member, NamedCategory, Note, Number, Plaything, PointerA, Ranking, Related,
- Report, ReservedName, Tag, TvChef, Valid, X, Food, Eaten, Node, ObjectA,
- ObjectB, ObjectC, CategoryItem, SimpleCategory, SpecialCategory,
- OneToOneCategory, NullableName, ProxyCategory, SingleObject, RelatedObject,
- ModelA, ModelB, ModelC, ModelD, Responsibility, Job, JobResponsibilities,
- BaseA, FK1, Identifier, Program, Channel, Page, Paragraph, Chapter, Book,
- MyObject, Order, OrderItem, SharedConnection, Task, Staff, StaffUser,
- CategoryRelationship, Ticket21203Parent, Ticket21203Child, Person,
- Company, Employment, CustomPk, CustomPkTag, Classroom, School, Student,
- Ticket23605A, Ticket23605B, Ticket23605C)
+ FK1, X, Annotation, Article, Author, BaseA, Book, CategoryItem,
+ CategoryRelationship, Celebrity, Channel, Chapter, Child, Classroom,
+ Company, Cover, CustomPk, CustomPkTag, Detail, DumbCategory, 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, Ranking, Related, RelatedIndividual, RelatedObject, Report,
+ ReservedName, Responsibility, School, SharedConnection, SimpleCategory,
+ SingleObject, SpecialCategory, Staff, StaffUser, Student, Tag, Task,
+ Ticket21203Child, Ticket21203Parent, Ticket23605A, Ticket23605B,
+ Ticket23605C, TvChef, Valid,
+)
class BaseQuerysetTest(TestCase):
@@ -3448,3 +3450,27 @@ class Ticket23605Tests(TestCase):
self.assertQuerysetEqual(qs1, [a1], lambda x: x)
qs2 = Ticket23605A.objects.exclude(complex_q)
self.assertQuerysetEqual(qs2, [a2], lambda x: x)
+
+
+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
+ )