Opened 85 minutes ago

Last modified 16 minutes 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 85 minutes ago.

Download all attachments as: .zip

Change History (2)

by Tilman Koschnick, 85 minutes ago

Attachment: checks.diff added

comment:1 by Simon Charette, 19 minutes 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 property which is implemented by UniqueConstraint and ExclusionConstraint over the introspection logic that currently exists.

That might call for a Options.unique_together_fields: set[tuple[str]] that combine Field.unique, Options.unique_together and Constraint.totally_unique_for_fields so interested parties don't have to check of them every time.

Last edited 16 minutes ago by Simon Charette (previous) (diff)
Note: See TracTickets for help on using tickets.
Back to Top