Opened 15 years ago
Closed 9 years ago
#13768 closed Bug (duplicate)
'exclude' does not work with lists containing a 'None' element.
Reported by: | Felipe 'chronos' Prenholato | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.2 |
Severity: | Normal | Keywords: | None, NULL, in, postgres, postgresql |
Cc: | niels.busch@… | Triage Stage: | Accepted |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
This ticket covers use of 'None' (NULL for DB) in list of one 'in' lookup.
Postgres at least, when run a query with a 'WHERE' like "object_id in (NULL,'other val')" returns a query with no
rows, and ORM too, what is a problem because developer can think that query is right, so as Alex Gaynor said in #django-dev 'we can rewrite it as (value IN (other, vals) OR value IS NULL)' or raise a error in database backend (since in ORM we can't thinking that mongodb would allow it as 'apollo13' said).
My vode is to raise a error in database backend.
Here is code in python shell that show the problem:
In Django 1.1.X
>>> LogEntry.objects.exclude(object_id=None).count() 274527 >>> connection.queries[-1] {'sql': 'SELECT COUNT(*) FROM "django_admin_log" WHERE NOT ("django_admin_log"."object_id" IS NULL)', 'time': '0.101'} >>> LogEntry.objects.exclude(object_id__in=(None,)).count() 0 >>> connection.queries[-1] {'sql': 'SELECT COUNT(*) FROM "django_admin_log" WHERE NOT ("django_admin_log"."object_id" IN (NULL) AND NOT ("django_admin_log"."object_id" IS NULL))', 'time': '0.085'} >>> LogEntry.objects.exclude(object_id=None,object_id='None').count() 274443 >>> connection.queries[-1] {'sql': 'SELECT COUNT(*) FROM "django_admin_log" WHERE NOT ("django_admin_log"."object_id" = E\'None\' AND NOT ("django_admin_log"."object_id" IS NULL))', 'time': '0.122'} >>> LogEntry.objects.exclude(object_id__in=(None,'None')).count() 0 >>> connection.queries[-1] {'sql': 'SELECT COUNT(*) FROM "django_admin_log" WHERE NOT ("django_admin_log"."object_id" IN (NULL, E\'None\') AND NOT ("django_admin_log"."object_id" IS NULL))', 'time': '0.126'}
Django 1.2
>>> LogEntry.objects.exclude(object_id=None).count() 274527 >>> connection.queries[-1] {'sql': 'SELECT COUNT(*) FROM "django_admin_log" WHERE NOT ("django_admin_log"."object_id" IS NULL)', 'time': '0.104'} >>> LogEntry.objects.exclude(object_id__in=(None,)).count() 0 >>> connection.queries[-1] {'sql': 'SELECT COUNT(*) FROM "django_admin_log" WHERE NOT (("django_admin_log"."object_id" IN (NULL) AND NOT ("django_admin_log"."object_id" IS NULL)))', 'time': '0.088'} >>> LogEntry.objects.exclude(Q(object_id=None),Q(object_id='None')).count() 274527 >>> connection.queries[-1] {'sql': 'SELECT COUNT(*) FROM "django_admin_log" WHERE NOT ("django_admin_log"."object_id" IS NULL AND "django_admin_log"."object_id" = E\'None\' )', 'time': '0.114'} >>> LogEntry.objects.exclude(object_id__in=(None,'None')).count() 0 >>> connection.queries[-1] {'sql': 'SELECT COUNT(*) FROM "django_admin_log" WHERE NOT (("django_admin_log"."object_id" IN (NULL, E\'None\') AND NOT ("django_admin_log"."object_id" IS NULL)))', 'time': '0.120'}
Change History (10)
comment:1 by , 15 years ago
Triage Stage: | Unreviewed → Accepted |
---|
follow-up: 3 comment:2 by , 15 years ago
comment:3 by , 14 years ago
comment:4 by , 14 years ago
Severity: | → Normal |
---|---|
Type: | → Bug |
comment:13 by , 11 years ago
Cc: | added |
---|
comment:14 by , 9 years ago
Resolution: | → duplicate |
---|---|
Status: | new → closed |
Summary: | Bug in Django ORM when filtering with 'in' lookup and None in values list (1.1.x and 1.2.x) → 'exclude' does not work with lists containing a 'None' element. |
Duplicate of #20024.
Confirmed in SQLite and MySQL as well. This influences current generated SQL for checking isnull on reverse nullable (null=True) relations as well.
generates
Because of the null=True in the relation, the subquery might return NULL-values which results in an empty query instead of a filtered one.