summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsage <laymonage@gmail.com>2020-12-09 21:45:18 +0700
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2020-12-11 11:18:15 +0100
commita891e1bb0a3e1b29a461784cd0bf717513e72f19 (patch)
treebb1f15167c8e90a56b1bfebfa740df0e51bb6faf
parentce7f8c2eada40950796cb20c88c36f568052f070 (diff)
[3.1.x] Fixed #32252 -- Fixed __isnull=True on key transforms on SQLite and Oracle.
__isnull=True on key transforms should not match keys with NULL values. Backport of 8d7085e0fd004af5431389f3d903aba6220d7957 from master
-rw-r--r--django/db/models/fields/json.py19
-rw-r--r--docs/releases/3.1.5.txt4
-rw-r--r--tests/model_fields/test_jsonfield.py4
3 files changed, 22 insertions, 5 deletions
diff --git a/django/db/models/fields/json.py b/django/db/models/fields/json.py
index 5b9fe4b63a..7a3b2d3578 100644
--- a/django/db/models/fields/json.py
+++ b/django/db/models/fields/json.py
@@ -368,14 +368,25 @@ class CaseInsensitiveMixin:
class KeyTransformIsNull(lookups.IsNull):
# key__isnull=False is the same as has_key='key'
def as_oracle(self, compiler, connection):
+ sql, params = HasKey(
+ self.lhs.lhs,
+ self.lhs.key_name,
+ ).as_oracle(compiler, connection)
if not self.rhs:
- return HasKey(self.lhs.lhs, self.lhs.key_name).as_oracle(compiler, connection)
- return super().as_sql(compiler, connection)
+ return sql, params
+ # Column doesn't have a key or IS NULL.
+ lhs, lhs_params, _ = self.lhs.preprocess_lhs(compiler, connection)
+ return '(NOT %s OR %s IS NULL)' % (sql, lhs), tuple(params) + tuple(lhs_params)
def as_sqlite(self, compiler, connection):
+ template = 'JSON_TYPE(%s, %%s) IS NULL'
if not self.rhs:
- return HasKey(self.lhs.lhs, self.lhs.key_name).as_sqlite(compiler, connection)
- return super().as_sql(compiler, connection)
+ template = 'JSON_TYPE(%s, %%s) IS NOT NULL'
+ return HasKey(self.lhs.lhs, self.lhs.key_name).as_sql(
+ compiler,
+ connection,
+ template=template,
+ )
class KeyTransformIn(lookups.In):
diff --git a/docs/releases/3.1.5.txt b/docs/releases/3.1.5.txt
index 4a7fcc5876..0d11118446 100644
--- a/docs/releases/3.1.5.txt
+++ b/docs/releases/3.1.5.txt
@@ -9,4 +9,6 @@ Django 3.1.5 fixes several bugs in 3.1.4.
Bugfixes
========
-* ...
+* Fixed ``__isnull=True`` lookup on key transforms for
+ :class:`~django.db.models.JSONField` with Oracle and SQLite
+ (:ticket:`32252`).
diff --git a/tests/model_fields/test_jsonfield.py b/tests/model_fields/test_jsonfield.py
index f041c659d1..a4bc9e2454 100644
--- a/tests/model_fields/test_jsonfield.py
+++ b/tests/model_fields/test_jsonfield.py
@@ -535,6 +535,10 @@ class TestQuerying(TestCase):
self.objs[:3] + self.objs[5:],
)
self.assertSequenceEqual(
+ NullableJSONModel.objects.filter(value__j__isnull=True),
+ self.objs[:4] + self.objs[5:],
+ )
+ self.assertSequenceEqual(
NullableJSONModel.objects.filter(value__a__isnull=False),
[self.objs[3], self.objs[4]],
)