Refs #32143 -- Removed superflous constraints on excluded query.

The outer query reference is not necessary when alias can be reused and
can even be harmful by confusing query planers.

Refs #34597.
This commit is contained in:
Simon Charette 2023-06-14 00:28:42 -04:00 committed by Mariusz Felisiak
parent cfc9c94d97
commit 1c4f5f314e
2 changed files with 15 additions and 5 deletions

View File

@ -2020,10 +2020,11 @@ class Query(BaseExpression):
lookup = lookup_class(pk.get_col(query.select[0].alias), pk.get_col(alias))
query.where.add(lookup, AND)
query.external_aliases[alias] = True
else:
lookup_class = select_field.get_lookup("exact")
lookup = lookup_class(col, ResolvedOuterRef(trimmed_prefix))
query.where.add(lookup, AND)
lookup_class = select_field.get_lookup("exact")
lookup = lookup_class(col, ResolvedOuterRef(trimmed_prefix))
query.where.add(lookup, AND)
condition, needed_inner = self.build_filter(Exists(query))
if contains_louter:

View File

@ -3231,7 +3231,7 @@ class ExcludeTests(TestCase):
[self.r2],
)
def test_ticket14511(self):
def test_exclude_m2m_through(self):
alex = Person.objects.get_or_create(name="Alex")[0]
jane = Person.objects.get_or_create(name="Jane")[0]
@ -3267,7 +3267,16 @@ class ExcludeTests(TestCase):
.distinct()
.order_by("name")
)
self.assertSequenceEqual(alex_nontech_employers, [google, intel, microsoft])
with self.assertNumQueries(1) as ctx:
self.assertSequenceEqual(alex_nontech_employers, [google, intel, microsoft])
sql = ctx.captured_queries[0]["sql"]
# Company's ID should appear in SELECT and INNER JOIN, not in EXISTS as
# the outer query reference is not necessary when an alias is reused.
company_id = "%s.%s" % (
connection.ops.quote_name(Company._meta.db_table),
connection.ops.quote_name(Company._meta.get_field("id").column),
)
self.assertEqual(sql.count(company_id), 2)
def test_exclude_reverse_fk_field_ref(self):
tag = Tag.objects.create()