diff --git a/symmetric-db/src/main/java/org/jumpmind/db/platform/postgresql/PostgreSqlDmlStatement95.java b/symmetric-db/src/main/java/org/jumpmind/db/platform/postgresql/PostgreSqlDmlStatement95.java index 9fd160a21a..51c70cb39b 100644 --- a/symmetric-db/src/main/java/org/jumpmind/db/platform/postgresql/PostgreSqlDmlStatement95.java +++ b/symmetric-db/src/main/java/org/jumpmind/db/platform/postgresql/PostgreSqlDmlStatement95.java @@ -6,6 +6,8 @@ import org.jumpmind.db.platform.DatabaseInfo; public class PostgreSqlDmlStatement95 extends PostgreSqlDmlStatement { + + public static final String ON_CONFLICT_DO_NOTHING = "on conflict do nothing"; public PostgreSqlDmlStatement95(DmlType type, String catalogName, String schemaName, String tableName, Column[] keysColumns, Column[] columns, boolean[] nullKeyValues, DatabaseInfo databaseInfo, @@ -20,9 +22,18 @@ public String buildInsertSql(String tableName, Column[] keys, Column[] columns) appendColumns(sql, columns, false); sql.append(") values ("); appendColumnParameters(sql, columns); - sql.append(") on conflict do nothing"); + sql.append(") ").append(ON_CONFLICT_DO_NOTHING); return sql.toString(); } + + @Override + public String getSql(boolean allowIgnoreOnConflict) { + if (allowIgnoreOnConflict) { + return sql; + } else { + return sql.replace(ON_CONFLICT_DO_NOTHING, ""); + } + } @Override public Column[] getMetaData() { diff --git a/symmetric-db/src/main/java/org/jumpmind/db/sql/DmlStatement.java b/symmetric-db/src/main/java/org/jumpmind/db/sql/DmlStatement.java index ba19ebc13c..42730554b9 100644 --- a/symmetric-db/src/main/java/org/jumpmind/db/sql/DmlStatement.java +++ b/symmetric-db/src/main/java/org/jumpmind/db/sql/DmlStatement.java @@ -375,6 +375,10 @@ public String getColumnsSql(Column[] columns) { public String getSql() { return sql; } + + public String getSql(boolean allowIgnoreOnConflict) { + return sql; + } public DmlType getDmlType() { return dmlType; diff --git a/symmetric-io/src/integrationTest/java/org/jumpmind/symmetric/io/data/writer/DatabaseWriterConflictTest.java b/symmetric-io/src/integrationTest/java/org/jumpmind/symmetric/io/data/writer/DatabaseWriterConflictTest.java index 0975511dc5..d2e0b9e73e 100644 --- a/symmetric-io/src/integrationTest/java/org/jumpmind/symmetric/io/data/writer/DatabaseWriterConflictTest.java +++ b/symmetric-io/src/integrationTest/java/org/jumpmind/symmetric/io/data/writer/DatabaseWriterConflictTest.java @@ -85,12 +85,12 @@ public void testInsertUkViolation() throws Exception { @Test public void testInsertUkViolationDeleteFkViolation() throws Exception { - String firstId = insert(getNextId(), "twin", null); + String firstId = insert(getNextId(), "twin2", null); String secondId = insert(getNextId(), "depends1", firstId); String thirdId = insert(getNextId(), "depends2", firstId); insert(getNextId(), "depends3", secondId); insert(getNextId(), "depends4", thirdId); - insert(getNextId(), "twin", null); + insert(getNextId(), "twin2", null); } @Test @@ -182,12 +182,12 @@ public void testUpdatePkViolation() throws Exception { // TODO: Case when row blocks itself with a FK violation //@Test public void testUpdatePkViolationDeleteFkViolationBlockingSelf() throws Exception { - String firstId = insert(getNextId(), "update-pk1", null); - String secondId = insert(getNextId(), "update-pk2", firstId); + String firstId = insert(getNextId(), "update2-pk1", null); + String secondId = insert(getNextId(), "update2-pk2", firstId); // this row blocks itself (fk violation), so it gets deleted, then the update gets 0 rows // would it work if we then inserted the row, got a PK violation, then updated new values? - update(secondId, firstId, "update-pk2", null); + update(secondId, firstId, "update2-pk2", null); } @Test diff --git a/symmetric-io/src/main/java/org/jumpmind/symmetric/io/data/writer/DefaultDatabaseWriter.java b/symmetric-io/src/main/java/org/jumpmind/symmetric/io/data/writer/DefaultDatabaseWriter.java index c540ce1a1b..102b67bf09 100644 --- a/symmetric-io/src/main/java/org/jumpmind/symmetric/io/data/writer/DefaultDatabaseWriter.java +++ b/symmetric-io/src/main/java/org/jumpmind/symmetric/io/data/writer/DefaultDatabaseWriter.java @@ -24,7 +24,6 @@ import java.io.StringReader; import java.lang.reflect.Method; import java.sql.SQLException; -import java.sql.SQLIntegrityConstraintViolationException; import java.sql.Types; import java.util.ArrayList; import java.util.Arrays; @@ -225,7 +224,7 @@ protected LoadStatus insert(CsvData data) { return LoadStatus.SUCCESS; } else { context.put(CUR_DATA,getCurData(getTransaction())); - context.setLastError(new SQLIntegrityConstraintViolationException("duplicate", "23000")); + context.setLastError(getInsertException2(data, values)); return LoadStatus.CONFLICT; } } catch (SqlException ex) { @@ -251,7 +250,21 @@ protected LoadStatus insert(CsvData data) { } } - private boolean isUniqueIndexViolation(Throwable ex, Table targetTable) { + private SqlException getInsertException2(CsvData data, String[] values) { + SqlException ret = null; + String sql = currentDmlStatement.getSql(false); + Object[] dmlValues = getPlatform().getObjectValues(batch.getBinaryEncoding(), values, + currentDmlStatement.getMetaData(), false, writerSettings.isFitToColumn()); + try { + getPlatform().getSqlTemplate().update(sql, dmlValues); + } catch(SqlException ex) { + ret = ex; + } + + return ret; + } + + private boolean isUniqueIndexViolation(Throwable ex, Table targetTable) { String violatedIndexName = getPlatform().getSqlTemplate().getUniqueKeyViolationIndexName(ex); for (IIndex index : targetTable.getIndices()) { if (index.isUnique() && (index.getName().equals(violatedIndexName))) {