diff --git a/jOOQ/src/main/java/org/jooq/InsertOnDuplicateStep.java b/jOOQ/src/main/java/org/jooq/InsertOnDuplicateStep.java index 8b12a4963a..7a2dd94a3d 100644 --- a/jOOQ/src/main/java/org/jooq/InsertOnDuplicateStep.java +++ b/jOOQ/src/main/java/org/jooq/InsertOnDuplicateStep.java @@ -47,6 +47,7 @@ import static org.jooq.SQLDialect.HSQLDB; import static org.jooq.SQLDialect.MARIADB; import static org.jooq.SQLDialect.MYSQL; // ... +import static org.jooq.SQLDialect.POSTGRES_9_5; // ... // ... @@ -89,7 +90,7 @@ public interface InsertOnDuplicateStep extends InsertReturning *

* These are the dialects that fulfill the above requirements: */ - @Support({ CUBRID, HSQLDB, MARIADB, MYSQL }) + @Support({ CUBRID, HSQLDB, MARIADB, MYSQL, POSTGRES_9_5 }) InsertOnDuplicateSetStep onDuplicateKeyUpdate(); /** @@ -108,21 +109,21 @@ public interface InsertOnDuplicateStep extends InsertReturning * Emulation * * - * {@link SQLDialect#MARIADB} - *

INSERT IGNORE INTO ..
+ * {@link SQLDialect#MYSQL} and {@link SQLDialect#MARIADB} + *
INSERT IGNORE INTO ..
* * - * {@link SQLDialect#MYSQL} - *
INSERT IGNORE INTO ..
+ * {@link SQLDialect#POSTGRES_9_5} + *
INSERT INTO .. ON CONFLICT DO NOTHING
* * - * {@link SQLDialect#CUBRID} + * {@link SQLDialect#CUBRID} * *
INSERT INTO .. ON DUPLICATE KEY UPDATE [any-field] = [any-field]
* * * - * {@link SQLDialect#DB2}
+ * {@link SQLDialect#DB2}
* {@link SQLDialect#HSQLDB}
* {@link SQLDialect#ORACLE}
* {@link SQLDialect#SQLSERVER}
diff --git a/jOOQ/src/main/java/org/jooq/InsertQuery.java b/jOOQ/src/main/java/org/jooq/InsertQuery.java index bb7082f11b..6a59b0b60b 100644 --- a/jOOQ/src/main/java/org/jooq/InsertQuery.java +++ b/jOOQ/src/main/java/org/jooq/InsertQuery.java @@ -54,6 +54,7 @@ import static org.jooq.SQLDialect.MARIADB; import static org.jooq.SQLDialect.MYSQL; // ... import static org.jooq.SQLDialect.POSTGRES; +import static org.jooq.SQLDialect.POSTGRES_9_5; import static org.jooq.SQLDialect.SQLITE; // ... // ... @@ -108,7 +109,7 @@ public interface InsertQuery extends StoreQuery, Insert * * @see InsertOnDuplicateStep#onDuplicateKeyUpdate() */ - @Support({ CUBRID, HSQLDB, MARIADB, MYSQL }) + @Support({ CUBRID, HSQLDB, MARIADB, MYSQL, POSTGRES_9_5 }) void onDuplicateKeyUpdate(boolean flag); /** @@ -123,17 +124,21 @@ public interface InsertQuery extends StoreQuery, Insert * Emulation * * - * {@link SQLDialect#MYSQL} - *
INSERT IGNORE INTO ..
+ * {@link SQLDialect#MYSQL} and {@link SQLDialect#MARIADB} + *
INSERT IGNORE INTO ..
* * - * {@link SQLDialect#CUBRID} + * {@link SQLDialect#POSTGRES_9_5} + *
INSERT INTO .. ON CONFLICT DO NOTHING
+ * + * + * {@link SQLDialect#CUBRID} * *
INSERT INTO .. ON DUPLICATE KEY UPDATE [any-field] = [any-field]
* * * - * {@link SQLDialect#DB2}
+ * {@link SQLDialect#DB2}
* {@link SQLDialect#HSQLDB}
* {@link SQLDialect#ORACLE}
* {@link SQLDialect#SQLSERVER}
@@ -168,7 +173,7 @@ public interface InsertQuery extends StoreQuery, Insert * * @see InsertOnDuplicateStep#onDuplicateKeyUpdate() */ - @Support({ CUBRID, HSQLDB, MARIADB, MYSQL }) + @Support({ CUBRID, HSQLDB, MARIADB, MYSQL, POSTGRES_9_5 }) void addValueForUpdate(Field field, T value); /** @@ -177,7 +182,7 @@ public interface InsertQuery extends StoreQuery, Insert * * @see InsertOnDuplicateStep#onDuplicateKeyUpdate() */ - @Support({ CUBRID, HSQLDB, MARIADB, MYSQL }) + @Support({ CUBRID, HSQLDB, MARIADB, MYSQL, POSTGRES_9_5 }) void addValueForUpdate(Field field, Field value); /** @@ -190,7 +195,7 @@ public interface InsertQuery extends StoreQuery, Insert * * @see InsertOnDuplicateStep#onDuplicateKeyUpdate() */ - @Support({ CUBRID, HSQLDB, MARIADB, MYSQL }) + @Support({ CUBRID, HSQLDB, MARIADB, MYSQL, POSTGRES_9_5 }) void addValuesForUpdate(Map, ?> map); /** diff --git a/jOOQ/src/main/java/org/jooq/LoaderOptionsStep.java b/jOOQ/src/main/java/org/jooq/LoaderOptionsStep.java index 6d21e7c762..2c8150e9a8 100644 --- a/jOOQ/src/main/java/org/jooq/LoaderOptionsStep.java +++ b/jOOQ/src/main/java/org/jooq/LoaderOptionsStep.java @@ -46,6 +46,7 @@ import static org.jooq.SQLDialect.HSQLDB; import static org.jooq.SQLDialect.MARIADB; import static org.jooq.SQLDialect.MYSQL; // ... +import static org.jooq.SQLDialect.POSTGRES_9_5; // ... // ... @@ -86,7 +87,7 @@ public interface LoaderOptionsStep> extends LoaderSourc * the default. This cannot be combined with {@link #onDuplicateKeyError()} * or {@link #onDuplicateKeyIgnore()} */ - @Support({ CUBRID, HSQLDB, MARIADB, MYSQL }) + @Support({ CUBRID, HSQLDB, MARIADB, MYSQL, POSTGRES_9_5 }) LoaderOptionsStep onDuplicateKeyUpdate(); /** diff --git a/jOOQ/src/main/java/org/jooq/impl/InsertQueryImpl.java b/jOOQ/src/main/java/org/jooq/impl/InsertQueryImpl.java index f3a3e0c06d..771e704a9f 100644 --- a/jOOQ/src/main/java/org/jooq/impl/InsertQueryImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/InsertQueryImpl.java @@ -176,6 +176,33 @@ class InsertQueryImpl extends AbstractStoreQuery implements break; } + case POSTGRES: { + toSQLInsert(ctx); + ctx.formatSeparator() + .start(INSERT_ON_DUPLICATE_KEY_UPDATE) + .keyword("on conflict") + .sql(" ("); + + if (table.getPrimaryKey() == null) { + ctx.sql("[unknown primary key]"); + } + else { + boolean qualify = ctx.qualify(); + + ctx.qualify(false) + .visit(new Fields(table.getPrimaryKey().getFields())) + .qualify(qualify); + } + + ctx.sql(") ") + .keyword("do update set") + .sql(' ') + .visit(updateMap) + .end(INSERT_ON_DUPLICATE_KEY_UPDATE); + + 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()); @@ -202,7 +229,7 @@ class InsertQueryImpl extends AbstractStoreQuery implements // ON DUPLICATE KEY IGNORE clause // ------------------------------ else if (onDuplicateKeyIgnore) { - switch (ctx.family()) { + switch (ctx.dialect()) { // MySQL has a nice, native syntax for this case MARIADB: @@ -214,6 +241,15 @@ class InsertQueryImpl extends AbstractStoreQuery implements break; } + case POSTGRES_9_5: { + toSQLInsert(ctx); + ctx.formatSeparator() + .start(INSERT_ON_DUPLICATE_KEY_UPDATE) + .keyword("on conflict do nothing") + .end(INSERT_ON_DUPLICATE_KEY_UPDATE); + break; + } + // CUBRID can emulate this using ON DUPLICATE KEY UPDATE case CUBRID: { FieldMapForUpdate update = new FieldMapForUpdate(INSERT_ON_DUPLICATE_KEY_UPDATE_ASSIGNMENT); @@ -234,9 +270,21 @@ class InsertQueryImpl extends AbstractStoreQuery implements // Some databases allow for emulating this clause using a MERGE statement /* [pro] xx xxxx xxxx + xxxx xxxxxx + xxxx xxxxxxx + xxxx xxxxxxxxx + xxxx xxxxxxx xxxx xxxxxxxxxx + xxxx xxxxxxxxxx + xxxx xxxxxxxxxx + + xxxx xxxxxxxxxx + xxxx xxxxxxxxxxxxxx + xxxx xxxxxxxxxxxxxx + xxxx xxxxxxxxxxxxxx + xxxx xxxxxxx xx [/pro] */ case HSQLDB: {