summaryrefslogtreecommitdiff
path: root/django/db/models/sql
diff options
context:
space:
mode:
authorRussell Keith-Magee <russell@keith-magee.com>2011-03-03 13:51:54 +0000
committerRussell Keith-Magee <russell@keith-magee.com>2011-03-03 13:51:54 +0000
commitb7c41c1fbb2d45634dde5f7a450ba1a5aea5a8af (patch)
treecef5898ff8190183438659664479b442726f8919 /django/db/models/sql
parentd1290b5b43485c7018ba92981d34c1f96614924e (diff)
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
Diffstat (limited to 'django/db/models/sql')
-rw-r--r--django/db/models/sql/query.py18
1 files changed, 13 insertions, 5 deletions
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index 341765c608..8fa3419059 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -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.