Fixed #24605 -- Fixed incorrect reference to alias in subquery.
Thanks to charettes and priidukull for investigating the issue, and to kurevin for the report.
This commit is contained in:
parent
8ca9bc5ec3
commit
355c5edd93
|
@ -347,7 +347,8 @@ class SQLCompiler(object):
|
||||||
if name in self.quote_cache:
|
if name in self.quote_cache:
|
||||||
return self.quote_cache[name]
|
return self.quote_cache[name]
|
||||||
if ((name in self.query.alias_map and name not in self.query.table_map) or
|
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
|
self.quote_cache[name] = name
|
||||||
return name
|
return name
|
||||||
r = self.connection.ops.quote_name(name)
|
r = self.connection.ops.quote_name(name)
|
||||||
|
|
|
@ -4,5 +4,9 @@ Django 1.7.8 release notes
|
||||||
|
|
||||||
*Under development*
|
*Under development*
|
||||||
|
|
||||||
Django 1.7.8 fixes database introspection with SQLite 3.8.9 (released April 8,
|
Django 1.7.8 fixes:
|
||||||
2015) (:ticket:`24637`).
|
|
||||||
|
* 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`).
|
||||||
|
|
|
@ -53,3 +53,5 @@ Bugfixes
|
||||||
* Fixed queries where an expression was referenced in ``order_by()``, but wasn't
|
* Fixed queries where an expression was referenced in ``order_by()``, but wasn't
|
||||||
part of the select clause. An example query is
|
part of the select clause. An example query is
|
||||||
``qs.annotate(foo=F('field')).values('pk').order_by('foo'))`` (:ticket:`24615`).
|
``qs.annotate(foo=F('field')).values('pk').order_by('foo'))`` (:ticket:`24615`).
|
||||||
|
|
||||||
|
* Fixed a database table name quoting regression (:ticket:`24605`).
|
||||||
|
|
|
@ -713,3 +713,18 @@ class Ticket23605B(models.Model):
|
||||||
|
|
||||||
class Ticket23605C(models.Model):
|
class Ticket23605C(models.Model):
|
||||||
field_c0 = models.FloatField()
|
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'
|
||||||
|
|
|
@ -21,16 +21,16 @@ from .models import (
|
||||||
FK1, X, Annotation, Article, Author, BaseA, Book, CategoryItem,
|
FK1, X, Annotation, Article, Author, BaseA, Book, CategoryItem,
|
||||||
CategoryRelationship, Celebrity, Channel, Chapter, Child, ChildObjectA,
|
CategoryRelationship, Celebrity, Channel, Chapter, Child, ChildObjectA,
|
||||||
Classroom, Company, Cover, CustomPk, CustomPkTag, Detail, DumbCategory,
|
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,
|
JobResponsibilities, Join, LeafA, LeafB, LoopX, LoopZ, ManagedModel,
|
||||||
Member, ModelA, ModelB, ModelC, ModelD, MyObject, NamedCategory, Node,
|
Member, ModelA, ModelB, ModelC, ModelD, MyObject, NamedCategory, Node,
|
||||||
Note, NullableName, Number, ObjectA, ObjectB, ObjectC, OneToOneCategory,
|
Note, NullableName, Number, ObjectA, ObjectB, ObjectC, OneToOneCategory,
|
||||||
Order, OrderItem, Page, Paragraph, Person, Plaything, PointerA, Program,
|
Order, OrderItem, Page, Paragraph, Person, Plaything, PointerA, Program,
|
||||||
ProxyCategory, ProxyObjectA, ProxyObjectB, Ranking, Related, RelatedObject,
|
ProxyCategory, ProxyObjectA, ProxyObjectB, Ranking, Related,
|
||||||
Report, ReservedName, Responsibility, School, SharedConnection,
|
RelatedIndividual, RelatedObject, Report, ReservedName, Responsibility,
|
||||||
SimpleCategory, SingleObject, SpecialCategory, Staff, StaffUser, Student,
|
School, SharedConnection, SimpleCategory, SingleObject, SpecialCategory,
|
||||||
Tag, Task, Ticket21203Child, Ticket21203Parent, Ticket23605A, Ticket23605B,
|
Staff, StaffUser, Student, Tag, Task, Ticket21203Child, Ticket21203Parent,
|
||||||
Ticket23605C, TvChef, Valid,
|
Ticket23605A, Ticket23605B, Ticket23605C, TvChef, Valid,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -3690,3 +3690,27 @@ class TestInvalidValuesRelation(TestCase):
|
||||||
Annotation.objects.filter(tag='abc')
|
Annotation.objects.filter(tag='abc')
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
Annotation.objects.filter(tag__in=[123, 'abc'])
|
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
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in New Issue