diff --git a/django/contrib/postgres/fields/array.py b/django/contrib/postgres/fields/array.py index 87760613fb..ceac798604 100644 --- a/django/contrib/postgres/fields/array.py +++ b/django/contrib/postgres/fields/array.py @@ -198,7 +198,11 @@ class ArrayLenTransform(Transform): def as_sql(self, compiler, connection): lhs, params = compiler.compile(self.lhs) - return 'array_length(%s, 1)' % lhs, params + # Distinguish NULL and empty arrays + return ( + 'CASE WHEN %(lhs)s IS NULL THEN NULL ELSE ' + 'coalesce(array_length(%(lhs)s, 1), 0) END' + ) % {'lhs': lhs}, params class IndexTransform(Transform): diff --git a/docs/releases/1.8.8.txt b/docs/releases/1.8.8.txt index 1c4b659782..1a28efe167 100644 --- a/docs/releases/1.8.8.txt +++ b/docs/releases/1.8.8.txt @@ -11,3 +11,6 @@ Bugfixes * Fixed incorrect ``unique_together`` field name generation by ``inspectdb`` (:ticket:`25274`). + +* Corrected ``__len`` query lookup on ``ArrayField`` for empty arrays + (:ticket:`25772`). diff --git a/tests/postgres_tests/test_array.py b/tests/postgres_tests/test_array.py index fb7eb16da2..b514a4329e 100644 --- a/tests/postgres_tests/test_array.py +++ b/tests/postgres_tests/test_array.py @@ -218,6 +218,13 @@ class TestQuerying(TestCase): self.objs[0:3] ) + def test_len_empty_array(self): + obj = NullableIntegerArrayModel.objects.create(field=[]) + self.assertSequenceEqual( + NullableIntegerArrayModel.objects.filter(field__len=0), + [obj] + ) + def test_slice(self): self.assertSequenceEqual( NullableIntegerArrayModel.objects.filter(field__0_1=[2]),