diff options
| author | Anssi Kääriäinen <akaariai@gmail.com> | 2012-12-20 21:25:48 +0200 |
|---|---|---|
| committer | Anssi Kääriäinen <akaariai@gmail.com> | 2012-12-20 21:27:00 +0200 |
| commit | 3dcd435a0eb4380a3846e9c65140df480975687e (patch) | |
| tree | 95f6d265f68af8f8bd579e466d9471875ea8fef6 /tests | |
| parent | c04c03daa3620dc5106740a976738ada35203ab5 (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.py | 8 | ||||
| -rw-r--r-- | tests/regressiontests/queries/tests.py | 33 |
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) |
