summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorAnssi Kääriäinen <akaariai@gmail.com>2012-12-20 21:25:48 +0200
committerAnssi Kääriäinen <akaariai@gmail.com>2012-12-20 21:27:00 +0200
commit3dcd435a0eb4380a3846e9c65140df480975687e (patch)
tree95f6d265f68af8f8bd579e466d9471875ea8fef6 /tests
parentc04c03daa3620dc5106740a976738ada35203ab5 (diff)
Fixed #19500 -- Solved a regression in join reuse
The ORM didn't reuse joins for direct foreign key traversals when using chained filters. For example: qs.filter(fk__somefield=1).filter(fk__somefield=2)) produced two joins. As a bonus, reverse onetoone filters can now reuse joins correctly The regression was caused by the join() method refactor in commit 68847135bc9acb2c51c2d36797d0a85395f0cd35 Thanks for Simon Charette for spotting some issues with the first draft of the patch.
Diffstat (limited to 'tests')
-rw-r--r--tests/regressiontests/generic_relations_regress/tests.py8
-rw-r--r--tests/regressiontests/queries/tests.py33
2 files changed, 40 insertions, 1 deletions
diff --git a/tests/regressiontests/generic_relations_regress/tests.py b/tests/regressiontests/generic_relations_regress/tests.py
index 4c0f024433..262c2e4917 100644
--- a/tests/regressiontests/generic_relations_regress/tests.py
+++ b/tests/regressiontests/generic_relations_regress/tests.py
@@ -72,5 +72,11 @@ class GenericRelationTests(TestCase):
Q(notes__note__icontains=r'other note'))
self.assertTrue(org_contact in qs)
-
+ def test_join_reuse(self):
+ qs = Person.objects.filter(
+ addresses__street='foo'
+ ).filter(
+ addresses__street='bar'
+ )
+ self.assertEqual(str(qs.query).count('JOIN'), 2)
diff --git a/tests/regressiontests/queries/tests.py b/tests/regressiontests/queries/tests.py
index 75e27769b4..9270955877 100644
--- a/tests/regressiontests/queries/tests.py
+++ b/tests/regressiontests/queries/tests.py
@@ -2418,3 +2418,36 @@ class ReverseJoinTrimmingTest(TestCase):
qs = Tag.objects.filter(annotation__tag=t.pk)
self.assertIn('INNER JOIN', str(qs.query))
self.assertEquals(list(qs), [])
+
+class JoinReuseTest(TestCase):
+ """
+ Test that the queries reuse joins sensibly (for example, direct joins
+ are always reused).
+ """
+ def test_fk_reuse(self):
+ qs = Annotation.objects.filter(tag__name='foo').filter(tag__name='bar')
+ self.assertEqual(str(qs.query).count('JOIN'), 1)
+
+ def test_fk_reuse_select_related(self):
+ qs = Annotation.objects.filter(tag__name='foo').select_related('tag')
+ self.assertEqual(str(qs.query).count('JOIN'), 1)
+
+ def test_fk_reuse_annotation(self):
+ qs = Annotation.objects.filter(tag__name='foo').annotate(cnt=Count('tag__name'))
+ self.assertEqual(str(qs.query).count('JOIN'), 1)
+
+ def test_fk_reuse_disjunction(self):
+ qs = Annotation.objects.filter(Q(tag__name='foo') | Q(tag__name='bar'))
+ self.assertEqual(str(qs.query).count('JOIN'), 1)
+
+ def test_fk_reuse_order_by(self):
+ qs = Annotation.objects.filter(tag__name='foo').order_by('tag__name')
+ self.assertEqual(str(qs.query).count('JOIN'), 1)
+
+ def test_revo2o_reuse(self):
+ qs = Detail.objects.filter(member__name='foo').filter(member__name='foo')
+ self.assertEqual(str(qs.query).count('JOIN'), 1)
+
+ def test_revfk_noreuse(self):
+ qs = Author.objects.filter(report__name='r4').filter(report__name='r1')
+ self.assertEqual(str(qs.query).count('JOIN'), 2)