﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
15823	incorrect join condition when combining Q objects	Dan Watson	Luke Plant	"Originally described the issue in https://groups.google.com/d/msg/django-developers/4wMNF61oQNM/hqspS-Jp5rwJ but copied here for reference.

Models:
{{{
class Item (models.Model):
    title = models.CharField(max_length=100)

class PropertyValue (models.Model):
    label = models.CharField(max_length=100)

class Property (models.Model):
    item = models.ForeignKey(Item, related_name='props')
    key = models.CharField(max_length=100)
    value = models.ForeignKey(PropertyValue, null=True)
}}}

Code:
{{{
item = Item.objects.create(title='Some Item')
pv = PropertyValue.objects.create(label='Some Value')
item.props.create(key='a', value=pv)
item.props.create(key='b')
q1 = Q(props__key='a', props__value=pv)
q2 = Q(props__key='b', props__value__isnull=True)
qs1 = Item.objects.filter(q1) & Item.objects.filter(q2)
qs2 = Item.objects.filter(q2) & Item.objects.filter(q1)
}}}

The problem is that `qs1` and `qs2` do not evaluate to the same thing, as they should (`qs1` is empty). The SQL generated for `qs1` is:

{{{
SELECT ""app_item"".""id"", ""app_item"".""title"" FROM ""app_item"" 
INNER JOIN ""app_property"" ON (""app_item"".""id"" = ""app_property"".""item_id"") 
LEFT OUTER JOIN ""app_property"" T4 ON (""app_item"".""id"" = T4.""item_id"") 
LEFT OUTER JOIN ""app_propertyvalue"" T5 ON (""app_property"".""value_id"" = T5.""id"") 
WHERE ((""app_property"".""value_id"" = 1  AND ""app_property"".""key"" = 'a' ) AND (T5.""id"" IS NULL AND T4.""key"" = 'b'))
}}}

The problem is that the first `app_property` join corresponds to `q1`, and the second corresponds to `q2`. However, the `app_propertyvalue` join (corresponding to the `isnull` from `q2`) refers to `app_property.value_id` (i.e. from `q1`) instead of `T4.value_id` (i.e. from `q2`).

The attached patch checks the left side of the join when combining queries, and if it has already been re-aliased, uses the new alias. That way, join conditions should reference what they referenced before the combination. It also has a regression test, and all tests pass."	Bug	closed	Database layer (models, ORM)	dev	Normal	fixed	query, q, join		Ready for checkin	1	0	0	0	0	0
