I'm trying to figure out if there's a way to drop a unique constraint using 
a SQL statement that will work for both MySQL and H2 (setup in MySQL 
compatibility mode). Basically MySQL is expecting the syntax:

ALTER TABLE <table> DROP INDEX <index_name>

However, when this is used with H2 it can't find the index because it 
appears that H2 is creating the index suffixed with the keyword "INDEX_C" 
or some other test scenarios I did it looks like during renames the index 
gets suffixed with "INDEX_<number>". Here's some example code that 
reproduces the issue:

import java.io.InputStream;
>
> import java.io.InputStreamReader;
>
> import java.sql.Connection;
>
> import java.sql.DriverManager;
>
> import java.sql.ResultSet;
>
> import java.sql.SQLException;
>
>
> import org.h2.tools.RunScript;
>
> import org.junit.Test;
>
>
> public class TestH2 {
>
>
>     @Test
>
>     public void testIndexIssue() throws SQLException, 
> ClassNotFoundException {
>
>         Class.forName("org.h2.Driver");
>
>         InputStream in = getClass().getResourceAsStream("script.sql");
>
>         if (in == null) {
>
>             System.out.println("Please add the file script.sql to the 
> classpath, package "
>
>                     + getClass().getPackage().getName());
>
>         } else {
>
>             Connection conn = DriverManager.getConnection(
> "jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false;MODE=MYSQL;IGNORECASE=TRUE"
> );
>
>             RunScript.execute(conn, new InputStreamReader(in));
>
>             ResultSet rs = conn.getMetaData().getIndexInfo(null, null, 
> "test_table", false, true);
>
>             while (rs.next()) {
>
>                 System.out.println(rs.getString("INDEX_NAME"));
>
>             }
>
>             conn.close();
>
>         }
>
>     }
>
> }
>

Then the script.sql it loads has the following statements:

CREATE TABLE test_table (
>
>     id serial,
>
>     unique_field bigint unsigned not null,
>
>     CONSTRAINT pk_test_table PRIMARY KEY (
>
>         id ASC
>
>     ),
>
>     CONSTRAINT uk_test UNIQUE KEY (
>
>         unique_field
>
>     )
>
> );
>
>
> /* Comment this out to see the available indexes in the test output */
>
> ALTER TABLE test_table DROP INDEX uk_test;
>
>
>

Which will then fail with:

org.h2.jdbc.JdbcSQLException: Index "UK_TEST" not found; SQL statement:

If you comment out the drop index line at the end the test will print out 
the indexes which shows:

primary_key_c

uk_test_index_c


I'm using Flyway for migrations with H2 as a test database and MySQL in 
production. Flyway doesn't abstract SQL language differences but that has 
been okay for the most part as H2 has been compatible however for this 
particular issue I haven't found a way to handle this short of writing two 
different migrations or I wrote a Java based migration that just checks for 
the use of H2 and replaces "DROP INDEX" with "DROP CONSTRAINT".
 

-- 
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 [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/h2-database.
For more options, visit https://groups.google.com/d/optout.

Reply via email to