<!--
Les sources pour ce sujet sont :

* https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=8c852ba9a

Discussion :

* https://www.postgresql.org/message-id/flat/ec8b1d9b-502e-d1f8-e909-1bf9dffe6fa5@illuminatedcomputing.com
-->

<div class="slide-content">

  * Les contraintes d'exclusion sont autorisées si elles :
    + incluent toutes les colonnes de la clé de partitionnement
    + n'utilisent que l'opérateur `=`

</div>

<div class="notes">

Voici un exemple :

```sql
CREATE TABLE rendezvous(heure tstzrange, medecin int, client int) PARTITION BY RANGE (heure);
CREATE TABLE rendezvous_1 PARTITION OF rendezvous
  FOR VALUES FROM ('[2024-01-01 00:00:00+02, 2024-01-02 00:00:00+02)'::tstzrange)
               TO ('[2024-01-31 00:00:00+02, 2024-02-01 00:00:00+02)'::tstzrange);
CREATE TABLE rendezvous_2 PARTITION OF rendezvous
  FOR VALUES FROM ('[2024-02-01 00:00:00+02, 2024-02-02 00:00:00+02)'::tstzrange)
               TO ('[2024-02-29 00:00:00+02, 2024-03-01 00:00:00+02)'::tstzrange);
CREATE EXTENSION btree_gist ;
```

Ajoutons une contrainte d'exclusion avec l'opérateur `=` :

```sql
ALTER TABLE rendezvous ADD CONSTRAINT overlap EXCLUDE USING gist (heure WITH =);
INSERT INTO rendezvous VALUES('[2024-01-01 10:00:00+02, 2024-01-01 11:30:00+02)', 1, 1);
INSERT INTO rendezvous VALUES('[2024-01-01 10:00:00+02, 2024-01-01 11:30:00+02)', 1, 1);
```
```console
ALTER TABLE
INSERT 0 1
ERROR:  conflicting key value violates exclusion constraint "rendezvous_1_heure_excl"
DETAIL:  Key (heure)=(["2024-01-01 09:00:00+01","2024-01-01 10:30:00+01")) conflicts with existing key (heure)=(["2024-01-01 09:00:00+01","2024-01-01 10:30:00+01")).
```

Nous pouvons voir que la contrainte se comporte comme une contrainte d'unicité.

Essayons avec l'opérateur `&&` :

```sql
ALTER TABLE rendezvous ADD CONSTRAINT overlap EXCLUDE USING gist (heure WITH &&);
```
```console
ERROR:  cannot match partition key to index on column "heure" using non-equal operator "&&"
```

Nous pouvons voir que tout opérateur différent de `=` est refusé. C'est compréhensible,
un autre opérateur pourrait contraindre PostgreSQL à vérifier si la ligne insérée
entre en conflit avec des lignes d'autres partitions.

Cela pourrait changer avec les clefs temporelles en version 18.

</div>
