带 predicate 的postgresql排除约束:意外结果

li9yvcax  于 2021-07-24  发布在  Java
关注(0)|答案(1)|浏览(363)

我试图通过添加一个 PREDICATE .
在一个案例中,它的工作方式和我预期的一样。在另一种情况下…不是这样
第一个例子,在“cage”上有一个 predicate 。效果很好:

=> CREATE TABLE zoo(
    cage     INTEGER,
    animal   TEXT,
    EXCLUDE USING GIST (cage WITH =, animal WITH <>) WHERE (cage = 1)
);
CREATE TABLE

=> INSERT INTO zoo VALUES (1, 'zebra');
INSERT 0 1

=> INSERT INTO zoo VALUES (2, 'lion');
INSERT 0 1

=> INSERT INTO zoo VALUES (1, 'lion');
ERROR:  conflicting key value violates exclusion constraint "zoo_cage_animal_excl"
DETAIL:  Key (cage, animal)=(1, lion) conflicts with existing key (cage, animal)=(1, zebra).

到目前为止,还不错。 (1, lion) 确实与 (1, zebra) .
第二个例子,用一个谓语“animal”。意外结果:

=> CREATE TABLE zoo(
        cage     INTEGER,
        animal   TEXT,
        EXCLUDE USING GIST (cage WITH =, animal WITH <>) WHERE (animal = 'lion')
    );
    CREATE TABLE

    => INSERT INTO zoo VALUES (1, 'zebra');
    INSERT 0 1

    => INSERT INTO zoo VALUES (2, 'lion');
    INSERT 0 1

    => INSERT INTO zoo VALUES (2, 'zebra');
    INSERT 0 1

为什么这最后一句话没有引起矛盾的错误? WHERE (animal = 'lion') 建立部分gist索引。最后一排( (2, zebra) )应与现有行冲突 (2, lion) (同一笼子,不同动物: 2 = 2 , zebra <> lion ).
那为什么postgresql允许这一行呢 (2, zebra) 要插入吗?

8e2ybdfx

8e2ybdfx1#

'zebra' <> 'lion' ,的 zebra 部分索引中不包括记录。
事实上只是 lion 记录包含在部分索引中。
这永远不会是真的 'lion' <> 'lion' ,所以 exclude 条件永远不会满足。

相关问题