Django

Code

Ticket #7125 (new)

Opened 2 weeks ago

Last modified 2 weeks ago

Multiple ForeignKeys to the same model produces wrong SQL statements.

Reported by: mk Assigned to: nobody
Component: Database wrapper Version: SVN
Keywords: wrong sql join intermediary Cc: mk@spinlock.ch, cmutel@gmail.com
Triage Stage: Unreviewed Has patch: 0
Needs documentation: 0 Needs tests: 0
Patch needs improvement: 0

Description

Take the following models:

from django.db import models

class Category(models.Model):
	name = models.CharField(max_length=20)

class Record(models.Model):
	category = models.ForeignKey(Category)

class Relation(models.Model):
	left = models.ForeignKey(Record, related_name='left_set')
	right = models.ForeignKey(Record, related_name='right_set')

Some example data:

from testcase.models import *
c1 = Category.objects.create(name='First')
c2 = Category.objects.create(name='Second')

r1 = Record.objects.create(category=c1)
r2 = Record.objects.create(category=c1)
r3 = Record.objects.create(category=c2)
r4 = Record.objects.create(category=c2)

Relation.objects.create(left=r1, right=r2)
Relation.objects.create(left=r3, right=r4)
Relation.objects.create(left=r1, right=r3)

The following query:

Relation.objects.filter(left__category__name__in=['Second'], right__category__name__in=['First'])

produces this SQL statement:

SELECT "testcase_relation"."id", "testcase_relation"."left_id", "testcase_relation"."right_id" FROM "testcase_relation"
INNER JOIN "testcase_record" ON ("testcase_relation"."right_id" = "testcase_record"."id")
INNER JOIN "testcase_category" ON ("testcase_record"."category_id" = "testcase_category"."id")
INNER JOIN "testcase_record" T4 ON ("testcase_relation"."left_id" = T4."id")
WHERE "testcase_category"."name" IN (First) AND "testcase_category"."name" IN (Second)

which is obviously wrong.

Note that the first WHERE clause should be T4.name IN (First), not "testcase_category"."name" IN (First). Also note the missing second join on testcase_category.

Attachments

Change History

04/29/08 10:29:12 changed by ElliottM

  • needs_better_patch changed.
  • needs_tests changed.
  • needs_docs changed.

This is very strongly related to #7110, and these two should probably be treated as one ticket, because i've noticed more problems than just the select_related() thing I mentioned in my ticket. I was actually planning on renaming it to refer to problems with multiple FKs in general, but if this is already here then i guess we can just use this one.

04/29/08 10:47:31 changed by oyvind

  • keywords set to wrong sql join intermediary.

Confirmed

Should it not be?

SELECT "testcase_relation"."id", "testcase_relation"."left_id", "testcase_relation"."right_id" FROM "testcase_relation"
INNER JOIN "testcase_record" ON ("testcase_relation"."right_id" = "testcase_record"."id")
INNER JOIN "testcase_category" ON ("testcase_record"."category_id" = "testcase_category"."id")
INNER JOIN "testcase_record" T4 ON ("testcase_relation"."left_id" = T4."id")
INNER JOIN "testcase_category" T5 ON ("T4"."category_id" = T5."id")
WHERE T5."name" IN (First) AND "testcase_category"."name" IN (Second)

04/30/08 03:39:09 changed by anonymous

  • cc changed from cmutel@gmail.com to mk@spinlock.ch, cmutel@gmail.com.

04/30/08 12:06:58 changed by oyvind

Seems to handle the first level only, something goes wrong and causes reuse of the same alias in the second level join.

04/30/08 12:15:27 changed by oyvind

With select_related() the correct T5 join is added, but the where uses the wrong alias.

05/01/08 13:59:57 changed by oyvind

Test queries for example models.

""" Missing T5 join, wrong where """
Relation.objects.filter(left__category__name__in=['Second'], right__category__name__in=['First']).query.as_sql()

""" With T5 join, but wrong where """
Relation.objects.filter(left__category__name__in=['Second'], right__category__name__in=['First']).select_related().query.as_sql()

Add/Change #7125 (Multiple ForeignKeys to the same model produces wrong SQL statements.)




Change Properties
Action