On Thu, 13 Jul 2006, Chris Hoover wrote: > I am having what appears to be a bug with unique indexes on 8.1.3. > > I have created a new table. > > create table payer_835 ( > payer_id int8 not null default > nextval('payer_835_payer_id_seq'::regclass) primary key, > payer_name varchar(50) not null, > payer_trn03 varchar(10) not null, > payer_trn04 varchar(30), > sku_id int8 references skucode(sku_id) on delete cascade on > update cascade, > payer_billable boolean not null default true, > create_timestamp timestamp not null default now(), > last_mod_timestamp timestamp, > expire_timestamp timestamp > ); > > On this table, I have created a unique index on payer_trn03, payer_trn04, > and expire_timestamp. However, since the expire_timestamp is normally null, > the unique index does not appear to be working. I have been able to enter > two identical rows into this table. Two nulls are considered distinct for purposes of unique indexes and constraints. The unique constraint is defined effective as a search condition of UNIQUE ( SELECT UCL FROM TN ) (with UCL being the column list in the constraint). The definition from the UNIQUE predicate says (from sql92): "If there are no two rows in T such that the value of each column in one row is non-null as is equal to the value of the corresponding column in the other row according to Subclause 8.2, "<comparison predicate>", then the result of the <unique predicate> is true; otherwise, the result of the <unique predicate> is false." So, given something like 1, 2, NULL 1, 2, NULL the unique predicate is true and the data is allowed by the constraint.