[#2508] Support ON DUPLICATE KEY UPDATE in H2

This commit is contained in:
lukaseder 2018-03-28 10:47:00 +02:00
parent 4f4f0600a6
commit c61a5fd970
3 changed files with 19 additions and 11 deletions

View File

@ -39,6 +39,7 @@ package org.jooq;
import static org.jooq.SQLDialect.CUBRID;
// ...
import static org.jooq.SQLDialect.H2;
import static org.jooq.SQLDialect.HSQLDB;
// ...
import static org.jooq.SQLDialect.MARIADB;
@ -123,9 +124,9 @@ public interface InsertOnDuplicateStep<R extends Record> extends InsertReturning
* {@link DSLContext#mergeInto(Table)}).</li>
* </ul>
* <p>
* These are the dialects that fulfill the above requirements:
* H2 supports this clause in MySQL mode.
*/
@Support({ CUBRID, HSQLDB, MARIADB, MYSQL, POSTGRES_9_5 })
@Support({ CUBRID, H2, HSQLDB, MARIADB, MYSQL, POSTGRES_9_5 })
InsertOnDuplicateSetStep<R> onDuplicateKeyUpdate();
/**

View File

@ -154,7 +154,7 @@ public interface InsertQuery<R extends Record> extends StoreQuery<R>, Insert<R>
*
* @see InsertOnDuplicateStep#onDuplicateKeyUpdate()
*/
@Support({ CUBRID, HSQLDB, MARIADB, MYSQL, POSTGRES_9_5 })
@Support({ CUBRID, H2, HSQLDB, MARIADB, MYSQL, POSTGRES_9_5 })
void onDuplicateKeyUpdate(boolean flag);
/**
@ -218,7 +218,7 @@ public interface InsertQuery<R extends Record> extends StoreQuery<R>, Insert<R>
*
* @see InsertOnDuplicateStep#onDuplicateKeyUpdate()
*/
@Support({ CUBRID, HSQLDB, MARIADB, MYSQL, POSTGRES_9_5 })
@Support({ CUBRID, H2, HSQLDB, MARIADB, MYSQL, POSTGRES_9_5 })
<T> void addValueForUpdate(Field<T> field, T value);
/**
@ -227,7 +227,7 @@ public interface InsertQuery<R extends Record> extends StoreQuery<R>, Insert<R>
*
* @see InsertOnDuplicateStep#onDuplicateKeyUpdate()
*/
@Support({ CUBRID, HSQLDB, MARIADB, MYSQL, POSTGRES_9_5 })
@Support({ CUBRID, H2, HSQLDB, MARIADB, MYSQL, POSTGRES_9_5 })
<T> void addValueForUpdate(Field<T> field, Field<T> value);
/**
@ -240,7 +240,7 @@ public interface InsertQuery<R extends Record> extends StoreQuery<R>, Insert<R>
*
* @see InsertOnDuplicateStep#onDuplicateKeyUpdate()
*/
@Support({ CUBRID, HSQLDB, MARIADB, MYSQL, POSTGRES_9_5 })
@Support({ CUBRID, H2, HSQLDB, MARIADB, MYSQL, POSTGRES_9_5 })
void addValuesForUpdate(Map<?, ?> map);
/**

View File

@ -44,6 +44,7 @@ import static org.jooq.Clause.INSERT_ON_DUPLICATE_KEY_UPDATE;
import static org.jooq.Clause.INSERT_ON_DUPLICATE_KEY_UPDATE_ASSIGNMENT;
import static org.jooq.Clause.INSERT_RETURNING;
import static org.jooq.Clause.INSERT_SELECT;
import static org.jooq.SQLDialect.H2;
import static org.jooq.SQLDialect.MARIADB;
import static org.jooq.SQLDialect.MYSQL;
// ...
@ -256,15 +257,26 @@ final class InsertQueryImpl<R extends Record> extends AbstractStoreQuery<R> impl
// MySQL has a nice syntax for this
case CUBRID:
case H2:
case MARIADB:
case MYSQL: {
// [#2508] In H2, this syntax is supported in MySQL MODE (we're assuming users will
// set this mode in order to profit from this functionality). Up until
// H2 1.4.197, qualification of columns in the ON DUPLICATE KEY UPDATE clause
// wasn't supported (see https://github.com/h2database/h2database/issues/1027)
boolean oldQualify = ctx.qualify();
boolean newQualify = ctx.family() == H2 ? false : oldQualify;
toSQLInsert(ctx);
ctx.formatSeparator()
.start(INSERT_ON_DUPLICATE_KEY_UPDATE)
.visit(K_ON_DUPLICATE_KEY_UPDATE)
.formatIndentStart()
.formatSeparator()
.qualify(newQualify)
.visit(updateMap)
.qualify(oldQualify)
.formatIndentEnd()
.end(INSERT_ON_DUPLICATE_KEY_UPDATE);
@ -330,11 +342,6 @@ final class InsertQueryImpl<R extends Record> extends AbstractStoreQuery<R> impl
break;
}
// Some dialects can't really handle this clause. Emulation should be done in two steps
case H2: {
throw new SQLDialectNotSupportedException("The ON DUPLICATE KEY UPDATE clause cannot be emulated for " + ctx.dialect());
}
// Some databases allow for emulating this clause using a MERGE statement