There seems to be an important difference between the Postgresql and DB2 implementation of a unique index across multiple fields, which include fields that can be null
For example on a table like:
create table if not exists bus_target_log
(k_targetlog_id varchar(36) primary key
,c_message_id varchar(50) not null
,c_lep_name varchar(50)
,c_unique varchar(36)
,d_delivered_timestamp timestamp not null default statement_timestamp()
,c_target varchar(30) not null)
I add a unique index:
create unique index if not exists bus_target_log_ix1
on bus_target_log
(c_unique asc
,c_message_id asc
,c_lep_name asc
);
If I know insert the following on DB2, I would get an error on the second insert.
insert into bus_target_log(k_targetlog_id, c_message_id, c_lep_name, c_target) values ('4444','111', 'targetname1', 'target'); -- works
insert into bus_target_log(k_targetlog_id, c_message_id, c_lep_name, c_target) values ('5555','111', 'targetname1', 'target'); -- fails
However on Postgresql both inserts work!
On postgresql I can run the following:
insert into bus_target_log(k_targetlog_id, c_message_id, c_lep_name, c_target, c_unique) values ('1','111', 'targetname1', 'target','1');
-- works
insert into bus_target_log(k_targetlog_id, c_message_id, c_lep_name, c_target, c_unique) values ('2','111', 'targetname1', 'target','1');
-- fails
insert into bus_target_log(k_targetlog_id, c_message_id, c_lep_name, c_target) values ('3','111', 'targetname1', 'target');
-- works
insert into bus_target_log(k_targetlog_id, c_message_id, c_lep_name, c_target) values ('4','111', 'targetname1', 'target');
-- works
This can be fixed in Postgresql by ensuring all fields in the unique index are not null, for example
create table if not exists bus_target_log
(k_targetlog_id varchar(36) primary key
,c_message_id varchar(50) not null
,c_lep_name varchar(50) not null default '0'
,c_unique varchar(36) not null default '0'
,d_delivered_timestamp timestamp not null default statement_timestamp()
,c_target varchar(30) not null)