Hai scelto un vero calvario. Utilizza un indice univoco, che è molto più semplice, sicuro e veloce.
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.