Opened 5 years ago

Closed 4 years ago

Last modified 4 years ago

#31530 closed Cleanup/optimization (fixed)

Check that CheckConstraint.check and UniqueConstraint.condition don't span joins.

Reported by: Simon Charette Owned by: Hasan Ramezani
Component: Database layer (models, ORM) Version: dev
Severity: Normal Keywords:
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Mariusz Felisiak)

Similar to #31410 but for check and condition.


Not everyone is familiar with the fact database level constraint cannot span across tables and might be tempted to do

class Person(models.Model):
    age = models.PositiveSmallIntegerField()
    parent = models.ForeignKey(self)

    class Meta:
        constraints = {
            CheckConstraint(
                name='age_lt_parent', check=Q(age__lt=parent__age)
            ),
        }

Which we'll happily create migrations for but we'll then crash because we prevent JOINs when resolving check.

Change History (10)

comment:1 by Mariusz Felisiak, 5 years ago

Description: modified (diff)
Triage Stage: UnreviewedAccepted

comment:2 by Hasan Ramezani, 4 years ago

Has patch: set
Owner: changed from nobody to Hasan Ramezani
Status: newassigned

comment:3 by Alexandr Tatarinov, 4 years ago

Patch needs improvement: set

Is it even possible to handle all cases with Q objects?
As mentioned in this comment, custom expressions might be impossible to introspect.
Maybe we can rely on something like get_source_expressions to get all included fields...

comment:4 by Hasan Ramezani, 4 years ago

Here is my comment on PR:

Yes, this doesn't work for Lower('parent__name'). I can change the patch to cover this case as well but I don't know exactly which kind of expression should I cover? and with more cases, the code is going to be complicated.

@felixxm Do you have any idea?

comment:5 by Hasan Ramezani, 4 years ago

Patch needs improvement: unset

comment:6 by Mariusz Felisiak, 4 years ago

Patch needs improvement: set
Version: 3.0master

comment:7 by Hasan Ramezani, 4 years ago

Patch needs improvement: unset

comment:8 by Mariusz Felisiak, 4 years ago

Triage Stage: AcceptedReady for checkin

comment:9 by Mariusz Felisiak <felisiak.mariusz@…>, 4 years ago

Resolution: fixed
Status: assignedclosed

In b7b7df5:

Fixed #31530 -- Added system checks for invalid model field names in CheckConstraint.check and UniqueConstraint.condition.

comment:10 by Mariusz Felisiak <felisiak.mariusz@…>, 4 years ago

In 33abc556:

Refs #31530 -- Added test for joined OneToOneField in CheckConstraint.check

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