#28689: OuterRef outputs unquoted table name in SQL query under specific
circumstances
-------------------------------------+-------------------------------------
               Reporter:  Joey       |          Owner:  nobody
  Wilhelm                            |
                   Type:  Bug        |         Status:  new
              Component:  Database   |        Version:  master
  layer (models, ORM)                |
               Severity:  Normal     |       Keywords:
           Triage Stage:             |      Has patch:  0
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  0
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 Under very specific circumstances, I am getting a SQL query with an
 unquoted table name, causing a crash on PostgreSQL.

 **models.py**
 {{{#!python
 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:
 {{{#!python
 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:
 {{{#!python
 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:
 {{{#!sql
 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.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/28689>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/054.7ca67ec1bfb76f8e6e0e695d55bab394%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to