You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We need a way to generalize exclusive constraints to refer to something other than each value subject to the constraint being != to all other values.
In large part this is motivated by #3088 and the practical need to have non-overlapping intervals. Currently the non-overlapping constraint cannot be expressed. However, even in the imagined future where we have the interval types and the standard library functions and operators to work with them it would still be impossible to express "this interval property must be non-overlapping with other objects".
The proposal is to use existing language features as much as possible to express the exclusive constraint in a way that would allow using more complex expressions as the basis for exclusion. The premise is that generally speaking, an exclusion constraint is a statement about some expression being true for all elements subject to the constraint.
The generalized variant would look something like this:
The expression in the using block would have to be wrapped into all, indicating that what follows is in fact a condition that must be globally true. Inside the all argument we could use __other__ (referring to all other existing subjects of the constraints) to distinguish from __subject__. Not all expressions would be valid inside that, much like we currently don't allow long paths and non-immutable functions in all constraints. We could additionally allow top level and to combine multiple properties into a single exclusive constraint where a simple tuple exclusivity does not express what we want.
For example, consider a constraint like this:
abstract constraint invariant() extending exclusive {
using (
all(
__subject__.name != __other__.name and
__subject__.cohort = __other__.cohort and
)
);
};
Names have to be unique, but the cohort has to be the same (whatever it is). So we can have at most one cohort at any time, and within the objects that have a cohort specified, the names have to be unique, even if they aren't globally unique. This is meant to illustrate a situation which is inexpressible by the current less generic exclusive constraints and requires different operations to be performed on different constraint parts.
The operator and is a great way to indicate such composite constraints because it distributes over all (all(A and B) = all(A) and all(B)). It is probably not as useful to allow the use of any as an alternative way of expressing such rules mostly because and and any have a more complex interaction. At the end of the day it seems that we need to reduce the expression into a all(A and B and ...) format for Postgres and this task would be harder if we allowed any as an alternative way of specifying our exclusion constraints.
As far as parameters are concerned imagine if we could specify a constraint like this:
# Ensure that all constraint subjects are close to each other.
abstract constraint grouped(distance: float64) extending exclusive {
using (
all((__subject__ - __other__ ) ^ 2 < $distance ^ 2 )
);
};
It might make more sense to use expression as the base constraint in the above examples, making exclusive defined like this:
We need a way to generalize exclusive constraints to refer to something other than each value subject to the constraint being
!=
to all other values.In large part this is motivated by #3088 and the practical need to have non-overlapping intervals. Currently the non-overlapping constraint cannot be expressed. However, even in the imagined future where we have the interval types and the standard library functions and operators to work with them it would still be impossible to express "this interval property must be non-overlapping with other objects".
The proposal is to use existing language features as much as possible to express the
exclusive
constraint in a way that would allow using more complex expressions as the basis for exclusion. The premise is that generally speaking, an exclusion constraint is a statement about some expression being true for all elements subject to the constraint.The generalized variant would look something like this:
The expression in the
using
block would have to be wrapped intoall
, indicating that what follows is in fact a condition that must be globally true. Inside theall
argument we could use__other__
(referring to all other existing subjects of the constraints) to distinguish from__subject__
. Not all expressions would be valid inside that, much like we currently don't allow long paths and non-immutable functions in all constraints. We could additionally allow top leveland
to combine multiple properties into a single exclusive constraint where a simple tuple exclusivity does not express what we want.For example, consider a constraint like this:
Names have to be unique, but the cohort has to be the same (whatever it is). So we can have at most one cohort at any time, and within the objects that have a
cohort
specified, the names have to be unique, even if they aren't globally unique. This is meant to illustrate a situation which is inexpressible by the current less genericexclusive
constraints and requires different operations to be performed on different constraint parts.The operator
and
is a great way to indicate such composite constraints because it distributes overall
(all(A and B) = all(A) and all(B)
). It is probably not as useful to allow the use ofany
as an alternative way of expressing such rules mostly becauseand
andany
have a more complex interaction. At the end of the day it seems that we need to reduce the expression into aall(A and B and ...)
format for Postgres and this task would be harder if we allowedany
as an alternative way of specifying our exclusion constraints.As far as parameters are concerned imagine if we could specify a constraint like this:
It might make more sense to use
expression
as the base constraint in the above examples, makingexclusive
defined like this:The text was updated successfully, but these errors were encountered: