带有谓词的 Postgresql EXCLUDE 约束:意外结果
Postgresql EXCLUDE constraint with a predicate : unexpected result
我试图通过添加 PREDICATE
.
进一步 Postgresql's EXCLUDE example
在一种情况下,它的工作方式与我预期的一样。
另一种情况……不是这样
第一个示例,谓词为“cage”。工作正常:
=> 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)
.
冲突
第二个例子,谓词是“动物”。意外结果:
=> 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)
?
自 'zebra' <> 'lion'
起,zebra
记录未包含在部分索引中。
实际上只有 lion
条记录包含在部分索引中。
'lion' <> 'lion'
永远不会为真,因此永远不会满足 exclude
条件。
我试图通过添加 PREDICATE
.
在一种情况下,它的工作方式与我预期的一样。 另一种情况……不是这样
第一个示例,谓词为“cage”。工作正常:
=> 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)
.
第二个例子,谓词是“动物”。意外结果:
=> 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)
?
自 'zebra' <> 'lion'
起,zebra
记录未包含在部分索引中。
实际上只有 lion
条记录包含在部分索引中。
'lion' <> 'lion'
永远不会为真,因此永远不会满足 exclude
条件。