diff options
| author | Anssi Kääriäinen <akaariai@gmail.com> | 2013-02-18 01:56:24 +0200 |
|---|---|---|
| committer | Anssi Kääriäinen <akaariai@gmail.com> | 2013-02-19 01:10:49 +0200 |
| commit | b4492a8ca4a7ae4daa3a6b03c3d7a845fad74931 (patch) | |
| tree | 83eeaaa7d67bbccabbb00ab56c8460b99bfd2d6c /tests | |
| parent | ffcfb19f47f5995406003cffca24cf62c6d234a8 (diff) | |
Fixed #19837 -- Refactored split_exclude() join generation
The refactoring mainly concentrates on making sure the inner and outer
query agree about the split position. The split position is where the
multijoin happens, and thus the split position also determines the
columns used in the "WHERE col1 IN (SELECT col2 from ...)" condition.
This commit fixes a regression caused by #10790 and commit
69597e5bcc89aadafd1b76abf7efab30ee0b8b1a. The regression was caused
by wrong cols in the split position.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/regressiontests/queries/models.py | 14 | ||||
| -rw-r--r-- | tests/regressiontests/queries/tests.py | 21 | ||||
| -rw-r--r-- | tests/tmp.txt | 1 |
3 files changed, 35 insertions, 1 deletions
diff --git a/tests/regressiontests/queries/models.py b/tests/regressiontests/queries/models.py index 16583e891c..91edf71aeb 100644 --- a/tests/regressiontests/queries/models.py +++ b/tests/regressiontests/queries/models.py @@ -439,3 +439,17 @@ class BaseA(models.Model): a = models.ForeignKey(FK1, null=True) b = models.ForeignKey(FK2, null=True) c = models.ForeignKey(FK3, null=True) + +@python_2_unicode_compatible +class Identifier(models.Model): + name = models.CharField(max_length=100) + + def __str__(self): + return self.name + +class Program(models.Model): + identifier = models.OneToOneField(Identifier) + +class Channel(models.Model): + programs = models.ManyToManyField(Program) + identifier = models.OneToOneField(Identifier) diff --git a/tests/regressiontests/queries/tests.py b/tests/regressiontests/queries/tests.py index ea54d18451..34bfea0b94 100644 --- a/tests/regressiontests/queries/tests.py +++ b/tests/regressiontests/queries/tests.py @@ -24,7 +24,7 @@ from .models import (Annotation, Article, Author, Celebrity, Child, Cover, Node, ObjectA, ObjectB, ObjectC, CategoryItem, SimpleCategory, SpecialCategory, OneToOneCategory, NullableName, ProxyCategory, SingleObject, RelatedObject, ModelA, ModelD, Responsibility, Job, - JobResponsibilities, BaseA) + JobResponsibilities, BaseA, Identifier, Program, Channel) class BaseQuerysetTest(TestCase): @@ -2612,3 +2612,22 @@ class DisjunctionPromotionTests(TestCase): qs = BaseA.objects.filter(Q(a__f1=F('c__f1')) | (Q(pk=1) & Q(pk=2))) self.assertEqual(str(qs.query).count('LEFT OUTER JOIN'), 2) self.assertEqual(str(qs.query).count('INNER JOIN'), 0) + + +class ManyToManyExcludeTest(TestCase): + def test_exclude_many_to_many(self): + Identifier.objects.create(name='extra') + program = Program.objects.create(identifier=Identifier.objects.create(name='program')) + channel = Channel.objects.create(identifier=Identifier.objects.create(name='channel')) + channel.programs.add(program) + + # channel contains 'program1', so all Identifiers except that one + # should be returned + self.assertQuerysetEqual( + Identifier.objects.exclude(program__channel=channel).order_by('name'), + ['<Identifier: channel>', '<Identifier: extra>'] + ) + self.assertQuerysetEqual( + Identifier.objects.exclude(program__channel=None).order_by('name'), + ['<Identifier: program>'] + ) diff --git a/tests/tmp.txt b/tests/tmp.txt new file mode 100644 index 0000000000..4e812b2c23 --- /dev/null +++ b/tests/tmp.txt @@ -0,0 +1 @@ +SELECT "queries_tag"."id", "queries_tag"."name", "queries_tag"."parent_id", "queries_tag"."category_id" FROM "queries_tag" WHERE NOT (("queries_tag"."id" IN (SELECT U0."id" FROM "queries_tag" U0 LEFT OUTER JOIN "queries_tag" U1 ON (U0."id" = U1."parent_id") WHERE (U1."id" IS NULL AND U0."id" IS NOT NULL)) AND "queries_tag"."id" IS NOT NULL)) ORDER BY "queries_tag"."name" ASC |
