#29697: Complex query crashes with "missing FROM-clause entry for table" -------------------------------------+------------------------------------- Reporter: Dmitry | Owner: nobody Type: Bug | Status: new Component: Database layer | Version: 2.1 (models, ORM) | Severity: Normal | Resolution: Keywords: | Triage Stage: Accepted Has patch: 0 | Needs documentation: 0 Needs tests: 0 | Patch needs improvement: 0 Easy pickings: 0 | UI/UX: 0 -------------------------------------+------------------------------------- Changes (by Tim Graham):
* stage: Unreviewed => Accepted Old description: > python version: 3.6.6 > database backend: psycopg2 v2.7.5 > > Hi. I have next models in my project: > > {{{ > class Status(models.Model): > ... > company = models.ForeignKey( > 'customauth.Company', > on_delete=models.CASCADE) > key = models.SlugField(max_length=255) > ... > > class User(models.Model): > ... > company = models.ForeignKey( > 'customauth.Company', > on_delete=models.CASCADE, > related_name='employees', > db_index=True) > permissions = postgres.fields.JSONField(blank=True, default=list) > is_superuser = models.BooleanField(default=False) > ... > > class Company(models.Model): > ... > }}} > > When trying execute next code: > > {{{ > Status.objects.filter( > Q(company__employees__is_superuser=True) | > ~Q(company__employees__permissions__has_key=Concat(Value('records.'), > 'key', Value('.denied'))), > company__employees__pk=4) > }}} > > raising error: > > {{{ > Traceback (most recent call last): > File "C:\Users\user\py366-tpr\lib\site- > packages\django\db\backends\utils.py", line 85, in _execute > return self.cursor.execute(sql, params) > psycopg2.ProgrammingError: missing FROM-clause entry for table "u1" > LINE 1: ...status" U0 INNER JOIN "customauth_user" U2 ON (U1."id" = ... > ^ > }}} > > SQL after call .query() look like this: > > {{{ > SELECT * > FROM records_status > INNER JOIN customauth_company ON (records_status.company_id = > customauth_company.id) > INNER JOIN customauth_user ON (customauth_company.id = > customauth_user.company_id) > WHERE > ( > ( > customauth_user.is_superuser = True OR > NOT ( > records_status.company_id IN ( > SELECT U2.company_id > FROM records_status U0 > INNER JOIN customauth_user U2 ON (U1.id = > U2.company_id) > WHERE ( > U2.permissions ? (CONCAT('records.', CONCAT(U0.key, > '.denied'))) AND > U2.id = (customauth_user.id) > ) > ) > ) > ) AND > customauth_user.id = 4 AND > records_status.company_id = (customauth_user.company_id) > ) > ORDER BY records_status.key ASC; > }}} > > It is not clear where U1 alias comes from. New description: python version: 3.6.6 database backend: psycopg2 v2.7.5 Hi. I have next models in my project: {{{ from django.db import models from django.contrib.postgres.fields import JSONField class Company(models.Model): ... class Status(models.Model): ... company = models.ForeignKey( Company, on_delete=models.CASCADE) key = models.SlugField(max_length=255) ... class User(models.Model): ... company = models.ForeignKey( Company, on_delete=models.CASCADE, related_name='employees', db_index=True) permissions = JSONField(blank=True, default=list) is_superuser = models.BooleanField(default=False) ... }}} When trying execute next code: {{{ from django.db.models import Q, Value from django.db.models.functions import Concat Status.objects.filter( Q(company__employees__is_superuser=True) | ~Q(company__employees__permissions__has_key=Concat(Value('records.'), 'key', Value('.denied'))), company__employees__pk=4) }}} raising error: {{{ Traceback (most recent call last): File "C:\Users\user\py366-tpr\lib\site- packages\django\db\backends\utils.py", line 85, in _execute return self.cursor.execute(sql, params) psycopg2.ProgrammingError: missing FROM-clause entry for table "u1" LINE 1: ...status" U0 INNER JOIN "customauth_user" U2 ON (U1."id" = ... ^ }}} SQL after call .query() look like this: {{{ SELECT * FROM records_status INNER JOIN customauth_company ON (records_status.company_id = customauth_company.id) INNER JOIN customauth_user ON (customauth_company.id = customauth_user.company_id) WHERE ( ( customauth_user.is_superuser = True OR NOT ( records_status.company_id IN ( SELECT U2.company_id FROM records_status U0 INNER JOIN customauth_user U2 ON (U1.id = U2.company_id) WHERE ( U2.permissions ? (CONCAT('records.', CONCAT(U0.key, '.denied'))) AND U2.id = (customauth_user.id) ) ) ) ) AND customauth_user.id = 4 AND records_status.company_id = (customauth_user.company_id) ) ORDER BY records_status.key ASC; }}} It is not clear where U1 alias comes from. -- Comment: Reproduced at 50b8493581fea3d7137dd8db33bac7008868d23a. -- Ticket URL: <https://code.djangoproject.com/ticket/29697#comment:1> 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 django-updates+unsubscr...@googlegroups.com. To post to this group, send email to django-updates@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-updates/065.2faf1c772adc5f5ff76d856f657e2d09%40djangoproject.com. For more options, visit https://groups.google.com/d/optout.