summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Charette <charette.s@gmail.com>2025-09-17 01:56:40 -0400
committerSarah Boyce <42296566+sarahboyce@users.noreply.github.com>2025-09-22 09:02:01 +0200
commitffac97bf63ea803a6196d2097b4186e0865d9091 (patch)
tree5fb97de15668bc153a17110b0cc15c86c8a4b55b
parent359c1c6ff943b518b05f5780723e62ce5bda7be6 (diff)
[6.0.x] Fixed #36612 -- Fixed a KeyTextTransform crash on MySQL against annotations.
MySQL only supports the ->> when used directly against columns, this can be inferred by the presence of lhs.output_field.model as model bounds fields are directly tied to columns. Purposely don't systematically switch to using JSON_QUOTE(JSON_EXTRACT(...)) as there might be functional indices out there that rely on the SQL remaining stable between versions. Thanks Jacob Tavener for the report. Backport of af84cfba5970fda8306860b650937701c7c03c6f from main.
-rw-r--r--django/db/models/fields/json.py8
-rw-r--r--tests/model_fields/test_jsonfield.py6
2 files changed, 12 insertions, 2 deletions
diff --git a/django/db/models/fields/json.py b/django/db/models/fields/json.py
index d544caf3e5..e0aa5c622b 100644
--- a/django/db/models/fields/json.py
+++ b/django/db/models/fields/json.py
@@ -424,8 +424,12 @@ class KeyTextTransform(KeyTransform):
output_field = TextField()
def as_mysql(self, compiler, connection):
- if connection.mysql_is_mariadb:
- # MariaDB doesn't support -> and ->> operators (see MDEV-13594).
+ # The ->> operator is not supported on MariaDB (see MDEV-13594) and
+ # only supported against columns on MySQL.
+ if (
+ connection.mysql_is_mariadb
+ or getattr(self.lhs.output_field, "model", None) is None
+ ):
sql, params = super().as_mysql(compiler, connection)
return "JSON_UNQUOTE(%s)" % sql, params
else:
diff --git a/tests/model_fields/test_jsonfield.py b/tests/model_fields/test_jsonfield.py
index 16ab8887a9..b16499d198 100644
--- a/tests/model_fields/test_jsonfield.py
+++ b/tests/model_fields/test_jsonfield.py
@@ -1160,6 +1160,12 @@ class TestQuerying(TestCase):
True,
)
+ def test_cast_with_key_text_transform(self):
+ obj = NullableJSONModel.objects.annotate(
+ json_data=Cast(Value({"foo": "bar"}, JSONField()), JSONField())
+ ).get(pk=self.objs[0].pk, json_data__foo__icontains="bar")
+ self.assertEqual(obj, self.objs[0])
+
@skipUnlessDBFeature("supports_json_field_contains")
def test_contains_contained_by_with_key_transform(self):
tests = [