Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Duplicate column name on H2 with MODE=PostgreSQL #21

Closed
kressi opened this issue Jul 2, 2022 · 4 comments
Closed

Duplicate column name on H2 with MODE=PostgreSQL #21

kressi opened this issue Jul 2, 2022 · 4 comments

Comments

@kressi
Copy link

kressi commented Jul 2, 2022

Running migrations on H2 with MODE=PostgreSQL causes following exception.

io.r2dbc.spi.R2dbcBadGrammarException: Duplicate column name "?column?"; SQL statement:
insert into "migrations_lock"(id, locked) select * from (select 1, false) x  where not exists(select * from "migrations_lock") [42121-214]

I am not sure whether that's an issue of r2dbc-migrate or r2dbc-h2. I don`t understand why that issue occurs.

  • Versions
    • name.nkonev.r2dbc-migrate:r2dbc-migrate-spring-boot-starter:2.7.6
    • org.springframework.boot:spring-boot-starter-parent:2.7.1
  • Complete logs
  • application.yml
@nkonev
Copy link
Owner

nkonev commented Jul 2, 2022

Try to force postgres dialect, e. g.

spring:
  r2dbc:
    url: r2dbc:h2:mem:///testdb;MODE=PostgreSQL
    username: sa
    password: ''

r2dbc:
  migrate:
    dialect: POSTGRESQL
    resources-paths:
      - classpath:/db/migration/*.sql

@kressi
Copy link
Author

kressi commented Jul 2, 2022

Now I get a syntax error instead of duplicate column.

io.r2dbc.spi.R2dbcBadGrammarException: Syntax error in SQL statement "insert into ""migrations_lock""(id, locked) values (1, false) [*]on conflict (id) do nothing"; SQL statement:
insert into "migrations_lock"(id, locked) values (1, false) on conflict (id) do nothing [42000-214]

@nkonev
Copy link
Owner

nkonev commented Jul 2, 2022

@kressi

It seems the issue is caused by quoted table names
Screenshot from 2022-07-02 13-44-20

But H2 migrations are works without Postgres compatibility mode.

I also tried to provide custom dialect to avoid quotes but H2 in Postgres compatibility mode isn't able to parse modern Postgres syntax

@Component
    public static class SimplePostgresqlDialect implements SqlQueries {
        @Override
        public List<String> createInternalTables() {
            return Arrays.asList(
                    "create table if not exists simple_migrations(id int primary key, description text)",
                    "create table if not exists simple_migrations_lock(id int primary key, locked boolean not null)",
                    "insert into simple_migrations_lock(id, locked) values (1, false) on conflict (id) do nothing"
            );
        }

        @Override
        public String getMaxMigration() {
            return "select max(id) from simple_migrations";
        }

        public String insertMigration() {
            return "insert into simple_migrations(id, description) values ($1, $2)";
        }

        @Override
        public Statement createInsertMigrationStatement(Connection connection, FilenameParser.MigrationInfo migrationInfo) {
            return connection
                    .createStatement(insertMigration())
                    .bind("$1", migrationInfo.getVersion())
                    .bind("$2", migrationInfo.getDescription());
        }

        @Override
        public String tryAcquireLock() {
            return "update simple_migrations_lock set locked = true where id = 1 and locked = false";
        }

        @Override
        public String releaseLock() {
            return "update simple_migrations_lock set locked = false where id = 1";
        }
    }

Screenshot from 2022-07-02 13-51-24

io.r2dbc.spi.R2dbcBadGrammarException: Syntax error in SQL statement "insert into simple_migrations_lock(id, locked) values (1, false) [*]on conflict (id) do nothing"; SQL statement:
insert into simple_migrations_lock(id, locked) values (1, false) on conflict (id) do nothing [42000-214]

This library is heavy relies on upsert-like syntax CREATE TABLE .. ON CONFLICT DO NOTHING so I can conclude that it's no way to start it against H2 in Postgres compatibility mode.

@nkonev
Copy link
Owner

nkonev commented Jul 2, 2022

You can play with tuning dialect or (I recommend) to use testcontainers as I did https://github.com/nkonev/r2dbc-migrate-example, because testing with testcontainers runs real Postgres.

@nkonev nkonev closed this as completed Jul 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants