Opened 4 years ago

Last modified 4 years ago

#32151 closed Bug

invalid query SQL created when combining __in and F() in filter — at Initial Version

Reported by: Beda Kosata Owned by: nobody
Component: Database layer (models, ORM) Version: 3.1
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

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

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:

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:

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.

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")

Change History (0)

Note: See TracTickets for help on using tickets.
Back to Top