[4.0.x] Fixed #33159 -- Reverted "Fixed #32970 -- Changed WhereNode.clone() to create a shallow copy of children."

This reverts commit e441847eca.

A shallow copy is not enough because querysets can be reused and
evaluated in nested nodes, which shouldn't mutate JOIN aliases.

Thanks Michal Čihař for the report.
Backport of 903aaa35e5 from main
This commit is contained in:
Mariusz Felisiak 2021-09-30 11:26:17 +02:00
parent b2a0978610
commit 93a42d43a6
2 changed files with 11 additions and 1 deletions

View File

@ -148,7 +148,11 @@ class WhereNode(tree.Node):
clone = self.__class__._new_instance(
children=None, connector=self.connector, negated=self.negated,
)
clone.children = self.children[:]
for child in self.children:
if hasattr(child, 'clone'):
clone.children.append(child.clone())
else:
clone.children.append(child)
return clone
def relabeled_clone(self, change_map):

View File

@ -1663,6 +1663,12 @@ class Queries5Tests(TestCase):
'bar %s'
)
def test_queryset_reuse(self):
# Using querysets doesn't mutate aliases.
authors = Author.objects.filter(Q(name='a1') | Q(name='nonexistent'))
self.assertEqual(Ranking.objects.filter(author__in=authors).get(), self.rank3)
self.assertEqual(authors.count(), 1)
class SelectRelatedTests(TestCase):
def test_tickets_3045_3288(self):