[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 8d7085e0fd
from master
This commit is contained in:
parent
ce7f8c2ead
commit
a891e1bb0a
|
@ -368,14 +368,25 @@ class CaseInsensitiveMixin:
|
||||||
class KeyTransformIsNull(lookups.IsNull):
|
class KeyTransformIsNull(lookups.IsNull):
|
||||||
# key__isnull=False is the same as has_key='key'
|
# key__isnull=False is the same as has_key='key'
|
||||||
def as_oracle(self, compiler, connection):
|
def as_oracle(self, compiler, connection):
|
||||||
|
sql, params = HasKey(
|
||||||
|
self.lhs.lhs,
|
||||||
|
self.lhs.key_name,
|
||||||
|
).as_oracle(compiler, connection)
|
||||||
if not self.rhs:
|
if not self.rhs:
|
||||||
return HasKey(self.lhs.lhs, self.lhs.key_name).as_oracle(compiler, connection)
|
return sql, params
|
||||||
return super().as_sql(compiler, connection)
|
# 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):
|
def as_sqlite(self, compiler, connection):
|
||||||
|
template = 'JSON_TYPE(%s, %%s) IS NULL'
|
||||||
if not self.rhs:
|
if not self.rhs:
|
||||||
return HasKey(self.lhs.lhs, self.lhs.key_name).as_sqlite(compiler, connection)
|
template = 'JSON_TYPE(%s, %%s) IS NOT NULL'
|
||||||
return super().as_sql(compiler, connection)
|
return HasKey(self.lhs.lhs, self.lhs.key_name).as_sql(
|
||||||
|
compiler,
|
||||||
|
connection,
|
||||||
|
template=template,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class KeyTransformIn(lookups.In):
|
class KeyTransformIn(lookups.In):
|
||||||
|
|
|
@ -9,4 +9,6 @@ Django 3.1.5 fixes several bugs in 3.1.4.
|
||||||
Bugfixes
|
Bugfixes
|
||||||
========
|
========
|
||||||
|
|
||||||
* ...
|
* Fixed ``__isnull=True`` lookup on key transforms for
|
||||||
|
:class:`~django.db.models.JSONField` with Oracle and SQLite
|
||||||
|
(:ticket:`32252`).
|
||||||
|
|
|
@ -534,6 +534,10 @@ class TestQuerying(TestCase):
|
||||||
NullableJSONModel.objects.filter(value__a__isnull=True),
|
NullableJSONModel.objects.filter(value__a__isnull=True),
|
||||||
self.objs[:3] + self.objs[5:],
|
self.objs[:3] + self.objs[5:],
|
||||||
)
|
)
|
||||||
|
self.assertSequenceEqual(
|
||||||
|
NullableJSONModel.objects.filter(value__j__isnull=True),
|
||||||
|
self.objs[:4] + self.objs[5:],
|
||||||
|
)
|
||||||
self.assertSequenceEqual(
|
self.assertSequenceEqual(
|
||||||
NullableJSONModel.objects.filter(value__a__isnull=False),
|
NullableJSONModel.objects.filter(value__a__isnull=False),
|
||||||
[self.objs[3], self.objs[4]],
|
[self.objs[3], self.objs[4]],
|
||||||
|
|
Loading…
Reference in New Issue