Helaas kan dit niet eenvoudig worden opgelost met eenvoudige unieke beperkingen / indexen (als het al met hen kan worden opgelost).
Wat je nodig hebt, is een uitsluiting beperking :de mogelijkheid om enkele rijen uit te sluiten, op basis van bijvoorbeeld botsing . Unieke beperkingen zijn slechts specifieke uitsluitingsbeperkingen (ze zijn gebaseerd op gelijkheid botsingen ).
Dus in theorie hoef je alleen elke row1
. uit te sluiten , waar er al een row2
. is , waarvoor deze uitdrukking waar is:ARRAY[row1.cola, row1.colb] && ARRAY[row2.cola, row2.colb]
Deze index zou doe het werk (momenteel alleen gist
indexen ondersteunen uitsluitingsbeperkingen):
ALTER TABLE table_name
ADD CONSTRAINT table_name_exclusion
EXCLUDE USING gist ((ARRAY[cola, colb]) WITH &&);
Maar helaas is er geen standaard operatorklasse voor arrays (die gebruikmaakt van gist
). Er is een intarray
module
, die er een biedt voor slechts integer
arrays, maar niets voor text
arrays.
Als je dit echt wilt oplossen, kun je altijd misbruik maken van de range
soorten
(bijv. ik gebruikte de aangrenzende -|-
operator, die alle zaken afhandelt, die niet kunnen worden afgehandeld met unique
) ...
-- there is no built-in type for text ranges neither,
-- but it can can be created fairly easily:
CREATE TYPE textrange AS RANGE (
SUBTYPE = text
);
ALTER TABLE table_name
ADD CONSTRAINT table_name_exclusion
EXCLUDE USING gist ((textrange(least(cola, colb), greatest(cola, colb))) WITH -|-);
-- the exclusion constraint above does not handle all situations:
ALTER TABLE table_name
ADD CONSTRAINT table_name_check
CHECK (cola is distinct from colb); -- without this, empty ranges could be created,
-- which are not adjacent to any other range
CREATE UNIQUE INDEX table_name_unique
ON table_name ((ARRAY[least(cola, colb), greatest(cola, colb)]));
-- without this, duplicated rows could be created,
-- because ranges are not adjacent to themselves
... maar ik ben bang dat je oorspronkelijke probleem veel gemakkelijker zou kunnen worden opgelost met een beetje refactoring van de database; wat ons bij de vraag brengt:welk probleem wil je hiermee oplossen?