1
0
mirror of https://github.com/django/django.git synced 2025-10-29 16:46:11 +00:00

Fixed #12252 -- Ensure that queryset unions are commutative. Thanks to benreynwar for the report, and draft patch, and to Karen and Ramiro for the review eyeballs and patch updates.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@15726 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Russell Keith-Magee
2011-03-03 13:51:54 +00:00
parent d1290b5b43
commit b7c41c1fbb
3 changed files with 98 additions and 6 deletions

View File

@@ -446,6 +446,8 @@ class Query(object):
"Cannot combine a unique query with a non-unique query."
self.remove_inherited_models()
l_tables = set([a for a in self.tables if self.alias_refcount[a]])
r_tables = set([a for a in rhs.tables if rhs.alias_refcount[a]])
# Work out how to relabel the rhs aliases, if necessary.
change_map = {}
used = set()
@@ -463,13 +465,19 @@ class Query(object):
first = False
# So that we don't exclude valid results in an "or" query combination,
# the first join that is exclusive to the lhs (self) must be converted
# all joins exclusive to either the lhs or the rhs must be converted
# to an outer join.
if not conjunction:
for alias in self.tables[1:]:
if self.alias_refcount[alias] == 1:
self.promote_alias(alias, True)
break
# Update r_tables aliases.
for alias in change_map:
if alias in r_tables:
r_tables.remove(alias)
r_tables.add(change_map[alias])
# Find aliases that are exclusive to rhs or lhs.
# These are promoted to outer joins.
outer_aliases = (l_tables | r_tables) - (l_tables & r_tables)
for alias in outer_aliases:
self.promote_alias(alias, True)
# Now relabel a copy of the rhs where-clause and add it to the current
# one.