summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorAnssi Kääriäinen <akaariai@gmail.com>2013-02-18 01:56:24 +0200
committerAnssi Kääriäinen <akaariai@gmail.com>2013-02-19 01:10:49 +0200
commitb4492a8ca4a7ae4daa3a6b03c3d7a845fad74931 (patch)
tree83eeaaa7d67bbccabbb00ab56c8460b99bfd2d6c /tests
parentffcfb19f47f5995406003cffca24cf62c6d234a8 (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.py14
-rw-r--r--tests/regressiontests/queries/tests.py21
-rw-r--r--tests/tmp.txt1
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