在审核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:排除运算符必须是 与约束的索引运算符类相关。
此外,this question可被视为此副本的副本;但是,该问题的问题在于与其他RDBMS的兼容性...... 这个问题专门解决了如何处理上述错误。
答案 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.