#19672 closed Bug (fixed)
Negated Q objects over nullable joins result in invalid SQL
Reported by: | Erin Kelly | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Normal | Keywords: | Q ForeignKey nullable |
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
Using the following set of models:
from django.db import models class A(models.Model): value = models.IntegerField(null=True) class B(models.Model): a = models.ForeignKey(A) class C(models.Model): b = models.ForeignKey(B, null=True)
The query C.objects.filter(~Q(b__a__value=42))
fails with the following error:
DatabaseError: no such column: testapp_b.value
The SQL generated is:
SELECT "testapp_c"."id", "testapp_c"."b_id" FROM "testapp_c" LEFT OUTER JOIN "t estapp_b" ON ("testapp_c"."b_id" = "testapp_b"."id") LEFT OUTER JOIN "testapp_a" ON ("testapp_b"."a_id" = "testapp_a"."id") WHERE NOT (("testapp_a"."value" = 42 AND NOT ("testapp_b"."id" IS NULL) AND "testapp_b"."value" IS NOT NULL))
The problem is caused by the last WHERE condition, which is incorrectly filtering on the "value" column in the testapp_b table (where it does not exist) instead of in the testapp_a table.
Attachments (1)
Change History (6)
by , 12 years ago
Attachment: | 19672.diff added |
---|
comment:1 by , 12 years ago
Has patch: | set |
---|
comment:2 by , 12 years ago
Triage Stage: | Unreviewed → Ready for checkin |
---|
The patch looks good to me.
What versions to patch? I think 1.4 is out of reach, this isn't a crashing or data loss bug.
1.5 is technically also in "crash, data-loss, security, regression" fixes only as it is in RC, but as we are going to do RC2 and the patch is as safe as they get, IMO master + stable/1.5.x seems like the correct way.
comment:4 by , 12 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
The bug seems to happen because a local variable gets clobbered in the Query.add_filter method. I've uploaded a patch and tests to fix this.