[Django] #32151: invalid query SQL created when combining __in and F() in filter

16 views
Skip to first unread message

Django

unread,
Oct 27, 2020, 12:43:47 PM10/27/20
to django-...@googlegroups.com
#32151: invalid query SQL created when combining __in and F() in filter
-------------------------------------+-------------------------------------
Reporter: Beda | Owner: nobody
Kosata |
Type: Bug | Status: new
Component: Database | Version: 3.1
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 |
-------------------------------------+-------------------------------------
When a query contains an `__in` filter with `F()` on the right side (I
observed it with a ManyToMany relationship), the generated SQL is not
correct and causes a SyntaxError. At least for PostgreSQL 12.

Here is a sample project to reproduce the issue:

**models.py**

{{{#!python
from django.db import models

class Author(models.Model):
name = models.CharField(max_length=32)


class Publisher(models.Model):
authors = models.ManyToManyField(Author)


class Book(models.Model):
publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
}}}

This query:

{{{#!python
list(Book.objects.filter(author__in=F('publisher__authors')))
}}}


then fails with `psycopg2.errors.SyntaxError: syntax error at or near
""ferror_publisher_authors""`


The problem is that the generated query looks like this:

{{{#!sql
SELECT "ferror_book"."id", "ferror_book"."publisher_id",
"ferror_book"."author_id"
FROM "ferror_book"
INNER JOIN "ferror_publisher" ON ("ferror_book"."publisher_id" =
"ferror_publisher"."id")
INNER JOIN "ferror_publisher_authors" ON ("ferror_publisher"."id" =
"ferror_publisher_authors"."publisher_id")
WHERE "ferror_book"."author_id" IN "ferror_publisher_authors"."author_id"
}}}

This issue is present in both 3.0.10 and 3.1.5. When the same code is run
in Django 2.2.16, a correct query is created with brackets around the
`"ferror_publisher_authors"."author_id"` part at the end.

{{{#!sql
SELECT "ferror_book"."id", "ferror_book"."publisher_id",
"ferror_book"."author_id"
FROM "ferror_book"
INNER JOIN "ferror_publisher" ON ("ferror_book"."publisher_id" =
"ferror_publisher"."id")
INNER JOIN "ferror_publisher_authors" ON ("ferror_publisher"."id" =
"ferror_publisher_authors"."publisher_id")
WHERE "ferror_book"."author_id" IN
("ferror_publisher_authors"."author_id")
}}}

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

Django

unread,
Oct 27, 2020, 12:47:12 PM10/27/20
to django-...@googlegroups.com
#32151: invalid query SQL created when combining __in and F() in filter
-------------------------------------+-------------------------------------
Reporter: Beda Kosata | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 3.1
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Description changed by Beda Kosata:

Old description:

New description:

**models.py**

This query:

{{{#!python
list(Book.objects.filter(author__in=F('publisher__authors')))
}}}

This issue is present in both 3.0.10 and 3.1.2. When the same code is run


in Django 2.2.16, a correct query is created with brackets around the
`"ferror_publisher_authors"."author_id"` part at the end.

{{{#!sql
SELECT "ferror_book"."id", "ferror_book"."publisher_id",
"ferror_book"."author_id"
FROM "ferror_book"
INNER JOIN "ferror_publisher" ON ("ferror_book"."publisher_id" =
"ferror_publisher"."id")
INNER JOIN "ferror_publisher_authors" ON ("ferror_publisher"."id" =
"ferror_publisher_authors"."publisher_id")
WHERE "ferror_book"."author_id" IN
("ferror_publisher_authors"."author_id")
}}}

--

--
Ticket URL: <https://code.djangoproject.com/ticket/32151#comment:1>

Django

unread,
Oct 27, 2020, 1:47:04 PM10/27/20
to django-...@googlegroups.com
#32151: invalid query SQL created when combining __in and F() in filter
-------------------------------------+-------------------------------------
Reporter: Beda Kosata | Owner: nobody
Type: Bug | Status: new

Component: Database layer | Version: 3.1
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Simon Charette):

Not sure if this was ever explicitly supported, any reason you don't use
`author=F('publisher__authors')`?

--
Ticket URL: <https://code.djangoproject.com/ticket/32151#comment:2>

Django

unread,
Oct 27, 2020, 3:32:41 PM10/27/20
to django-...@googlegroups.com
#32151: Invalid query SQL created when combining __in and F() in filter
-------------------------------------+-------------------------------------

Reporter: Beda Kosata | Owner: nobody
Type: Bug | Status: closed

Component: Database layer | Version: 3.1
(models, ORM) |
Severity: Normal | Resolution: duplicate
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak):

* status: new => closed
* resolution: => duplicate


Comment:

Duplicate of #31135.

--
Ticket URL: <https://code.djangoproject.com/ticket/32151#comment:3>

Django

unread,
Oct 28, 2020, 7:36:28 AM10/28/20
to django-...@googlegroups.com
#32151: Invalid query SQL created when combining __in and F() in filter
-------------------------------------+-------------------------------------

Reporter: Beda Kosata | Owner: nobody
Type: Bug | Status: closed
Component: Database layer | Version: 3.1
(models, ORM) |
Severity: Normal | Resolution: duplicate
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Beda Kosata):

Replying to [comment:2 Simon Charette]:


> Not sure if this was ever explicitly supported, any reason you don't use
`author=F('publisher__authors')`?

Thanks for the hint. I was thinking about it yesterday after I submitted
the bug report and wanted to test it today (my actual use case is more
complicated than the test code), but you were faster :)

--
Ticket URL: <https://code.djangoproject.com/ticket/32151#comment:4>

Reply all
Reply to author
Forward
0 new messages