Skip to content

Commit

Permalink
Fixed #30704 -- Fixed crash of JSONField nested key and index transfo…
Browse files Browse the repository at this point in the history
…rms on expressions with params.

Thanks Florian Apolloner for the report and helping with tests.
  • Loading branch information
felixxm committed Aug 13, 2019
1 parent efa1908 commit c19ad2d
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 2 deletions.
2 changes: 1 addition & 1 deletion django/contrib/postgres/fields/jsonb.py
Expand Up @@ -107,7 +107,7 @@ def as_sql(self, compiler, connection):
previous = previous.lhs previous = previous.lhs
lhs, params = compiler.compile(previous) lhs, params = compiler.compile(previous)
if len(key_transforms) > 1: if len(key_transforms) > 1:
return "(%s %s %%s)" % (lhs, self.nested_operator), [key_transforms] + params return '(%s %s %%s)' % (lhs, self.nested_operator), params + [key_transforms]
try: try:
lookup = int(self.key_name) lookup = int(self.key_name)
except ValueError: except ValueError:
Expand Down
21 changes: 20 additions & 1 deletion tests/postgres_tests/test_json.py
Expand Up @@ -6,7 +6,9 @@
from django.core import checks, exceptions, serializers from django.core import checks, exceptions, serializers
from django.core.serializers.json import DjangoJSONEncoder from django.core.serializers.json import DjangoJSONEncoder
from django.db import connection from django.db import connection
from django.db.models import Count, Q from django.db.models import Count, F, Q
from django.db.models.expressions import RawSQL
from django.db.models.functions import Cast
from django.forms import CharField, Form, widgets from django.forms import CharField, Form, widgets
from django.test.utils import CaptureQueriesContext, isolate_apps from django.test.utils import CaptureQueriesContext, isolate_apps
from django.utils.html import escape from django.utils.html import escape
Expand Down Expand Up @@ -186,6 +188,23 @@ def test_ordering_grouping_by_key_transform(self):
operator.itemgetter('key', 'count'), operator.itemgetter('key', 'count'),
) )


def test_nested_key_transform_raw_expression(self):
expr = RawSQL('%s::jsonb', ['{"x": {"y": "bar"}}'])
self.assertSequenceEqual(
JSONModel.objects.filter(field__foo=KeyTransform('y', KeyTransform('x', expr))),
[self.objs[-1]],
)

def test_nested_key_transform_expression(self):
self.assertSequenceEqual(
JSONModel.objects.filter(field__d__0__isnull=False).annotate(
key=KeyTransform('d', 'field'),
chain=KeyTransform('f', KeyTransform('1', 'key')),
expr=KeyTransform('f', KeyTransform('1', Cast('key', JSONField()))),
).filter(chain=F('expr')),
[self.objs[8]],
)

def test_deep_values(self): def test_deep_values(self):
query = JSONModel.objects.values_list('field__k__l') query = JSONModel.objects.values_list('field__k__l')
self.assertSequenceEqual( self.assertSequenceEqual(
Expand Down

0 comments on commit c19ad2d

Please sign in to comment.