Skip to content

Commit

Permalink
Fixed #35329 -- Fixed migrations crash when adding partial unique con…
Browse files Browse the repository at this point in the history
…straints with nulls_distinct.

Bug in 595a2ab.

Thanks Lucas Lemke Saunitti for the report.
  • Loading branch information
felixxm authored Mar 26, 2024
1 parent ae10146 commit b98271a
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 1 deletion.
2 changes: 1 addition & 1 deletion django/db/backends/base/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ class BaseDatabaseSchemaEditor:
)
sql_create_unique_index = (
"CREATE UNIQUE INDEX %(name)s ON %(table)s "
"(%(columns)s)%(include)s%(condition)s%(nulls_distinct)s"
"(%(columns)s)%(include)s%(nulls_distinct)s%(condition)s"
)
sql_rename_index = "ALTER INDEX %(old_name)s RENAME TO %(new_name)s"
sql_delete_index = "DROP INDEX %(name)s"
Expand Down
4 changes: 4 additions & 0 deletions docs/releases/5.0.4.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,7 @@ Bugfixes
* Fixed a regression in Django 5.0 where the ``AdminFileWidget`` could be
rendered with two ``id`` attributes on the "Clear" checkbox
(:ticket:`35273`).

* Fixed a bug in Django 5.0 that caused a migration crash on PostgreSQL 15+
when adding a partial ``UniqueConstraint`` with ``nulls_distinct``
(:ticket:`35329`).
32 changes: 32 additions & 0 deletions tests/schema/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -3629,6 +3629,38 @@ def test_unique_constraint_nulls_distinct(self):
constraints = self.get_constraints(Author._meta.db_table)
self.assertNotIn(constraint.name, constraints)

@skipUnlessDBFeature(
"supports_nulls_distinct_unique_constraints",
"supports_partial_indexes",
)
def test_unique_constraint_nulls_distinct_condition(self):
with connection.schema_editor() as editor:
editor.create_model(Author)
constraint = UniqueConstraint(
fields=["height", "weight"],
name="un_height_weight_start_A",
condition=Q(name__startswith="A"),
nulls_distinct=False,
)
with connection.schema_editor() as editor:
editor.add_constraint(Author, constraint)
Author.objects.create(name="Adam", height=None, weight=None)
Author.objects.create(name="Avocado", height=1, weight=None)
Author.objects.create(name="Adrian", height=None, weight=1)
with self.assertRaises(IntegrityError):
Author.objects.create(name="Alex", height=None, weight=None)
Author.objects.create(name="Bob", height=None, weight=None)
with self.assertRaises(IntegrityError):
Author.objects.create(name="Alex", height=1, weight=None)
Author.objects.create(name="Bill", height=None, weight=None)
with self.assertRaises(IntegrityError):
Author.objects.create(name="Alex", height=None, weight=1)
Author.objects.create(name="Celine", height=None, weight=1)
with connection.schema_editor() as editor:
editor.remove_constraint(Author, constraint)
constraints = self.get_constraints(Author._meta.db_table)
self.assertNotIn(constraint.name, constraints)

@skipIfDBFeature("supports_nulls_distinct_unique_constraints")
def test_unique_constraint_nulls_distinct_unsupported(self):
# UniqueConstraint is ignored on databases that don't support
Expand Down

0 comments on commit b98271a

Please sign in to comment.