Opened 3 hours ago

Last modified 2 hours ago

#36880 new Bug

Postgres hash exclusion constraints are not considered totally unique

Reported by: Tilman Koschnick Owned by:
Component: Database layer (models, ORM) Version: dev
Severity: Normal Keywords:
Cc: Tilman Koschnick Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: yes
Easy pickings: no UI/UX: no

Description

Hi,

with Postgres, a hash index can be used as an exclusion constraint, functioning the same way a unique btree based constrained. Support for this has recently been merged to Django: https://code.djangoproject.com/ticket/36827

Using this on a USERNAME_FIELD can be good for index size and performance. Currently, the auth system checks doesn't detect a hash exclusion constraint as a viable option though:

account.User: (auth.E003) 'User.email' must be unique because it is named as the 'USERNAME_FIELD'.

The attached patch enhances the check to consider hash constraints as well.

Cheers, Til

Attachments (1)

checks.diff (1.0 KB ) - added by Tilman Koschnick 3 hours ago.

Download all attachments as: .zip

Change History (2)

by Tilman Koschnick, 3 hours ago

Attachment: checks.diff added

comment:1 by Simon Charette, 2 hours ago

Patch needs improvement: set
Summary: using hash index as exclusion constraint on USERNAME_FIELD triggers SystemCheckErrorPostgres hash exclusion constraints are not considered totally unique
Triage Stage: UnreviewedAccepted

Accepting on the basis that the check logic should be able to consider all type of unique constraints but the proposed patch is inadequate.

What should be done instead is find a way to have django.db.models.options.Options.total_unique_constraints include such constraint in a way that doesn't couple contrib.postgres with core.

A potential solution could be to introduce a Constraint.totally_unique_for_fields -> set[tuple[str]] | None method which is implemented by UniqueConstraint and ExclusionConstraint.

Version 0, edited 2 hours ago by Simon Charette (next)
Note: See TracTickets for help on using tickets.
Back to Top