Using querysets as an rvalue in filter() calls was causing an unnecessary

database query, due to a bool() call. This change stops that behaviour.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@9715 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Malcolm Tredinnick 2009-01-08 05:16:21 +00:00
parent d00c013cc8
commit d068ad0c01
3 changed files with 17 additions and 0 deletions

View File

@ -651,6 +651,10 @@ class QuerySet(object):
obj = self.values("pk") obj = self.values("pk")
return obj.query.as_nested_sql() return obj.query.as_nested_sql()
# When used as part of a nested query, a queryset will never be an "always
# empty" result.
value_annotation = True
class ValuesQuerySet(QuerySet): class ValuesQuerySet(QuerySet):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(ValuesQuerySet, self).__init__(*args, **kwargs) super(ValuesQuerySet, self).__init__(*args, **kwargs)
@ -795,6 +799,10 @@ class EmptyQuerySet(QuerySet):
# (it raises StopIteration immediately). # (it raises StopIteration immediately).
yield iter([]).next() yield iter([]).next()
# EmptyQuerySet is always an empty result in where-clauses (and similar
# situations).
value_annotation = False
def get_cached_row(klass, row, index_start, max_depth=0, cur_depth=0, def get_cached_row(klass, row, index_start, max_depth=0, cur_depth=0,
requested=None): requested=None):

View File

@ -66,6 +66,8 @@ class WhereNode(tree.Node):
# here in the future (using Python types is suggested for consistency). # here in the future (using Python types is suggested for consistency).
if isinstance(value, datetime.datetime): if isinstance(value, datetime.datetime):
annotation = datetime.datetime annotation = datetime.datetime
elif hasattr(value, 'value_annotation'):
annotation = value.value_annotation
else: else:
annotation = bool(value) annotation = bool(value)

View File

@ -1015,6 +1015,13 @@ performance problems on backends like MySQL.
>>> Annotation.objects.filter(notes__in=Note.objects.filter(note="n1")) >>> Annotation.objects.filter(notes__in=Note.objects.filter(note="n1"))
[<Annotation: a1>] [<Annotation: a1>]
Nested queries should not evaluate the inner query as part of constructing the
SQL. This test verifies this: if the inner query is evaluated, the outer "in"
lookup will raise an EmptyResultSet exception (as the inner query returns
nothing).
>>> print Annotation.objects.filter(notes__in=Note.objects.filter(note="xyzzy")).query
SELECT ...
"""} """}
# In Python 2.3 and the Python 2.6 beta releases, exceptions raised in __len__ # In Python 2.3 and the Python 2.6 beta releases, exceptions raised in __len__