If this fails for Oracle and MS SQL Server, then those databases are
not standards compliant in this regard by default. The ANSI SQL-92
standard says that NULL is not equal to NULL, that means the two rows
are not considered equal. I know this is a strange rule, and I don't
like it myself, but this is what is defined by the standard.
According to my tests, it works for MySQL, PostgreSQL, and H2. It
fails for Derby, HSQLDB, Oracle.
drop table t5;
create table t5(c1 char(1), c2 char(2));
create unique index i5 on t5(c1, c2);
insert into t5 values ('a', null);
insert into t5 values ('a', null);
I think that MS SQL Server has an option 'ANSI_NULLS' to achieve
standards compliance in this regard. See
http://weblogs.sqlteam.com/davidm/archive/2004/05/21/1364.aspx
What I could do is add a compatibility option for Derby, HSQLDB and
Oracle. However I like to avoid that if possible. Do you need this
feature?
Regards,
Thomas
> Jerry Brenner (jbre...@guidewire.com), a past database internals
> developer at Sybase and elsewhere responded:
> ANSI does not define the semantics of indexes, but the applicable
> behavior for nulls is DISTINCT and primary and unique constraints, not
> =
Well, let's just say NULL behavior is complicated and not well
defined. It doesn't really matter who is 'right' and who is 'wrong'
;-) The main problem is that databases behave differently. For H2 I
picked what I thought is the more 'standards compliant' way. I'm not
sure if that was the right decision if it turns out that only MySQL
and PostgreSQL support multiple rows with NULL.
It would be much simpler if NULL is considered equal to NULL, smaller
than any other value, and if there was no ternary logic
(http://en.wikipedia.org/wiki/Ternary_logic). But that's just a
fantasy ;-)
> Derby definitely has the correct ANSI semantics, because we used the
> ANSI document and the VP of engineering had been on the ANSI committee
> for a number of years.
Hehe ;-) I was working at PointBase with Steve Jones, he was also on
the ANSI committee. As far as I remember, he said the exact opposite
;-)
> A compatibility option, at a minimum, that would enable H2 to work as
> Oracle and SQL Server with filtered indexes do, that is, a unique
> index insures uniqueness of all non-null values, would be of great
> benefit.
Sure, I agree. I will add a new compatibility flag
'uniqueIndexNullDistinct' in the next release to only allow one row
with 'NULL' in a unique index. This flag will be enabled for Derby,
Oracle, MSSQLServer, and HSQLDB (but not for Regular, MySQL, and
PostgreSQL.
Regards,
Thomas
> BTW, when I installed the latest download for Windows, the shortcuts
> and Program Files folder is named H2 1.0.71 instead of H2 1.0.74.
Could the reason be that you have renamed it from just "H2" to "H2
1.0.71" when you installed it the first time? The default is "H2". It
will probably use the same name if you install it over an older
version.
So far I thought Oracle doesn't allow multiple NULL when using a
unique constraint or index. I have tested it now and it works. In the
next release, I will fix the Oracle mode.
Thanks,
Thomas