summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnssi Kääriäinen <akaariai@gmail.com>2012-10-08 18:36:51 +0300
committerAnssi Kääriäinen <akaariai@gmail.com>2012-10-08 18:40:09 +0300
commita62d53c03252bdf82b21b64874efe053160cbdb7 (patch)
treebdcb14d13a72b796d715753225cf08e6a46834b1
parent4797ad80da57f3f8a7c029008f3e937240cf23e6 (diff)
Fixed #19087 -- Ensured query's base table is never LOUTER joined
This fixes a regression created by join promotion logic refactoring: 01b9c3d5193fe61b82ae8b26242a13fdec22f211 Thanks to Ivan Virabyan for the report.
-rw-r--r--django/db/models/sql/query.py8
-rw-r--r--tests/regressiontests/aggregation_regress/tests.py11
2 files changed, 19 insertions, 0 deletions
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index 77f24fcf24..ad82b167a6 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -702,6 +702,11 @@ class Query(object):
aliases = list(aliases)
while aliases:
alias = aliases.pop(0)
+ if self.alias_map[alias].rhs_join_col is None:
+ # This is the base table (first FROM entry) - this table
+ # isn't really joined at all in the query, so we should not
+ # alter its join type.
+ continue
parent_alias = self.alias_map[alias].lhs_alias
parent_louter = (parent_alias
and self.alias_map[parent_alias].join_type == self.LOUTER)
@@ -1188,6 +1193,9 @@ class Query(object):
for alias in join_list:
if self.alias_map[alias].join_type == self.LOUTER:
j_col = self.alias_map[alias].rhs_join_col
+ # The join promotion logic should never produce
+ # a LOUTER join for the base join - assert that.
+ assert j_col is not None
entry = self.where_class()
entry.add(
(Constraint(alias, j_col, None), 'isnull', True),
diff --git a/tests/regressiontests/aggregation_regress/tests.py b/tests/regressiontests/aggregation_regress/tests.py
index b9f3ab27eb..af0f421502 100644
--- a/tests/regressiontests/aggregation_regress/tests.py
+++ b/tests/regressiontests/aggregation_regress/tests.py
@@ -878,3 +878,14 @@ class AggregationTests(TestCase):
connection.ops.convert_values(testData, testField),
testData
)
+
+ def test_annotate_joins(self):
+ """
+ Test that the base table's join isn't promoted to LOUTER. This could
+ cause the query generation to fail if there is an exclude() for fk-field
+ in the query, too. Refs #19087.
+ """
+ qs = Book.objects.annotate(n=Count('pk'))
+ self.assertIs(qs.query.alias_map['aggregation_regress_book'].join_type, None)
+ # Check that the query executes without problems.
+ self.assertEqual(len(qs.exclude(publisher=-1)), 6)