summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorJacob Walls <jacobtylerwalls@gmail.com>2024-12-29 01:13:48 -0800
committerSarah Boyce <42296566+sarahboyce@users.noreply.github.com>2025-08-04 10:14:01 +0200
commit8914f4703cf03e2a01683c4ba00f5ae7d3fa449d (patch)
tree5331d4fac059c893d16875710dc8539ff91bdc81 /django
parent079d31e698fa08dd92e2bc4f3fe9b4817a214419 (diff)
Fixed #35972 -- Fixed lookup crashes after subquery annotations.
Diffstat (limited to 'django')
-rw-r--r--django/contrib/gis/db/models/lookups.py8
-rw-r--r--django/contrib/postgres/search.py10
-rw-r--r--django/db/backends/base/schema.py3
-rw-r--r--django/db/models/expressions.py4
-rw-r--r--django/db/models/functions/comparison.py2
-rw-r--r--django/db/models/lookups.py12
6 files changed, 21 insertions, 18 deletions
diff --git a/django/contrib/gis/db/models/lookups.py b/django/contrib/gis/db/models/lookups.py
index 3d30ffed5c..b9e5e47b27 100644
--- a/django/contrib/gis/db/models/lookups.py
+++ b/django/contrib/gis/db/models/lookups.py
@@ -55,7 +55,7 @@ class GISLookup(Lookup):
def get_db_prep_lookup(self, value, connection):
# get_db_prep_lookup is called by process_rhs from super class
- return ("%s", [connection.ops.Adapter(value)])
+ return ("%s", (connection.ops.Adapter(value),))
def process_rhs(self, compiler, connection):
if isinstance(self.rhs, Query):
@@ -284,7 +284,7 @@ class RelateLookup(GISLookup):
elif not isinstance(pattern, str) or not self.pattern_regex.match(pattern):
raise ValueError('Invalid intersection matrix pattern "%s".' % pattern)
sql, params = super().process_rhs(compiler, connection)
- return sql, [*params, pattern]
+ return sql, (*params, pattern)
@BaseSpatialField.register_lookup
@@ -352,7 +352,7 @@ class DWithinLookup(DistanceLookupBase):
dist_sql, dist_params = self.process_distance(compiler, connection)
self.template_params["value"] = dist_sql
rhs_sql, params = super().process_rhs(compiler, connection)
- return rhs_sql, params + dist_params
+ return rhs_sql, (*params, *dist_params)
class DistanceLookupFromFunction(DistanceLookupBase):
@@ -367,7 +367,7 @@ class DistanceLookupFromFunction(DistanceLookupBase):
dist_sql, dist_params = self.process_distance(compiler, connection)
return (
"%(func)s %(op)s %(dist)s" % {"func": sql, "op": self.op, "dist": dist_sql},
- params + dist_params,
+ (*params, *dist_params),
)
diff --git a/django/contrib/postgres/search.py b/django/contrib/postgres/search.py
index 24f7a497da..4ab27605cb 100644
--- a/django/contrib/postgres/search.py
+++ b/django/contrib/postgres/search.py
@@ -27,7 +27,7 @@ class SearchVectorExact(Lookup):
def as_sql(self, qn, connection):
lhs, lhs_params = self.process_lhs(qn, connection)
rhs, rhs_params = self.process_rhs(qn, connection)
- params = lhs_params + rhs_params
+ params = (*lhs_params, *rhs_params)
return "%s @@ %s" % (lhs, rhs), params
@@ -148,7 +148,7 @@ class SearchVector(SearchVectorCombinable, Func):
weight_sql, extra_params = compiler.compile(clone.weight)
sql = "setweight({}, {})".format(sql, weight_sql)
- return sql, config_params + params + extra_params
+ return sql, (*config_params, *params, *extra_params)
class CombinedSearchVector(SearchVectorCombinable, CombinedExpression):
@@ -318,13 +318,13 @@ class SearchHeadline(Func):
def as_sql(self, compiler, connection, function=None, template=None):
options_sql = ""
- options_params = []
+ options_params = ()
if self.options:
- options_params.append(
+ options_params = (
", ".join(
connection.ops.compose_sql(f"{option}=%s", [value])
for option, value in self.options.items()
- )
+ ),
)
options_sql = ", %s"
sql, params = super().as_sql(
diff --git a/django/db/backends/base/schema.py b/django/db/backends/base/schema.py
index 5262864e7f..cc33740195 100644
--- a/django/db/backends/base/schema.py
+++ b/django/db/backends/base/schema.py
@@ -1,6 +1,7 @@
import logging
import operator
from datetime import datetime
+from itertools import chain
from django.conf import settings
from django.core.exceptions import FieldError
@@ -1160,7 +1161,7 @@ class BaseDatabaseSchemaEditor:
# Combine actions together if we can (e.g. postgres)
if self.connection.features.supports_combined_alters and actions:
sql, params = tuple(zip(*actions))
- actions = [(", ".join(sql), sum(params, []))]
+ actions = [(", ".join(sql), tuple(chain(*params)))]
# Apply those actions
for sql, params in actions:
self.execute(
diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py
index 012a7c346b..1168c7ddbd 100644
--- a/django/db/models/expressions.py
+++ b/django/db/models/expressions.py
@@ -1127,7 +1127,7 @@ class Func(SQLiteNumericMixin, Expression):
template = template or data.get("template", self.template)
arg_joiner = arg_joiner or data.get("arg_joiner", self.arg_joiner)
data["expressions"] = data["field"] = arg_joiner.join(sql_parts)
- return template % data, params
+ return template % data, tuple(params)
def copy(self):
copy = super().copy()
@@ -1323,7 +1323,7 @@ class Col(Expression):
alias, column = self.alias, self.target.column
identifiers = (alias, column) if alias else (column,)
sql = ".".join(map(compiler.quote_name_unless_alias, identifiers))
- return sql, []
+ return sql, ()
def relabeled_clone(self, relabels):
if self.alias is None:
diff --git a/django/db/models/functions/comparison.py b/django/db/models/functions/comparison.py
index 11af0c0750..8f7493f2fd 100644
--- a/django/db/models/functions/comparison.py
+++ b/django/db/models/functions/comparison.py
@@ -26,7 +26,7 @@ class Cast(Func):
compiler, connection, template=template, **extra_context
)
format_string = "%H:%M:%f" if db_type == "time" else "%Y-%m-%d %H:%M:%f"
- params.insert(0, format_string)
+ params = (format_string, *params)
return sql, params
elif db_type == "date":
template = "date(%(expressions)s)"
diff --git a/django/db/models/lookups.py b/django/db/models/lookups.py
index 51817710e9..65128732fd 100644
--- a/django/db/models/lookups.py
+++ b/django/db/models/lookups.py
@@ -101,7 +101,7 @@ class Lookup(Expression):
return Value(self.lhs)
def get_db_prep_lookup(self, value, connection):
- return ("%s", [value])
+ return ("%s", (value,))
def process_lhs(self, compiler, connection, lhs=None):
lhs = lhs or self.lhs
@@ -415,7 +415,7 @@ class IExact(BuiltinLookup):
def process_rhs(self, qn, connection):
rhs, params = super().process_rhs(qn, connection)
if params:
- params[0] = connection.ops.prep_for_iexact_query(params[0])
+ params = (connection.ops.prep_for_iexact_query(params[0]), *params[1:])
return rhs, params
@@ -603,8 +603,9 @@ class PatternLookup(BuiltinLookup):
def process_rhs(self, qn, connection):
rhs, params = super().process_rhs(qn, connection)
if self.rhs_is_direct_value() and params and not self.bilateral_transforms:
- params[0] = self.param_pattern % connection.ops.prep_for_like_query(
- params[0]
+ params = (
+ self.param_pattern % connection.ops.prep_for_like_query(params[0]),
+ *params[1:],
)
return rhs, params
@@ -686,8 +687,9 @@ class Regex(BuiltinLookup):
else:
lhs, lhs_params = self.process_lhs(compiler, connection)
rhs, rhs_params = self.process_rhs(compiler, connection)
+ params = (*lhs_params, *rhs_params)
sql_template = connection.ops.regex_lookup(self.lookup_name)
- return sql_template % (lhs, rhs), lhs_params + rhs_params
+ return sql_template % (lhs, rhs), params
@Field.register_lookup