Skip to content

Commit 3a505c7

Browse files
charettestimgraham
authored andcommitted
Refs #27149, #29542 -- Simplified subquery parentheses wrapping logic.
1 parent 3543129 commit 3a505c7

File tree

4 files changed

+8
-21
lines changed

4 files changed

+8
-21
lines changed

django/db/models/expressions.py

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,23 +1023,13 @@ def external_aliases(self):
10231023
def as_sql(self, compiler, connection, template=None, **extra_context):
10241024
connection.ops.check_expression_support(self)
10251025
template_params = {**self.extra, **extra_context}
1026-
template_params['subquery'], sql_params = self.query.as_sql(compiler, connection)
1026+
subquery_sql, sql_params = self.query.as_sql(compiler, connection)
1027+
template_params['subquery'] = subquery_sql[1:-1]
10271028

10281029
template = template or template_params.get('template', self.template)
10291030
sql = template % template_params
10301031
return sql, sql_params
10311032

1032-
def _prepare(self, output_field):
1033-
# This method will only be called if this instance is the "rhs" in an
1034-
# expression: the wrapping () must be removed (as the expression that
1035-
# contains this will provide them). SQLite evaluates ((subquery))
1036-
# differently than the other databases.
1037-
if self.template == '(%(subquery)s)':
1038-
clone = self.copy()
1039-
clone.template = '%(subquery)s'
1040-
return clone
1041-
return self
1042-
10431033
def get_group_by_cols(self, alias=None):
10441034
if alias:
10451035
return [Ref(alias, self)]

django/db/models/lookups.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,7 @@ def process_rhs(self, compiler, connection):
8989
value = self.apply_bilateral_transforms(value)
9090
value = value.resolve_expression(compiler.query)
9191
if hasattr(value, 'as_sql'):
92-
sql, params = compiler.compile(value)
93-
return '(' + sql + ')', params
92+
return compiler.compile(value)
9493
else:
9594
return self.get_db_prep_lookup(value, connection)
9695

django/db/models/sql/compiler.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
from django.core.exceptions import EmptyResultSet, FieldError
77
from django.db.models.constants import LOOKUP_SEP
8-
from django.db.models.expressions import OrderBy, Random, RawSQL, Ref, Subquery
8+
from django.db.models.expressions import OrderBy, Random, RawSQL, Ref
99
from django.db.models.query_utils import QueryWrapper, select_related_descend
1010
from django.db.models.sql.constants import (
1111
CURSOR, GET_ITERATOR_CHUNK_SIZE, MULTI, NO_RESULTS, ORDER_DIR, SINGLE,
@@ -126,11 +126,6 @@ def get_group_by(self, select, order_by):
126126

127127
for expr in expressions:
128128
sql, params = self.compile(expr)
129-
if isinstance(expr, Subquery) and not sql.startswith('('):
130-
# Subquery expression from HAVING clause may not contain
131-
# wrapping () because they could be removed when a subquery is
132-
# the "rhs" in an expression (see Subquery._prepare()).
133-
sql = '(%s)' % sql
134129
if (sql, tuple(params)) not in seen:
135130
result.append((sql, params))
136131
seen.add((sql, tuple(params)))

django/db/models/sql/query.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1022,7 +1022,10 @@ def resolve_expression(self, query, *args, **kwargs):
10221022
return clone
10231023

10241024
def as_sql(self, compiler, connection):
1025-
return self.get_compiler(connection=connection).as_sql()
1025+
sql, params = self.get_compiler(connection=connection).as_sql()
1026+
if self.subquery:
1027+
sql = '(%s)' % sql
1028+
return sql, params
10261029

10271030
def resolve_lookup_value(self, value, can_reuse, allow_joins, simple_col):
10281031
if hasattr(value, 'resolve_expression'):

0 commit comments

Comments
 (0)