﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
34293	Extra validation introduced in 30581 breaks certain constraint setups	Ionel Cristian Mărieș	nobody	"So I have this model
{{{
class TimeTsTzRange(models.Func):
    function = 'timetstzrange'
    output_field = fields.DateTimeRangeField()
class Schedule(models.Model):
    class Meta:
        constraints = [
            models.CheckConstraint(
                name='schedule_start_lt_end',
                check=(
                    Q(start_time__lt=F('end_time')) |
                    Q(start_time__lte=HALF_HOUR_BEFORE_MIDNIGHT, end_time=MIDNIGHT)
                ),
            ),
            constraints.ExclusionConstraint(
                name='schedule_exclude_overlapping',
                expressions=[
                    (
                        TimeTsTzRange(
                            'start_time',
                            'end_time',
                            fields.RangeBoundary(inclusive_upper=True),
                        ),
                        fields.RangeOperators.OVERLAPS,
                    ),
                    ('weekday', fields.RangeOperators.EQUAL),
                    ('therapist', fields.RangeOperators.EQUAL),
                ],
            ),
        ]
    start_time = models.TimeField(
        verbose_name=_('start time'),
    )
    end_time = models.TimeField(
        verbose_name=_('end time'),
    )
   # and some other irrelevant fields
}}}

Under 3.2 this worked fine, Schedule.objects.create(start_time=time(2),end_time=time(1)) would raise an IntegrityError as expected with a decently helpful message: new row for relation ""app_schedule"" violates check constraint ""schedule_start_lt_end"" DETAIL:  Failing row contains (13, 3, 02:00:00, 01:00:00, 3).

Under 4.2a1 this raises django.db.utils.DataError with a not really helpful message: range lower bound must be less than or equal to range upper bound
CONTEXT:  PL/pgSQL function timetstzrange(time without time zone,time without time zone,text) line 6 at RETURN

Now this happens because in 4.2 all the constraints are checked, regardless if 1st one faile, and obviously the second will fail horribly.

I've tried adding deferrable=models.Deferrable.DEFERRED to the second contraint but it's still run in validation - maybe this could be changed? And then my problem would go away.

Sure, I could make a custom function (that wraps timetstzrange) to shortcircuit the second constraint if range is invalid but that seems ugly if not dangerous.
"	Bug	closed	Database layer (models, ORM)	4.1	Normal	wontfix			Unreviewed	0	0	0	0	0	0
