Opened 3 weeks ago

Last modified 3 weeks ago

#36880 assigned Bug

Postgres hash exclusion constraints are not considered totally unique

Reported by: Tilman Koschnick Owned by: Karthik
Component: Database layer (models, ORM) Version: dev
Severity: Normal Keywords:
Cc: Tilman Koschnick, Karthik 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 weeks ago.

Download all attachments as: .zip

Change History (3)

by Tilman Koschnick, 3 weeks ago

Attachment: checks.diff added

comment:1 by Simon Charette, 3 weeks 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 3 weeks ago by Simon Charette (previous) (diff)

comment:2 by Karthik, 3 weeks ago

Cc: Karthik added
Owner: set to Karthik
Status: newassigned

I’m working on improving the patch following the maintainer’s feedback.

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