#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 , 13 years ago
| Attachment: | 19672.diff added |
|---|
comment:1 by , 13 years ago
| Has patch: | set |
|---|
comment:2 by , 13 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 , 13 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.