1
0
mirror of https://github.com/django/django.git synced 2025-03-06 07:22:32 +00:00

[5.2.x] Refs #36181 -- Removed the obsolete SubqueryConstraint machinery.

Adding proper support for subquery right-hand-sides to TupleIn made it
obsolete.

Backport of d386405e04dac50656af50d100a14efdf8c58e8f from main

Co-authored-by: Simon Charette <charette.s@gmail.com>
This commit is contained in:
Mariusz Felisiak 2025-02-15 17:48:53 +01:00 committed by GitHub
parent 8b1e324ca4
commit c80c81163e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 16 additions and 71 deletions

View File

@ -1,28 +1,20 @@
from django.core.exceptions import FieldError, FullResultSet
from django.db.models.expressions import Col
from django.db.models.sql import compiler
from django.db.models.sql.compiler import SQLAggregateCompiler, SQLCompiler
from django.db.models.sql.compiler import SQLDeleteCompiler as BaseSQLDeleteCompiler
from django.db.models.sql.compiler import SQLInsertCompiler
from django.db.models.sql.compiler import SQLUpdateCompiler as BaseSQLUpdateCompiler
__all__ = [
"SQLAggregateCompiler",
"SQLCompiler",
"SQLDeleteCompiler",
"SQLInsertCompiler",
"SQLUpdateCompiler",
]
class SQLCompiler(compiler.SQLCompiler):
def as_subquery_condition(self, alias, columns, compiler):
qn = compiler.quote_name_unless_alias
qn2 = self.connection.ops.quote_name
sql, params = self.as_sql()
return (
"(%s) IN (%s)"
% (
", ".join("%s.%s" % (qn(alias), qn2(column)) for column in columns),
sql,
),
params,
)
class SQLInsertCompiler(compiler.SQLInsertCompiler, SQLCompiler):
pass
class SQLDeleteCompiler(compiler.SQLDeleteCompiler, SQLCompiler):
class SQLDeleteCompiler(BaseSQLDeleteCompiler):
def as_sql(self):
# Prefer the non-standard DELETE FROM syntax over the SQL generated by
# the SQLDeleteCompiler's default implementation when multiple tables
@ -52,7 +44,7 @@ class SQLDeleteCompiler(compiler.SQLDeleteCompiler, SQLCompiler):
return " ".join(result), tuple(params)
class SQLUpdateCompiler(compiler.SQLUpdateCompiler, SQLCompiler):
class SQLUpdateCompiler(BaseSQLUpdateCompiler):
def as_sql(self):
update_query, update_params = super().as_sql()
# MySQL and MariaDB support UPDATE ... ORDER BY syntax.
@ -78,7 +70,3 @@ class SQLUpdateCompiler(compiler.SQLUpdateCompiler, SQLCompiler):
# removed in .update() and cannot be resolved.
pass
return update_query, update_params
class SQLAggregateCompiler(compiler.SQLAggregateCompiler, SQLCompiler):
pass

View File

@ -84,21 +84,12 @@ class RelatedIn(In):
def as_sql(self, compiler, connection):
if isinstance(self.lhs, ColPairs):
from django.db.models.sql.where import SubqueryConstraint
if self.rhs_is_direct_value():
values = [get_normalized_value(value, self.lhs) for value in self.rhs]
lookup = TupleIn(self.lhs, values)
return compiler.compile(lookup)
else:
return compiler.compile(
SubqueryConstraint(
self.lhs.alias,
[target.column for target in self.lhs.targets],
[source.name for source in self.lhs.sources],
self.rhs,
),
)
lookup = TupleIn(self.lhs, self.rhs)
return compiler.compile(lookup)
return super().as_sql(compiler, connection)

View File

@ -22,7 +22,6 @@ from django.db.models.sql.constants import (
SINGLE,
)
from django.db.models.sql.query import Query, get_order_dir
from django.db.models.sql.where import AND
from django.db.transaction import TransactionManagementError
from django.utils.functional import cached_property
from django.utils.hashable import make_hashable
@ -1661,19 +1660,6 @@ class SQLCompiler:
return list(result)
return result
def as_subquery_condition(self, alias, columns, compiler):
qn = compiler.quote_name_unless_alias
qn2 = self.connection.ops.quote_name
query = self.query.clone()
for index, select_col in enumerate(query.select):
lhs_sql, lhs_params = self.compile(select_col)
rhs = "%s.%s" % (qn(alias), qn2(columns[index]))
query.where.add(RawSQL("%s = %s" % (lhs_sql, rhs), lhs_params), AND)
sql, params = query.as_sql(compiler, self.connection)
return "EXISTS %s" % sql, params
def explain_query(self):
result = list(self.execute_sql())
# Some backends return 1 item tuples with strings, and others return

View File

@ -343,23 +343,3 @@ class ExtraWhere:
def as_sql(self, compiler=None, connection=None):
sqls = ["(%s)" % sql for sql in self.sqls]
return " AND ".join(sqls), list(self.params or ())
class SubqueryConstraint:
# Even if aggregates or windows would be used in a subquery,
# the outer query isn't interested about those.
contains_aggregate = False
contains_over_clause = False
def __init__(self, alias, columns, targets, query_object):
self.alias = alias
self.columns = columns
self.targets = targets
query_object.clear_ordering(clear_default=True)
self.query_object = query_object
def as_sql(self, compiler, connection):
query = self.query_object
query.set_values(self.targets)
query_compiler = query.get_compiler(connection=connection)
return query_compiler.as_subquery_condition(self.alias, self.columns, compiler)