diff options
| author | Simon Charette <charette.s@gmail.com> | 2025-09-17 01:56:40 -0400 |
|---|---|---|
| committer | Sarah Boyce <42296566+sarahboyce@users.noreply.github.com> | 2025-09-22 09:02:01 +0200 |
| commit | ffac97bf63ea803a6196d2097b4186e0865d9091 (patch) | |
| tree | 5fb97de15668bc153a17110b0cc15c86c8a4b55b | |
| parent | 359c1c6ff943b518b05f5780723e62ce5bda7be6 (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.py | 8 | ||||
| -rw-r--r-- | tests/model_fields/test_jsonfield.py | 6 |
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 = [ |
