mirror of
https://github.com/django/django.git
synced 2025-07-17 16:19:12 +00:00
[3.1.x] Refs #32096 -- Fixed __in lookup crash against key transforms for JSONField.
Regression in 6789ded0a6ab797f0dcdfa6ad5d1cfa46e23abcd and 1251772cb83aa4106f526fe00738e51c0eb59122. Thanks Simon Charette and Igor Jerosimić for the report. Backport of 7e1e198494d4fc72cf6e153f9d24fe2493c17dc1 from master
This commit is contained in:
parent
d94e777b66
commit
59fe0b8541
@ -369,27 +369,26 @@ class KeyTransformIsNull(lookups.IsNull):
|
|||||||
|
|
||||||
|
|
||||||
class KeyTransformIn(lookups.In):
|
class KeyTransformIn(lookups.In):
|
||||||
def process_rhs(self, compiler, connection):
|
def resolve_expression_parameter(self, compiler, connection, sql, param):
|
||||||
rhs, rhs_params = super().process_rhs(compiler, connection)
|
sql, params = super().resolve_expression_parameter(
|
||||||
if not connection.features.has_native_json_field:
|
compiler, connection, sql, param,
|
||||||
func = ()
|
)
|
||||||
|
if (
|
||||||
|
not hasattr(param, 'as_sql') and
|
||||||
|
not connection.features.has_native_json_field
|
||||||
|
):
|
||||||
if connection.vendor == 'oracle':
|
if connection.vendor == 'oracle':
|
||||||
func = []
|
value = json.loads(param)
|
||||||
for value in rhs_params:
|
if isinstance(value, (list, dict)):
|
||||||
value = json.loads(value)
|
sql = "JSON_QUERY(%s, '$.value')"
|
||||||
function = 'JSON_QUERY' if isinstance(value, (list, dict)) else 'JSON_VALUE'
|
else:
|
||||||
func.append("%s('%s', '$.value')" % (
|
sql = "JSON_VALUE(%s, '$.value')"
|
||||||
function,
|
params = (json.dumps({'value': value}),)
|
||||||
json.dumps({'value': value}),
|
|
||||||
))
|
|
||||||
func = tuple(func)
|
|
||||||
rhs_params = ()
|
|
||||||
elif connection.vendor == 'mysql' and connection.mysql_is_mariadb:
|
|
||||||
func = ("JSON_UNQUOTE(JSON_EXTRACT(%s, '$'))",) * len(rhs_params)
|
|
||||||
elif connection.vendor in {'sqlite', 'mysql'}:
|
elif connection.vendor in {'sqlite', 'mysql'}:
|
||||||
func = ("JSON_EXTRACT(%s, '$')",) * len(rhs_params)
|
sql = "JSON_EXTRACT(%s, '$')"
|
||||||
rhs = rhs % func
|
if connection.vendor == 'mysql' and connection.mysql_is_mariadb:
|
||||||
return rhs, rhs_params
|
sql = 'JSON_UNQUOTE(%s)' % sql
|
||||||
|
return sql, params
|
||||||
|
|
||||||
|
|
||||||
class KeyTransformExact(JSONExact):
|
class KeyTransformExact(JSONExact):
|
||||||
|
@ -241,7 +241,7 @@ class FieldGetDbPrepValueIterableMixin(FieldGetDbPrepValueMixin):
|
|||||||
if hasattr(param, 'resolve_expression'):
|
if hasattr(param, 'resolve_expression'):
|
||||||
param = param.resolve_expression(compiler.query)
|
param = param.resolve_expression(compiler.query)
|
||||||
if hasattr(param, 'as_sql'):
|
if hasattr(param, 'as_sql'):
|
||||||
sql, params = param.as_sql(compiler, connection)
|
sql, params = compiler.compile(param)
|
||||||
return sql, params
|
return sql, params
|
||||||
|
|
||||||
def batch_process_rhs(self, compiler, connection, rhs=None):
|
def batch_process_rhs(self, compiler, connection, rhs=None):
|
||||||
|
@ -25,3 +25,7 @@ Bugfixes
|
|||||||
:class:`~django.contrib.postgres.aggregates.ArrayAgg` and
|
:class:`~django.contrib.postgres.aggregates.ArrayAgg` and
|
||||||
:class:`~django.contrib.postgres.aggregates.StringAgg` with ``ordering``
|
:class:`~django.contrib.postgres.aggregates.StringAgg` with ``ordering``
|
||||||
on key transforms for :class:`~django.db.models.JSONField` (:ticket:`32096`).
|
on key transforms for :class:`~django.db.models.JSONField` (:ticket:`32096`).
|
||||||
|
|
||||||
|
* Fixed a regression in Django 3.1 that caused a crash of ``__in`` lookup when
|
||||||
|
using key transforms for :class:`~django.db.models.JSONField` in the lookup
|
||||||
|
value (:ticket:`32096`).
|
||||||
|
@ -631,6 +631,16 @@ class TestQuerying(TestCase):
|
|||||||
('value__0__in', [1], [self.objs[5]]),
|
('value__0__in', [1], [self.objs[5]]),
|
||||||
('value__0__in', [1, 3], [self.objs[5]]),
|
('value__0__in', [1, 3], [self.objs[5]]),
|
||||||
('value__foo__in', ['bar'], [self.objs[7]]),
|
('value__foo__in', ['bar'], [self.objs[7]]),
|
||||||
|
(
|
||||||
|
'value__foo__in',
|
||||||
|
[KeyTransform('foo', KeyTransform('bax', 'value'))],
|
||||||
|
[self.objs[7]],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'value__foo__in',
|
||||||
|
[KeyTransform('foo', KeyTransform('bax', 'value')), 'baz'],
|
||||||
|
[self.objs[7]],
|
||||||
|
),
|
||||||
('value__foo__in', ['bar', 'baz'], [self.objs[7]]),
|
('value__foo__in', ['bar', 'baz'], [self.objs[7]]),
|
||||||
('value__bar__in', [['foo', 'bar']], [self.objs[7]]),
|
('value__bar__in', [['foo', 'bar']], [self.objs[7]]),
|
||||||
('value__bar__in', [['foo', 'bar'], ['a']], [self.objs[7]]),
|
('value__bar__in', [['foo', 'bar'], ['a']], [self.objs[7]]),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user