[Django] #28872: JSONField __in operator breaks when given a values_list()

93 views
Skip to first unread message

Django

unread,
Dec 1, 2017, 11:08:56 AM12/1/17
to django-...@googlegroups.com
#28872: JSONField __in operator breaks when given a values_list()
--------------------------------------------+------------------------
Reporter: Jerome Leclanche | Owner: (none)
Type: Bug | Status: new
Component: contrib.postgres | Version: 1.11
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
--------------------------------------------+------------------------
Prerequisites

1. Create a model MyModel1 with the field `resource = JSONField()`.
2. Create another model MyModel2 with a field `id =
CharField(max_length=255)`

Reproduce by doing
MyModel1.objects.filter(resource__foo__id__in=MyModel2.objects.all().values_list("id"))

Expected result: Should look at MyModel1 for objects with `resource`
matching `{"foo": {"id": <id>}}`.

Actual result:

ERROR: operator does not exist: jsonb = character varying
LINE 1: ...AND ("resource" #> '{foo,id}') IN (SELECT...

The actual issue is that when passing a values_list() to __in, the values
list is not cast to jsonb (unlike when passing a text type). In the
resulting sql, we can see `IN (SELECT U0."id" AS Col1 FROM mymodel2 U0
...)`. Wrapping `to_json(U0."id")` solves the issue.

--
Ticket URL: <https://code.djangoproject.com/ticket/28872>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Dec 1, 2017, 11:09:22 AM12/1/17
to django-...@googlegroups.com
#28872: JSONField __in operator breaks when given a values_list()
----------------------------------+--------------------------------------

Reporter: Jerome Leclanche | Owner: (none)
Type: Bug | Status: new
Component: contrib.postgres | Version: 1.11
Severity: Normal | Resolution:

Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
----------------------------------+--------------------------------------
Description changed by Jerome Leclanche:

Old description:

> Prerequisites
>
> 1. Create a model MyModel1 with the field `resource = JSONField()`.
> 2. Create another model MyModel2 with a field `id =
> CharField(max_length=255)`
>
> Reproduce by doing
> MyModel1.objects.filter(resource__foo__id__in=MyModel2.objects.all().values_list("id"))
>
> Expected result: Should look at MyModel1 for objects with `resource`
> matching `{"foo": {"id": <id>}}`.
>
> Actual result:
>
> ERROR: operator does not exist: jsonb = character varying
> LINE 1: ...AND ("resource" #> '{foo,id}') IN (SELECT...
>
> The actual issue is that when passing a values_list() to __in, the values
> list is not cast to jsonb (unlike when passing a text type). In the
> resulting sql, we can see `IN (SELECT U0."id" AS Col1 FROM mymodel2 U0
> ...)`. Wrapping `to_json(U0."id")` solves the issue.

New description:

Prerequisites

1. Create a model MyModel1 with the field `resource = JSONField()`.
2. Create another model MyModel2 with a field `id =
CharField(max_length=255)`

Reproduce by doing
`MyModel1.objects.filter(resource__foo__id__in=MyModel2.objects.all().values_list("id"))`

Expected result: Should look at MyModel1 for objects with `resource`
matching `{"foo": {"id": <id>}}`.

Actual result:

ERROR: operator does not exist: jsonb = character varying
LINE 1: ...AND ("resource" #> '{foo,id}') IN (SELECT...

The actual issue is that when passing a values_list() to __in, the values
list is not cast to jsonb (unlike when passing a text type). In the
resulting sql, we can see `IN (SELECT U0."id" AS Col1 FROM mymodel2 U0
...)`. Wrapping `to_json(U0."id")` solves the issue.

--

--
Ticket URL: <https://code.djangoproject.com/ticket/28872#comment:1>

Django

unread,
Dec 27, 2017, 1:21:41 PM12/27/17
to django-...@googlegroups.com
#28872: JSONField __in operator breaks when given a values_list()
----------------------------------+------------------------------------

Reporter: Jerome Leclanche | Owner: (none)
Type: Bug | Status: new
Component: contrib.postgres | Version: 1.11
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
----------------------------------+------------------------------------
Changes (by Tim Graham):

* stage: Unreviewed => Accepted


Old description:

> Prerequisites
>
> 1. Create a model MyModel1 with the field `resource = JSONField()`.
> 2. Create another model MyModel2 with a field `id =
> CharField(max_length=255)`
>
> Reproduce by doing
> `MyModel1.objects.filter(resource__foo__id__in=MyModel2.objects.all().values_list("id"))`
>
> Expected result: Should look at MyModel1 for objects with `resource`
> matching `{"foo": {"id": <id>}}`.
>
> Actual result:
>
> ERROR: operator does not exist: jsonb = character varying
> LINE 1: ...AND ("resource" #> '{foo,id}') IN (SELECT...
>
> The actual issue is that when passing a values_list() to __in, the values
> list is not cast to jsonb (unlike when passing a text type). In the
> resulting sql, we can see `IN (SELECT U0."id" AS Col1 FROM mymodel2 U0
> ...)`. Wrapping `to_json(U0."id")` solves the issue.

New description:

Prerequisites

1. Create a model MyModel1 with the field `resource = JSONField()`.
2. Create another model MyModel2 with a field `id =
CharField(max_length=255)`

Reproduce by doing
`MyModel1.objects.filter(resource__foo__id__in=MyModel2.objects.all().values_list("id"))`

Expected result: Should look at MyModel1 for objects with `resource`
matching `{"foo": {"id": <id>}}`.

Actual result:
{{{
ERROR: operator does not exist: jsonb = character varying
LINE 1: ...AND ("resource" #> '{foo,id}') IN (SELECT...
}}}

The actual issue is that when passing a `values_list()` to `__in`, the


values list is not cast to jsonb (unlike when passing a text type). In the
resulting sql, we can see `IN (SELECT U0."id" AS Col1 FROM mymodel2 U0
...)`. Wrapping `to_json(U0."id")` solves the issue.

--

--
Ticket URL: <https://code.djangoproject.com/ticket/28872#comment:2>

Django

unread,
Oct 26, 2018, 8:26:29 AM10/26/18
to django-...@googlegroups.com
#28872: JSONField __in operator breaks when given a values_list()
----------------------------------+------------------------------------
Reporter: Jerome Leclanche | Owner: VCAMP
Type: Bug | Status: assigned
Component: contrib.postgres | Version: 1.11

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
----------------------------------+------------------------------------
Changes (by VCAMP):

* owner: (none) => VCAMP
* status: new => assigned


--
Ticket URL: <https://code.djangoproject.com/ticket/28872#comment:3>

Django

unread,
Nov 2, 2018, 10:32:48 AM11/2/18
to django-...@googlegroups.com
#28872: JSONField __in operator breaks when given a values_list()
----------------------------------+------------------------------------
Reporter: Jerome Leclanche | Owner: VCAMP
Type: Bug | Status: assigned
Component: contrib.postgres | Version: 1.11

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
----------------------------------+------------------------------------
Changes (by VCAMP):

* cc: VCAMP (added)
* has_patch: 0 => 1


--
Ticket URL: <https://code.djangoproject.com/ticket/28872#comment:4>

Django

unread,
Nov 6, 2018, 7:43:17 PM11/6/18
to django-...@googlegroups.com
#28872: JSONField __in operator breaks when given a values_list()
----------------------------------+------------------------------------
Reporter: Jerome Leclanche | Owner: VCAMP
Type: Bug | Status: assigned
Component: contrib.postgres | Version: 1.11

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1

Easy pickings: 0 | UI/UX: 0
----------------------------------+------------------------------------
Changes (by Tim Graham):

* needs_better_patch: 0 => 1


--
Ticket URL: <https://code.djangoproject.com/ticket/28872#comment:5>

Django

unread,
May 21, 2020, 2:41:56 AM5/21/20
to django-...@googlegroups.com
#28872: JSONField __in operator breaks when given a values_list()
----------------------------------+------------------------------------
Reporter: Jerome Leclanche | Owner: VCAMP
Type: Bug | Status: assigned
Component: contrib.postgres | Version: master

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1

Easy pickings: 0 | UI/UX: 0
----------------------------------+------------------------------------
Changes (by felixxm):

* version: 1.11 => master


Comment:

With the new implementation of `JSONField` this issue is PostgreSQL-
specific.

--
Ticket URL: <https://code.djangoproject.com/ticket/28872#comment:6>

Django

unread,
Jan 15, 2021, 5:40:26 AM1/15/21
to django-...@googlegroups.com
#28872: JSONField __in operator breaks when given a values_list()
-------------------------------------+-------------------------------------

Reporter: Jerome Leclanche | Owner: VCAMP
Type: Bug | Status: assigned
Component: Database layer | Version: master
(models, ORM) |

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak):

* component: contrib.postgres => Database layer (models, ORM)


--
Ticket URL: <https://code.djangoproject.com/ticket/28872#comment:7>

Django

unread,
Mar 21, 2023, 5:24:42 AM3/21/23
to django-...@googlegroups.com
#28872: JSONField __in operator breaks when given a values_list()
-------------------------------------+-------------------------------------

Reporter: Jerome Leclanche | Owner: (none)
Type: Bug | Status: new
Component: Database layer | Version: dev

(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak):

* owner: VCAMP => (none)
* status: assigned => new


--
Ticket URL: <https://code.djangoproject.com/ticket/28872#comment:8>

Django

unread,
Dec 25, 2025, 9:24:22 AM12/25/25
to django-...@googlegroups.com
#28872: JSONField __in operator breaks when given a values_list()
-------------------------------------+-------------------------------------
Reporter: Jerome Leclanche | Owner:
| JaeHyuckSa
Type: Bug | Status: assigned
Component: Database layer | Version: dev
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by JaeHyuckSa):

* needs_better_patch: 1 => 0
* owner: (none) => JaeHyuckSa
* status: new => assigned

--
Ticket URL: <https://code.djangoproject.com/ticket/28872#comment:9>

Django

unread,
Dec 25, 2025, 11:09:19 AM12/25/25
to django-...@googlegroups.com
#28872: JSONField __in operator breaks when given a values_list()
-------------------------------------+-------------------------------------
Reporter: Jerome Leclanche | Owner:
| JaeHyuckSa
Type: Bug | Status: assigned
Component: Database layer | Version: dev
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Simon Charette):

* needs_better_patch: 0 => 1

Comment:

Patch had a few issues notably

- It mutated a source expression during compilation
- It altered `sql.Query.select` and `.annotations` in a way that breaks
referenceing (`group_by`, `order_by`)

I suggested an alternative approach using a subquery pushdown instead.
--
Ticket URL: <https://code.djangoproject.com/ticket/28872#comment:10>

Django

unread,
Dec 26, 2025, 8:46:21 AM12/26/25
to django-...@googlegroups.com
#28872: JSONField __in operator breaks when given a values_list()
-------------------------------------+-------------------------------------
Reporter: Jerome Leclanche | Owner:
| JaeHyuckSa
Type: Bug | Status: assigned
Component: Database layer | Version: dev
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by JaeHyuckSa):

* needs_better_patch: 1 => 0

--
Ticket URL: <https://code.djangoproject.com/ticket/28872#comment:11>

Django

unread,
Jun 21, 2026, 1:13:30 PMJun 21
to django-...@googlegroups.com
#28872: JSONField __in operator breaks when given a values_list()
-------------------------------------+-------------------------------------
Reporter: Jerome Leclanche | Owner:
| JaeHyuckSa
Type: Bug | Status: assigned
Component: Database layer | Version: dev
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 1 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Jacob Walls):

