Opened 5 years ago

Closed 4 years ago

Last modified 4 years ago

#14876 closed Bug (fixed)

Q | Q with nullable related fields generates INNER JOIN where it should be LEFT JOIN

Reported by: simonpercivall Owned by: oinopion
Component: Database layer (models, ORM) Version: 1.2
Severity: Normal Keywords: Q, inner join, nullable, dceu2011
Cc: asendecka@… Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

The following example shows that when ORing Q's Person is LEFT OUTER JOINed and House is erroneously INNER JOINed. At the same time ORing querysets works.

from django.db import models
from django.db.models import Q

class House(models.Model):
    streetname = models.CharField(max_length=255)

class Person(models.Model):
    home = models.ForeignKey(House)

class Rock(models.Model):
    owner = models.ForeignKey(Person, null=True)

# with Q | Q
print Rock.objects.filter(Q(owner__isnull=True) | (Q(owner__home__streetname=''))).query

# with qs | qs
print (Rock.objects.filter(Q(owner__isnull=True)) | Rock.objects.filter(Q(owner__home__streetname=''))).query

This of course means that owner__is_null=True won't work with Q's becaues of the INNER JOIN.

Tested with 1.0.4+, 1.2.3+ and 1.3 trunk@14864

Attachments (2)

14876.diff (1.4 KB) - added by oinopion 4 years ago.
14876.r16622.diff (1.4 KB) - added by emulbreh 4 years ago.
cleanup for r16622

Download all attachments as: .zip

Change History (11)

comment:1 Changed 5 years ago by simonpercivall

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Summary changed from (Q) | Q with nullable related fields generates INNER JOIN where it should be LEFT JOIN to Q | Q with nullable related fields generates INNER JOIN where it should be LEFT JOIN

comment:2 Changed 5 years ago by russellm

  • Triage Stage changed from Unreviewed to Accepted

comment:3 Changed 4 years ago by jaddison

  • Severity set to Normal
  • Type set to Bug

Changed 4 years ago by oinopion

comment:4 Changed 4 years ago by oinopion

  • Easy pickings unset
  • Keywords dceu2011 added
  • Owner changed from nobody to oinopion
  • Status changed from new to assigned
  • UI/UX unset

After countless hours of debugging, one line fix patch is ready. Test included. Done by me & ethlinn (Aleksandra Sendecka).

comment:5 Changed 4 years ago by Aleksandra Sendecka <asendecka@…>

  • Cc asendecka@… added
  • Has patch set

comment:6 Changed 4 years ago by hvdklauw

  • Triage Stage changed from Accepted to Ready for checkin

Tested, works perfect.

Changed 4 years ago by emulbreh

cleanup for r16622

comment:7 Changed 4 years ago by emulbreh

I can confirm that this patch also fixes #11052.

comment:8 Changed 4 years ago by russellm

  • Resolution set to fixed
  • Status changed from assigned to closed

In [16648]:

Fixed #14876 -- Ensure that join promotion works correctly when there are nullable related fields. Thanks to simonpercivall for the report, oinopion and Aleksandra Sendecka for the original patch, and to Malcolm for helping me wrestle the edge cases to the ground.

comment:9 Changed 4 years ago by russellm

In [16671]:

[1.3.X] Fixed #14876 -- Ensure that join promotion works correctly when there are nullable related fields. Thanks to simonpercivall for the report, oinopion and Aleksandra Sendecka for the original patch, and to Malcolm for helping me wrestle the edge cases to the ground.

Backport of r16648 from trunk.

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