Fixed #19087 -- Ensured query's base table is never LOUTER joined
This fixes a regression created by join promotion logic refactoring:
01b9c3d519
Thanks to Ivan Virabyan for the report.
This commit is contained in:
parent
4797ad80da
commit
a62d53c032
|
@ -702,6 +702,11 @@ class Query(object):
|
||||||
aliases = list(aliases)
|
aliases = list(aliases)
|
||||||
while aliases:
|
while aliases:
|
||||||
alias = aliases.pop(0)
|
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_alias = self.alias_map[alias].lhs_alias
|
||||||
parent_louter = (parent_alias
|
parent_louter = (parent_alias
|
||||||
and self.alias_map[parent_alias].join_type == self.LOUTER)
|
and self.alias_map[parent_alias].join_type == self.LOUTER)
|
||||||
|
@ -1188,6 +1193,9 @@ class Query(object):
|
||||||
for alias in join_list:
|
for alias in join_list:
|
||||||
if self.alias_map[alias].join_type == self.LOUTER:
|
if self.alias_map[alias].join_type == self.LOUTER:
|
||||||
j_col = self.alias_map[alias].rhs_join_col
|
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 = self.where_class()
|
||||||
entry.add(
|
entry.add(
|
||||||
(Constraint(alias, j_col, None), 'isnull', True),
|
(Constraint(alias, j_col, None), 'isnull', True),
|
||||||
|
|
|
@ -878,3 +878,14 @@ class AggregationTests(TestCase):
|
||||||
connection.ops.convert_values(testData, testField),
|
connection.ops.convert_values(testData, testField),
|
||||||
testData
|
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)
|
||||||
|
|
Loading…
Reference in New Issue