* needs_tests: 0 => 1

--
Ticket URL: <https://code.djangoproject.com/ticket/28872#comment:12>

Django

unread,
Aug 10, 2026, 10:59:43 AMAug 10
to django-...@googlegroups.com
#28872: JSONField __in operator breaks when given a values_list()
-------------------------------------+-------------------------------------
Reporter: Jerome Leclanche | Owner: Pycon
| Korea Sprints
Type: Bug | Status: assigned
Component: Database layer | Version: dev
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 1 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Antoliny):

* owner: JaeHyuckSa => Pycon Korea Sprints

Comment:

Attempting to assign to Pycon Korea Sprints to make it easier to reserve
tickets. Pycon Korea ends August 17, this is available for someone else to
pick up on the 18th.
--
Ticket URL: <https://code.djangoproject.com/ticket/28872#comment:13>

Django

unread,
Aug 28, 2026, 5:14:12 PM (6 days ago) Aug 28
to django-...@googlegroups.com
#28872: JSONField __in operator breaks when given a values_list()
-------------------------------------+-------------------------------------
Reporter: Jerome Leclanche | Owner: Frantz
| Paul
Type: Bug | Status: assigned
Component: Database layer | Version: dev
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 1 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Frantz Paul):

* owner: Django Sprints => Frantz Paul

--
Ticket URL: <https://code.djangoproject.com/ticket/28872#comment:15>
Reply all
Reply to author
Forward
0 new messages