PostgreSQL 9.4 - 在EXCLUDE约束中使用自定义运算符

时间:2015-12-22 02:09:49

标签: postgresql postgresql-9.4

在审核this answer后,我创建了以下自定义运算符:

bitset

我有一个表允许两个CREATE OR REPLACE FUNCTION is_not_distinct_from( ANYELEMENT, ANYELEMENT ) RETURNS BOOLEAN AS $$ SELECT $1 IS NOT DISTINCT FROM $2; $$ LANGUAGE sql IMMUTABLE; CREATE OPERATOR =!= ( PROCEDURE = is_not_distinct_from(anyelement,anyelement), LEFTARG = anyelement, RIGHTARG = anyelement, COMMUTATOR = =!=, NEGATOR = <!> ); CREATE OR REPLACE FUNCTION is_distinct_from( ANYELEMENT, ANYELEMENT ) RETURNS BOOLEAN AS $$ SELECT $1 IS DISTINCT FROM $2; $$ LANGUAGE sql IMMUTABLE; CREATE OPERATOR <!> ( PROCEDURE = is_distinct_from(anyelement,anyelement), LEFTARG = anyelement, RIGHTARG = anyelement, COMMUTATOR = <!>, NEGATOR = =!= ); 值,我希望防止重复记录,将NULL视为值。

NULL

我收到以下错误:

  

错误:operator =!=(anyelement,anyelement)不是其成员   operator family“datetime_ops”DETAIL:排除运算符必须是   与约束的索引运算符类相关。

我查看了文档(herehere),但我很难理解这些材料。

此外,this question可被视为此副本的副本;但是,该问题的问题在于与其他RDBMS的兼容性...... 这个问题专门解决了如何处理上述错误。

1 个答案:

答案 0 :(得分:2)

你选择了真正的考验。使用一个更简单,更安全,更快速的独特索引。

CREATE TABLE foo (
    foo_id serial PRIMARY KEY,
    foo text NOT NULL,
    bar timestamptz,
    baz timestamptz
);
CREATE TABLE

CREATE UNIQUE INDEX foo_foo_bar_baz_idx ON foo 
(foo, coalesce(bar, 'infinity'), coalesce(baz, 'infinity'));
CREATE INDEX

INSERT INTO foo VALUES
(default, '', null, null),
(default, '', now(), null),
(default, '', null, now());
INSERT 0 3

INSERT INTO foo VALUES
(default, '', null, null);
ERROR:  duplicate key value violates unique constraint "foo_foo_bar_baz_idx"
DETAIL:  Key (foo, (COALESCE(bar, 'infinity'::timestamp with time zone)), (COALESCE(baz, 'infinity'::timestamp with time zone)))=(, infinity, infinity) already exists.