#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 , 16 years ago
| Triage Stage: | Unreviewed → Accepted |
|---|
comment:2 by , 16 years ago
| Owner: | changed from to |
|---|
by , 16 years ago
| Attachment: | 12252a.diff added |
|---|
comment:3 by , 16 years ago
| Has patch: | set |
|---|
by , 16 years ago
| Attachment: | 12252b.diff added |
|---|
second attempt to get the patch to display correctly
comment:4 by , 15 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 , 15 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 , 15 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 , 14 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.