Fixed #20507 -- SubqueryConstraint alias relabeling
The SubqueryConstraint defined relabeled_clone(), but that was never called. Instead there is now clone() and relabel_aliases() methods for SubqueryConstraint. A related problem was that SubqueryConstraint didn't correctly use quote_name_unless_alias() of the outer query. This resulted in failures when running under PostgreSQL.
This commit is contained in:
parent
ae71e3134e
commit
d467e11785
|
@ -786,8 +786,7 @@ class SQLCompiler(object):
|
||||||
return list(result)
|
return list(result)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def as_subquery_condition(self, alias, columns):
|
def as_subquery_condition(self, alias, columns, qn):
|
||||||
qn = self.quote_name_unless_alias
|
|
||||||
qn2 = self.connection.ops.quote_name
|
qn2 = self.connection.ops.quote_name
|
||||||
if len(columns) == 1:
|
if len(columns) == 1:
|
||||||
sql, params = self.as_sql()
|
sql, params = self.as_sql()
|
||||||
|
|
|
@ -408,9 +408,12 @@ class SubqueryConstraint(object):
|
||||||
query.clear_ordering(True)
|
query.clear_ordering(True)
|
||||||
|
|
||||||
query_compiler = query.get_compiler(connection=connection)
|
query_compiler = query.get_compiler(connection=connection)
|
||||||
return query_compiler.as_subquery_condition(self.alias, self.columns)
|
return query_compiler.as_subquery_condition(self.alias, self.columns, qn)
|
||||||
|
|
||||||
def relabeled_clone(self, relabels):
|
def relabel_aliases(self, change_map):
|
||||||
|
self.alias = change_map.get(self.alias, self.alias)
|
||||||
|
|
||||||
|
def clone(self):
|
||||||
return self.__class__(
|
return self.__class__(
|
||||||
relabels.get(self.alias, self.alias),
|
self.alias, self.columns, self.targets,
|
||||||
self.columns, self.query_object)
|
self.query_object)
|
||||||
|
|
|
@ -17,7 +17,7 @@ from django.utils import unittest
|
||||||
from django.utils.datastructures import SortedDict
|
from django.utils.datastructures import SortedDict
|
||||||
|
|
||||||
from .models import (Annotation, Article, Author, Celebrity, Child, Cover,
|
from .models import (Annotation, Article, Author, Celebrity, Child, Cover,
|
||||||
Detail, DumbCategory, ExtraInfo, Fan, Item, LeafA, LoopX, LoopZ,
|
Detail, DumbCategory, ExtraInfo, Fan, Item, LeafA, Join, LeafB, LoopX, LoopZ,
|
||||||
ManagedModel, Member, NamedCategory, Note, Number, Plaything, PointerA,
|
ManagedModel, Member, NamedCategory, Note, Number, Plaything, PointerA,
|
||||||
Ranking, Related, Report, ReservedName, Tag, TvChef, Valid, X, Food, Eaten,
|
Ranking, Related, Report, ReservedName, Tag, TvChef, Valid, X, Food, Eaten,
|
||||||
Node, ObjectA, ObjectB, ObjectC, CategoryItem, SimpleCategory,
|
Node, ObjectA, ObjectB, ObjectC, CategoryItem, SimpleCategory,
|
||||||
|
@ -2827,3 +2827,17 @@ class ValuesSubqueryTests(TestCase):
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
Order.objects.filter(items__in=OrderItem.objects.values_list('status')),
|
Order.objects.filter(items__in=OrderItem.objects.values_list('status')),
|
||||||
[o1.pk], lambda x: x.pk)
|
[o1.pk], lambda x: x.pk)
|
||||||
|
|
||||||
|
class DoubleInSubqueryTests(TestCase):
|
||||||
|
def test_double_subquery_in(self):
|
||||||
|
lfa1 = LeafA.objects.create(data='foo')
|
||||||
|
lfa2 = LeafA.objects.create(data='bar')
|
||||||
|
lfb1 = LeafB.objects.create(data='lfb1')
|
||||||
|
lfb2 = LeafB.objects.create(data='lfb2')
|
||||||
|
Join.objects.create(a=lfa1, b=lfb1)
|
||||||
|
Join.objects.create(a=lfa2, b=lfb2)
|
||||||
|
leaf_as = LeafA.objects.filter(data='foo').values_list('pk', flat=True)
|
||||||
|
joins = Join.objects.filter(a__in=leaf_as).values_list('b__id', flat=True)
|
||||||
|
qs = LeafB.objects.filter(pk__in=joins)
|
||||||
|
self.assertQuerysetEqual(
|
||||||
|
qs, [lfb1], lambda x: x)
|
||||||
|
|
Loading…
Reference in New Issue