#12252 closed (fixed)
Queryset unions are sometimes incorrect.
Reported by: | Ben | Owned by: | Ben |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Keywords: | ||
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Queryset unions are in this case incorrect. It appears that an 'inner join' is
not being converted into an 'outer join' when it should be. See the example below.
import unittest from django.db import models class ObjectA(models.Model): name = models.CharField(max_length=50) class ObjectB(models.Model): name = models.CharField(max_length=50) objecta = models.ForeignKey(ObjectA) number = models.PositiveSmallIntegerField() class TestStuff(unittest.TestCase): def test_stuff(self): names = ['one', 'two', 'three', 'four', 'five', 'six', 'seven'] obs = [ObjectA(name=name) for name in names] for o in obs: o.save() b_infos = [('fish', 5, obs[0]), ('turtle', 9, obs[0]), ('fish', 6, obs[3])] ob_bs = [ObjectB(name=name, objecta=objecta, number=number) for name, number, objecta in b_infos] for o in ob_bs: o.save() all_query = ObjectA.objects.all() filter1_query = ObjectA.objects.filter(objectb__name='fish') filter2_query = ObjectA.objects.filter(objectb__name='fish', objectb__number=6) # The tests with filter1_query pass for me. self.assertEqual(set(all_query | filter1_query), set(all_query) | set(filter1_query)) self.assertEqual(set(filter1_query | all_query), set(all_query) | set(filter1_query)) # The second test with filter2_query fails for me. self.assertEqual(set(all_query | filter2_query), set(all_query) | set(filter2_query)) self.assertEqual(set(filter2_query | all_query), set(all_query) | set(filter2_query))
Attachments (5)
Change History (13)
comment:1 by , 15 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:2 by , 15 years ago
Owner: | changed from | to
---|
by , 15 years ago
Attachment: | 12252a.diff added |
---|
comment:3 by , 15 years ago
Has patch: | set |
---|
by , 15 years ago
Attachment: | 12252b.diff added |
---|
second attempt to get the patch to display correctly
comment:4 by , 14 years ago
milestone: | → 1.3 |
---|
I'm seeing a similar issue in my project where queryset OR is not commutative. One way produces a LEFT OUTER JOIN and the other produces an INNER JOIN. This patch resolves this issue for me.
comment:5 by , 14 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
Near as I can tell, this is good to go, though I'd be happier if someone with more ORM clues than me would give it look...
by , 14 years ago
Attachment: | 12252.1.diff added |
---|
Karen, no enough ORM fu here, but updated the patch removing unneeded code in tests (init(), setUp())
by , 13 years ago
Attachment: | 12252_1.2.diff added |
---|
patch for 1.2.5 in case anyone needs it (fix is commited in 1.2.X branch)
I've uploaded a patch (although it's not displaying properly) which appears to correct this problem, and a regression test to go with it.