Refs #27149 -- Based recursive nested subquery detection on sys.getrecursionlimit().
This makes sure the test_avoid_infinite_loop_on_too_many_subqueries test doesn't fail on systems with a non-default recursion limit.
This commit is contained in:
parent
9ac8520fcd
commit
c0969ee227
|
@ -9,6 +9,7 @@ all about the internals of models in order to get the information it needs.
|
||||||
import difflib
|
import difflib
|
||||||
import functools
|
import functools
|
||||||
import inspect
|
import inspect
|
||||||
|
import sys
|
||||||
import warnings
|
import warnings
|
||||||
from collections import Counter, namedtuple
|
from collections import Counter, namedtuple
|
||||||
from collections.abc import Iterator, Mapping
|
from collections.abc import Iterator, Mapping
|
||||||
|
@ -883,7 +884,11 @@ class Query(BaseExpression):
|
||||||
# No clashes between self and outer query should be possible.
|
# No clashes between self and outer query should be possible.
|
||||||
return
|
return
|
||||||
|
|
||||||
local_recursion_limit = 67 # explicitly avoid infinite loop
|
# Explicitly avoid infinite loop. The constant divider is based on how
|
||||||
|
# much depth recursive subquery references add to the stack. This value
|
||||||
|
# might need to be adjusted when adding or removing function calls from
|
||||||
|
# the code path in charge of performing these operations.
|
||||||
|
local_recursion_limit = sys.getrecursionlimit() // 16
|
||||||
for pos, prefix in enumerate(prefix_gen()):
|
for pos, prefix in enumerate(prefix_gen()):
|
||||||
if prefix not in self.subq_aliases:
|
if prefix not in self.subq_aliases:
|
||||||
self.alias_prefix = prefix
|
self.alias_prefix = prefix
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import datetime
|
import datetime
|
||||||
import pickle
|
import pickle
|
||||||
|
import sys
|
||||||
import unittest
|
import unittest
|
||||||
from operator import attrgetter
|
from operator import attrgetter
|
||||||
|
|
||||||
|
@ -402,10 +403,10 @@ class Queries1Tests(TestCase):
|
||||||
|
|
||||||
def test_avoid_infinite_loop_on_too_many_subqueries(self):
|
def test_avoid_infinite_loop_on_too_many_subqueries(self):
|
||||||
x = Tag.objects.filter(pk=1)
|
x = Tag.objects.filter(pk=1)
|
||||||
local_recursion_limit = 67
|
local_recursion_limit = sys.getrecursionlimit() // 16
|
||||||
msg = 'Maximum recursion depth exceeded: too many subqueries.'
|
msg = 'Maximum recursion depth exceeded: too many subqueries.'
|
||||||
with self.assertRaisesMessage(RuntimeError, msg):
|
with self.assertRaisesMessage(RuntimeError, msg):
|
||||||
for i in range(local_recursion_limit * 2):
|
for i in range(local_recursion_limit + 2):
|
||||||
x = Tag.objects.filter(pk__in=x)
|
x = Tag.objects.filter(pk__in=x)
|
||||||
|
|
||||||
def test_reasonable_number_of_subq_aliases(self):
|
def test_reasonable_number_of_subq_aliases(self):
|
||||||
|
|
Loading…
Reference in New Issue