Opened 7 hours ago

Last modified 5 hours ago

#36107 assigned Bug

PostgresSQL ArrayField with size crashes with bulk_create

Reported by: Claude Paroz Owned by: Simon Charette
Component: Database layer (models, ORM) Version: 5.2
Severity: Release blocker Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When trying to bulk_create model instances with an ArrayField with a specified size (and triggering the UNNEST instruction), the query crashes at database level (column "<field>" is of type double precision[] but expression is of type double precision).

Probably a regression in a16eedcf9c69d8a11d94cac1811018c5b996d491

A possible reproducing test:

diff --git a/tests/postgres_tests/migrations/0002_create_test_models.py b/tests/postgres_tests/migrations/0002_create_test_models.py
index 188f79607d..31705ae21a 100644
--- a/tests/postgres_tests/migrations/0002_create_test_models.py
+++ b/tests/postgres_tests/migrations/0002_create_test_models.py
@@ -167,6 +167,28 @@ class Migration(migrations.Migration):
             },
             bases=(models.Model,),
         ),
+        migrations.CreateModel(
+            name="WithSizeArrayModel",
+            fields=[
+                (
+                    "id",
+                    models.AutoField(
+                        verbose_name="ID",
+                        serialize=False,
+                        auto_created=True,
+                        primary_key=True,
+                    ),
+                ),
+                (
+                    "field",
+                    ArrayField(models.FloatField(), size=2, null=True, blank=True),
+                ),
+            ],
+            options={
+                "required_db_vendor": "postgresql",
+            },
+            bases=(models.Model,),
+        ),
         migrations.CreateModel(
             name="NullableIntegerArrayModel",
             fields=[
diff --git a/tests/postgres_tests/models.py b/tests/postgres_tests/models.py
index e3118bc590..1563f6a35d 100644
--- a/tests/postgres_tests/models.py
+++ b/tests/postgres_tests/models.py
@@ -64,6 +64,10 @@ class DateTimeArrayModel(PostgreSQLModel):
     times = ArrayField(models.TimeField())
 
 
+class WithSizeArrayModel(PostgreSQLModel):
+    field = ArrayField(models.FloatField(), size=3)
+
+
 class NestedIntegerArrayModel(PostgreSQLModel):
     field = ArrayField(ArrayField(models.IntegerField()))
 
diff --git a/tests/postgres_tests/test_array.py b/tests/postgres_tests/test_array.py
index d930a01a1d..c2b0ebcd31 100644
--- a/tests/postgres_tests/test_array.py
+++ b/tests/postgres_tests/test_array.py
@@ -28,6 +28,7 @@ from .models import (
     OtherTypesArrayModel,
     PostgreSQLModel,
     Tag,
+    WithSizeArrayModel,
 )
 
 try:
@@ -216,6 +217,12 @@ class TestQuerying(PostgreSQLTestCase):
             ]
         )
 
+    def test_bulk_create_with_sized_arrayfield(self):
+        WithSizeArrayModel.objects.bulk_create([
+            WithSizeArrayModel(field=[1, 2]),
+            WithSizeArrayModel(field=[3, 4]),
+        ])
+
     def test_empty_list(self):
         NullableIntegerArrayModel.objects.create(field=[])
         obj = (

Change History (3)

comment:1 by Simon Charette, 6 hours ago

Triage Stage: UnreviewedAccepted

Thanks Claude, I'll look at it shortly.

The current heuristics to disable the optimization when dealing with ArrayField didn't account for sized ones.

comment:2 by Simon Charette, 6 hours ago

Owner: set to Simon Charette
Status: newassigned

comment:3 by Simon Charette, 5 hours ago

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