﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
15145	__in is ignored by an excluded query if foo__in is set to an empty iterable	Stephen Burrows	nobody	"Please note that the arguments may be ignored by a filtered query. I haven't tested that.

Assume the following model setup:
{{{
#!python
from django.db import models
from django.contrib.contenttypes.models import ContentType


class TestModel1(models.Model):
	content_type = models.ForeignKey(ContentType)
	integer = models.PositiveIntegerField()
}}}

Now run the following code:
{{{
#!python
>>> from test.models import TestModel1 # or wherever you're keeping it.
>>> from django.contrib.contenttypes.models import ContentType
>>> integer = 1
>>> ct = ContentType.objects.all()[0]
>>> TestModel1.objects.create(integer=integer, content_type=ct)
<TestModel1: TestModel1 object>
>>> TestModel1.objects.all()
[<TestModel1: TestModel1 object>]
>>> # This is where it starts getting interesting.
>>> TestModel1.objects.exclude(content_type=ct, integer__in=[])
[]
}}}
According to the documentation, this kind of exclude should exclude all rows where the content type is ct AND integer is in the list. Now since the list is empty, there should be no rows matching the exclusion, so all rows should be returned. Instead, I get an empty queryset.

Here's a look at the sql being generated by various queries (Line breaks added for readability):

----

{{{TestModel1.objects.all() or TestModel1.objects.exclude(integer__in=[]) or TestModel1.objects.exclude(content_type__in=[])}}}
{{{
#!sql
SELECT ""test_testmodel1"".""id"", ""test_testmodel1"".""content_type_id"", ""test_testmodel1"".""integer"" FROM ""test_testmodel1""
}}}

----

{{{TestModel1.objects.exclude(integer__in=[2])}}}
{{{
#!sql
SELECT ""test_testmodel1"".""id"", ""test_testmodel1"".""content_type_id"", ""test_testmodel1"".""integer""
FROM ""test_testmodel1"" WHERE NOT (""test_testmodel1"".""integer"" IN (2))
}}}

----

{{{TestModel1.objects.exclude(integer__in=[], content_type=ct) or TestModel1.objects.exclude(content_type=ct)}}}
{{{
#!sql
SELECT ""test_testmodel1"".""id"", ""test_testmodel1"".""content_type_id"", ""test_testmodel1"".""integer""
FROM ""test_testmodel1"" WHERE NOT (""test_testmodel1"".""content_type_id"" = 1 )
}}}

---

{{{TestModel1.objects.exclude(content_type__in=[], integer=1) or TestModel1.objects.exclude(integer=1)}}}
{{{
#!sql
SELECT ""test_testmodel1"".""id"", ""test_testmodel1"".""content_type_id"", ""test_testmodel1"".""integer""
FROM ""test_testmodel1"" WHERE NOT (""test_testmodel1"".""integer"" = 1 )

---

As you can see, the __in kwarg is being completely ignored. Unfortunately, I can't for the life of me figure out where the bug is happening, or I would try to write a patch. In case it's relevant, I'm using a sqlite3 database."	Bug	closed	Database layer (models, ORM)	dev	Normal	fixed		stephen.r.burrows@… botondus@…	Accepted	0	0	0	1	0	0
