繁体   English   中英

带有比较谓词的PostgreSQL排除约束

[英]PostgreSQL Exclusion constraint with comparison predicate

有简单的模仿唯一约束就像

create table foo(x int, exclude (x with =));

但是如何使用IS NOT DISTINCT FROM而不是= (因此表中只有一个NULL值)?

创建函数如f(anyelement, anyelement)和运算符失败,因为null具有未知类型。 还有一个问题:是否有可能将IS NOT DISTINCT FROM谓词包装到PostgreSQL中的运算符中?

请耐心等待,我没有寻找替代解决方案,我知道它很多:)

另外阅读: 比较运算符

创建一个与NOT DISTINCT TO对应的函数和运算符很容易:

CREATE FUNCTION ndist(anyelement, anyelement) RETURNS boolean
   IMMUTABLE CALLED ON NULL INPUT LANGUAGE sql
   AS 'SELECT $1 IS NOT DISTINCT FROM $2';

CREATE OPERATOR === (
   PROCEDURE = ndist,
   LEFTARG = anyelement,
   RIGHTARG = anyelement,
   COMMUTATOR = "==="
);

如果两个参数都是无类型的NULL,则会失败:

test=> SELECT NULL === NULL;
ERROR:  could not determine polymorphic type because input has type unknown

一种解决方案是使用重载并为您需要的每种类型定义相同的函数和运算符:

CREATE FUNCTION ndist(integer, integer) RETURNS boolean
   IMMUTABLE CALLED ON NULL INPUT LANGUAGE sql
   AS 'SELECT $1 IS NOT DISTINCT FROM $2';

CREATE FUNCTION ndist(text, text) RETURNS boolean
   IMMUTABLE CALLED ON NULL INPUT LANGUAGE sql
   AS 'SELECT $1 IS NOT DISTINCT FROM $2';

CREATE OPERATOR === (
   PROCEDURE = ndist,
   LEFTARG = integer,
   RIGHTARG = integer,
   COMMUTATOR = "==="
);

CREATE OPERATOR === (
   PROCEDURE = ndist,
   LEFTARG = text,
   RIGHTARG = text,
   COMMUTATOR = "==="
);

然后该示例将起作用:

test=> SELECT NULL === NULL;
 ?column? 
----------
 t
(1 row)

这是因为该类型解析规则会优先操作上text在这种情况下。

但所有这些都不允许您创建排除约束,因为您的运算符与运算符类没有关联,这对于确定要使用哪种索引是必要的。

您必须为每个btree 索引方法策略创建一个匹配函数,并使用这些函数为btree定义一个运算符类。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM