From e62ea0bb9cbb54c1eef848871fe3eab2bad268dc Mon Sep 17 00:00:00 2001 From: Simon Charette Date: Wed, 26 Apr 2017 23:20:04 -0400 Subject: [PATCH] Refs #20939 -- Moved subquery ordering clearing optimization to the __in lookup. Queries could potentially be resolved in cases where ordering matter. --- django/db/models/lookups.py | 15 ++++++++++++--- django/db/models/sql/query.py | 6 ------ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/django/db/models/lookups.py b/django/db/models/lookups.py index 48e68d0b8b..78ed3e477f 100644 --- a/django/db/models/lookups.py +++ b/django/db/models/lookups.py @@ -367,9 +367,18 @@ class In(FieldGetDbPrepValueIterableMixin, BuiltinLookup): placeholder = '(' + ', '.join(sqls) + ')' return (placeholder, sqls_params) else: - if not getattr(self.rhs, 'has_select_fields', True): - self.rhs.clear_select_clause() - self.rhs.add_fields(['pk']) + from django.db.models.sql.query import Query # avoid circular import + if isinstance(self.rhs, Query): + query = self.rhs + # It's safe to drop ordering if the queryset isn't using + # slicing, distinct(*fields), or select_for_update(). + if (query.low_mark == 0 and query.high_mark is None and + not query.distinct_fields and + not query.select_for_update): + query.clear_ordering(True) + if not query.has_select_fields: + query.clear_select_clause() + query.add_fields(['pk']) return super().process_rhs(compiler, connection) def get_rhs_op(self, connection, rhs): diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index a1c1c4be38..c8cb095d09 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -981,12 +981,6 @@ class Query: # Subqueries need to use a different set of aliases than the outer query. clone.bump_prefix(query) clone.subquery = True - # It's safe to drop ordering if the queryset isn't using slicing, - # distinct(*fields) or select_for_update(). - if (self.low_mark == 0 and self.high_mark is None and - not self.distinct_fields and - not self.select_for_update): - clone.clear_ordering(True) return clone def prepare_lookup_value(self, value, lookups, can_reuse, allow_joins=True):