From dcdc579d162b750ee3449e34efd772703592faca Mon Sep 17 00:00:00 2001 From: Anssi Kääriäinen Date: Tue, 13 Aug 2013 14:11:52 +0300 Subject: Fixed #20874 -- bump_prefix() in nested subqueries Also made some cleanup to build_filter() code by introducing submethods solve_lookup_type() and prepare_lookup_value(). --- tests/foreign_object/tests.py | 19 ++++++++++++++++++- tests/queries/tests.py | 16 ++++++++++++++-- 2 files changed, 32 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/tests/foreign_object/tests.py b/tests/foreign_object/tests.py index cd81cc68a2..77582162a8 100644 --- a/tests/foreign_object/tests.py +++ b/tests/foreign_object/tests.py @@ -132,7 +132,6 @@ class MultiColumnFKTests(TestCase): ], attrgetter('person_id') ) - self.assertQuerysetEqual( Membership.objects.filter(person__in=Person.objects.filter(name='Jim')), [ self.jim.id, @@ -140,6 +139,24 @@ class MultiColumnFKTests(TestCase): attrgetter('person_id') ) + def test_double_nested_query(self): + m1 = Membership.objects.create(membership_country_id=self.usa.id, person_id=self.bob.id, + group_id=self.cia.id) + m2 = Membership.objects.create(membership_country_id=self.usa.id, person_id=self.jim.id, + group_id=self.cia.id) + Friendship.objects.create(from_friend_country_id=self.usa.id, from_friend_id=self.bob.id, + to_friend_country_id=self.usa.id, to_friend_id=self.jim.id) + self.assertQuerysetEqual(Membership.objects.filter( + person__in=Person.objects.filter( + from_friend__in=Friendship.objects.filter( + to_friend__in=Person.objects.all()))), + [m1], lambda x: x) + self.assertQuerysetEqual(Membership.objects.exclude( + person__in=Person.objects.filter( + from_friend__in=Friendship.objects.filter( + to_friend__in=Person.objects.all()))), + [m2], lambda x: x) + def test_select_related_foreignkey_forward_works(self): Membership.objects.create(membership_country=self.usa, person=self.bob, group=self.cia) Membership.objects.create(membership_country=self.usa, person=self.jim, group=self.democrat) diff --git a/tests/queries/tests.py b/tests/queries/tests.py index 6e03b0d7f6..cd47f0ccd5 100644 --- a/tests/queries/tests.py +++ b/tests/queries/tests.py @@ -27,7 +27,6 @@ from .models import ( BaseA, FK1, Identifier, Program, Channel, Page, Paragraph, Chapter, Book, MyObject, Order, OrderItem) - class BaseQuerysetTest(TestCase): def assertValueQuerysetEqual(self, qs, values): return self.assertQuerysetEqual(qs, values, transform=lambda x: x) @@ -84,6 +83,19 @@ class Queries1Tests(BaseQuerysetTest): Cover.objects.create(title="first", item=i4) Cover.objects.create(title="second", item=self.i2) + def test_subquery_condition(self): + qs1 = Tag.objects.filter(pk__lte=0) + qs2 = Tag.objects.filter(parent__in=qs1) + qs3 = Tag.objects.filter(parent__in=qs2) + self.assertEqual(qs3.query.subq_aliases, set(['T', 'U', 'V'])) + self.assertIn('V0', str(qs3.query)) + qs4 = qs3.filter(parent__in=qs1) + self.assertEqual(qs4.query.subq_aliases, set(['T', 'U', 'V'])) + # It is possible to reuse U for the second subquery, no need to use W. + self.assertNotIn('W0', str(qs4.query)) + # So, 'U0."id"' is referenced twice. + self.assertTrue(str(qs4.query).count('U0."id"'), 2) + def test_ticket1050(self): self.assertQuerysetEqual( Item.objects.filter(tags__isnull=True), @@ -810,7 +822,7 @@ class Queries1Tests(BaseQuerysetTest): # Make sure bump_prefix() (an internal Query method) doesn't (re-)break. It's # sufficient that this query runs without error. qs = Tag.objects.values_list('id', flat=True).order_by('id') - qs.query.bump_prefix() + qs.query.bump_prefix(qs.query) first = qs[0] self.assertEqual(list(qs), list(range(first, first+5))) -- cgit v1.3