#28689 closed Bug (fixed)
OuterRef outputs unquoted table name in SQL query under specific circumstances
Reported by: | Joey Wilhelm | Owned by: | Mariusz Felisiak |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.11 |
Severity: | Release blocker | Keywords: | |
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Under very specific circumstances, I am getting a SQL query with an unquoted table name, causing a crash on PostgreSQL.
models.py
from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType from django.db import models class PrimaryModel(models.Model): name = models.CharField(max_length=255) class Meta: db_table = 'PrimaryModel' class GenericRelatedModel(models.Model): name = models.CharField(max_length=255) content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) object_id = models.PositiveIntegerField() content_object = GenericForeignKey() class Meta: db_table = 'GenericRelatedModel'
Then when running the following code:
from django.contrib.contenttypes.models import ContentType from django.db import connection from django.db.models import Exists, OuterRef from testapp.models import PrimaryModel, GenericRelatedModel PrimaryModel.objects.get_or_create(name='foo') generic = GenericRelatedModel.objects.filter(object_id=OuterRef('id'), content_type=ContentType.objects.get_for_model(PrimaryModel)) primary = PrimaryModel.objects.annotate(generic_exists=Exists(generic)) print(primary)
I encounter the following error:
Traceback (most recent call last): File ".virtualenvs/unquoted_outerref/lib/python3.6/site-packages/django/db/backends/utils.py", line 65, in execute return self.cursor.execute(sql, params) psycopg2.ProgrammingError: missing FROM-clause entry for table "primarymodel" LINE 1: ..."GenericRelatedModel" U0 WHERE (U0."object_id" = (PrimaryMod... ^
Looking at the generated SQL, I see that the table name, "PrimaryModel", is left unquoted inside the EXISTS query:
SELECT "PrimaryModel"."id", "PrimaryModel"."name", EXISTS(SELECT U0."id", U0."name", U0."content_type_id", U0."object_id" FROM "GenericRelatedModel" U0 WHERE (U0."object_id" = (PrimaryModel."id") AND U0."content_type_id" = 8)) AS "generic_exists" FROM "PrimaryModel" LIMIT 21
This doesn't cause any problems in SQLite, but I get a crash when using PostgreSQL due to its case sensitivity.
This bug does not surface if referencing a normal foreign key; it appears to be related to the fact of relating the PositiveIntegerField (object_id) to the OuterRef.
This bug occurs both in the latest 1.11, and in 2.0a1.
If necessary, I can provide a sample project with all of this code.
Attachments (1)
Change History (7)
comment:1 by , 7 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:2 by , 7 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
by , 7 years ago
Attachment: | 28689.diff added |
---|
comment:3 by , 7 years ago
Has patch: | set |
---|---|
Severity: | Normal → Release blocker |
Version: | master → 1.11 |
Just applying that will trigger similar errors:
tests/expressions/models.py