Opened 8 years ago

Closed 8 years ago

#27693 closed Bug (fixed)

Case insensitive lookups on JSONField nested values

Reported by: Harris Lapiroff Owned by: Simon Charette <charette.s@…>
Component: contrib.postgres Version: dev
Severity: Normal Keywords:
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Currently JSONField doesn't support case-insensitive lookups such as iexact. This is not documented as working, so I'm marking this as a new feature, but it's something I think Django can and should support.

Attempting to use an iexact lookup (e.g., OrganizationPerson.objects.filter(data__field2__iexact='Ethelfort')) results in a SQL error:

django.db.utils.ProgrammingError: function upper(jsonb) does not exist
LINE 1: ...st" FROM "organizations_organizationperson" WHERE UPPER("org...
                                                             ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.

I believe this is just a case of misplaced parens and quotes. Similar functionality (though still not documented) does work on HStoreFields. Here's an example of the successful SQL Django generates for an iexact lookup on an HStoreField.

SELECT "organizations_organizationperson"."id", "organizations_organizationperson"."organization_id", "organizations_organizationperson"."person_id", "organizations_organizationperson"."data", "organizations_organizationperson"."test" FROM "organizations_organizationperson" WHERE UPPER(("organizations_organizationperson"."test" -> 'foo')::text) = UPPER('Bar') LIMIT 21

And here's the unsuccessful SQL Django generates for an iexact lookup on a JSONField, which generates the error above:

SELECT "organizations_organizationperson"."id", "organizations_organizationperson"."organization_id", "organizations_organizationperson"."person_id", "organizations_organizationperson"."data", "organizations_organizationperson"."test" FROM "organizations_organizationperson" WHERE UPPER("organizations_organizationperson"."data" -> 'field2'::text) = UPPER('Ethelfort') LIMIT 21

I don't have an ORM-level fix for correcting the query, but a proper query that works as expected just includes a couple more parens and quotes in the WHERE clause:

SELECT "organizations_organizationperson"."id", "organizations_organizationperson"."organization_id", "organizations_organizationperson"."person_id", "organizations_organizationperson"."data", "organizations_organizationperson"."test" FROM "organizations_organizationperson" WHERE UPPER(("organizations_organizationperson"."data" -> 'field2')::text) = UPPER('"Ethelfort"') LIMIT 21

Change History (6)

comment:1 by Tim Graham, 8 years ago

Did you reproduce this on master? I thought it might be fixed by #27257 -- Fixed builtin text lookups on JSONField keys.

comment:2 by Stephen Burrows, 8 years ago

Just tested this on master, and I can confirm that the iexact lookup works - except that you need to add the quotes for the query in yourself. i.e.

>>> x = OrganizationPerson.objects.first()
>>> x.data
{'field2': 'Ethelfort'}
>>> OrganizationPerson.objects.filter(data__field2__iexact='Ethelfort')
<QuerySet []>
>>> OrganizationPerson.objects.filter(data__field2__iexact='"Ethelfort"')
<QuerySet [<OrganizationPerson: OrganizationPerson object>]>

Knowing how the SQL ends up looking, this sort of makes sense to me - but if I didn't know that from this ticket I would be completely lost.

comment:3 by Simon Charette, 8 years ago

Triage Stage: UnreviewedAccepted
Type: New featureBug
Version: 1.10master

It looks like the iexact case was overlooked by #27257. It believe it would be a simple matter of defining a KeyTransformIExact(KeyTransformTextLookupMixin, builtin_lookups.IExact) subclass and registering it as a KeyTransform lookup. See cecef94275118dc49a1b0d89d3ca9734e2ec9776.

comment:4 by Simon Charette, 8 years ago

Has patch: set

comment:5 by Tim Graham, 8 years ago

Triage Stage: AcceptedReady for checkin

comment:6 by Simon Charette <charette.s@…>, 8 years ago

Owner: set to Simon Charette <charette.s@…>
Resolution: fixed
Status: newclosed

In d9767602:

Fixed #27693, Refs #27257 -- Fixed iexact lookup on JSONField keys.

Thanks Harris Lapiroff for the report.

Note: See TracTickets for help on using tickets.
Back to Top