Is there a way to create an UNIQUE INDEX in H2?

14,381 views
Skip to first unread message

Rodrigo

unread,
Oct 5, 2016, 12:44:38 PM10/5/16
to H2 Database
I'm trying to add this statement in my h2 script:

CREATE UNIQUE INDEX "SOME_NAME" ON "SOME_TABLE_NAME" (COLUMN1,COLUMN2)

Looks like it is being bypassing, because I was able to insert two identical rows in my h2, but not in my actual DB (Oracle).

Is there a way to create that UNIQUE INDEX?



Steve McLeod

unread,
Oct 7, 2016, 4:19:08 AM10/7/16
to H2 Database
H2 does restrict inserts according to UNIQUE index constraints.

Can you post complete reproduction steps?

Rodrigo

unread,
Oct 7, 2016, 9:29:02 AM10/7/16
to H2 Database
Sure, this is my h2 Script:

CREATE TABLE "SOMETHING_TABLE"
  (
    "COLUMN1"           CHAR(10 BYTE),
    "COLUMN2"       CHAR(10 BYTE),
    "COLUMN3"          CHAR(2 BYTE),
    "COLUMN4"    VARCHAR2(9 BYTE)
  )

ALTER TABLE CMASTER ALTER COLUMN COLUMN1 SET NOT NULL;

  
CREATE UNIQUE INDEX "PK_SOMETHING_TABLE" ON "SOMETHING_TABLE"
  (
    "COLUMN1", "COLUMN2", "COLUMN3"
  )

Rodrigo

unread,
Oct 7, 2016, 7:12:45 PM10/7/16
to H2 Database
Actually there's a way, but it doesn't support composite index:

CREATE INDEX IDXNAME ON TEST(NAME)


So I would like to do something like:


CREATE INDEX IDXNAME ON TEST(SOME_COLUMN1,SOME_COLUMN2,SOME_COLUMN3)

Noel Grandin

unread,
Oct 8, 2016, 10:43:32 AM10/8/16
to h2-da...@googlegroups.com
For starters, your script does not run on H2 because it is using weird syntax.

However, if I fix it, H2 correctly throws a constraint violated exception.
CREATE TABLE SOMETHING_TABLE
  (
    COLUMN1           CHAR(10),
    COLUMN2       CHAR(10),
    COLUMN3          CHAR(2),
    COLUMN4    VARCHAR2(9)
  );
CREATE UNIQUE INDEX PK_SOMETHING_TABLE ON SOMETHING_TABLE
(
    COLUMN1, COLUMN2, COLUMN3
 );
insert into SOMETHING_TABLE values(1, 1, 1, 1) ;
insert into SOMETHING_TABLE values(1, 1, 1, 1) ;

Rodrigo

unread,
Oct 8, 2016, 9:49:29 PM10/8/16
to H2 Database
Yes, Sorry, I copied a bad formatted script. Regardless of that I just used your fixed script and it didn't work. I inserted 2 identical rows and I didn't get any error. All my Junit test passed.

Rodrigo

unread,
Oct 8, 2016, 9:56:26 PM10/8/16
to H2 Database
In fact the only way the unique index worked, was using a single field to index, like:

CREATE UNIQUE INDEX PK_SOMETHING_TABLE ON SOMETHING_TABLE( COLUMN1);

Try to create an index using more than one field, didn't work for me.

Rodrigo

unread,
Oct 8, 2016, 10:59:51 PM10/8/16
to H2 Database
I changed my mind. It worked, But for the scenario that I'm trying to test, it didn't work :)

It works fine if we use not null values related to the index, when inserting, for example:

insert into SOMETHING_TABLE values(1, 1, 1, 1) ;
insert into SOMETHING_TABLE values(1, 1, 1, 1) ;

Using above sentence, I will get an error.

But it I try to insert:

insert into SOMETHING_TABLE values(1, NULL, NULL, NULL) ;
insert into SOMETHING_TABLE values(1, NULL, NULL, NULL) ;


I won't get any errors and my Junit test passed without problems, which isn't what I was expecting

Noel Grandin

unread,
Oct 9, 2016, 1:32:17 AM10/9/16
to h2-da...@googlegroups.com
Confirmed that that this is indeed a bug, even in latest master, please log an issue in our tracker so we don't forget it.


Thanks,

Alexey Panchenko

unread,
Oct 9, 2016, 3:33:55 AM10/9/16
to h2-da...@googlegroups.com
That's actually a feature defined by the SQL standard.
E.g. you can see "Null values are not considered equal" in https://www.postgresql.org/docs/current/static/indexes-unique.html

A workaround can be partial indexes if supported by the database, something like:
CREATE UNIQUE INDEX IDX_12_3NULL ON SOMETHING_TABLE (COLUMN1, COLUMN2) WHERE COLUMN3 IS NULL;

In H2 I think it should be possible to add computed columns with NOT NULL results and then index those.

Regards,
Alex

--
You received this message because you are subscribed to the Google Groups "H2 Database" group.
To unsubscribe from this group and stop receiving emails from it, send an email to h2-database+unsubscribe@googlegroups.com.
To post to this group, send email to h2-da...@googlegroups.com.
Visit this group at https://groups.google.com/group/h2-database.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages