Fixed #21554 -- Incorrect SQL generated when using multiple inheritance.

This commit is contained in:
pegler 2013-12-05 11:46:25 -05:00 committed by Simon Charette
parent b63acdfe71
commit 38e24d680d
3 changed files with 35 additions and 7 deletions

View File

@ -284,25 +284,32 @@ class SQLCompiler(object):
continue continue
alias = self.query.join_parent_model(opts, model, start_alias, alias = self.query.join_parent_model(opts, model, start_alias,
seen_models) seen_models)
column = field.column
for seen_model, seen_alias in seen_models.items():
if seen_model and seen_alias == alias:
ancestor_link = seen_model._meta.get_ancestor_link(model)
if ancestor_link:
column = ancestor_link.column
break
table = self.query.alias_map[alias].table_name table = self.query.alias_map[alias].table_name
if table in only_load and field.column not in only_load[table]: if table in only_load and column not in only_load[table]:
continue continue
if as_pairs: if as_pairs:
result.append((alias, field.column)) result.append((alias, column))
aliases.add(alias) aliases.add(alias)
continue continue
if with_aliases and field.column in col_aliases: if with_aliases and column in col_aliases:
c_alias = 'Col%d' % len(col_aliases) c_alias = 'Col%d' % len(col_aliases)
result.append('%s.%s AS %s' % (qn(alias), result.append('%s.%s AS %s' % (qn(alias),
qn2(field.column), c_alias)) qn2(column), c_alias))
col_aliases.add(c_alias) col_aliases.add(c_alias)
aliases.add(c_alias) aliases.add(c_alias)
else: else:
r = '%s.%s' % (qn(alias), qn2(field.column)) r = '%s.%s' % (qn(alias), qn2(column))
result.append(r) result.append(r)
aliases.add(r) aliases.add(r)
if with_aliases: if with_aliases:
col_aliases.add(field.column) col_aliases.add(column)
return result, aliases return result, aliases
def get_distinct(self): def get_distinct(self):

View File

@ -233,3 +233,17 @@ class User(models.Model):
class Profile(User): class Profile(User):
profile_id = models.AutoField(primary_key=True) profile_id = models.AutoField(primary_key=True)
extra = models.CharField(max_length=30, blank=True) extra = models.CharField(max_length=30, blank=True)
# Check concrete + concrete -> concrete -> concrete
class Politician(models.Model):
politician_id = models.AutoField(primary_key=True)
title = models.CharField(max_length=50)
class Congressman(Person, Politician):
state = models.CharField(max_length=2)
class Senator(Congressman):
pass

View File

@ -15,7 +15,7 @@ from .models import (Place, Restaurant, ItalianRestaurant, ParkingLot,
SelfRefChild, ArticleWithAuthor, M2MChild, QualityControl, DerivedM, SelfRefChild, ArticleWithAuthor, M2MChild, QualityControl, DerivedM,
Person, BirthdayParty, BachelorParty, MessyBachelorParty, Person, BirthdayParty, BachelorParty, MessyBachelorParty,
InternalCertificationAudit, BusStation, TrainStation, User, Profile, InternalCertificationAudit, BusStation, TrainStation, User, Profile,
ParkingLot4A, ParkingLot4B) ParkingLot4A, ParkingLot4B, Senator)
class ModelInheritanceTest(TestCase): class ModelInheritanceTest(TestCase):
@ -455,3 +455,10 @@ class ModelInheritanceTest(TestCase):
# used in the qs and top contains direct pointer to the bottom model. # used in the qs and top contains direct pointer to the bottom model.
qs = ItalianRestaurant.objects.values_list('serves_gnocchi').filter(name='foo') qs = ItalianRestaurant.objects.values_list('serves_gnocchi').filter(name='foo')
self.assertEqual(str(qs.query).count('JOIN'), 1) self.assertEqual(str(qs.query).count('JOIN'), 1)
def test_issue_21554(self):
senator = Senator.objects.create(
name='John Doe', title='X', state='Y'
)
Senator.objects.get(pk=senator.pk)