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 1692f86145..5e494ecda0 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 @@ -56,8 +56,11 @@ public class DatabaseWriterConflictTest extends AbstractWriterTest { private final static String[] TEST_KEYS_GRANDCHILD = { "id" }; private final static String[] TEST_COLUMNS_GRANDCHILD = { "id", "pid" }; + private final static String TEST_TABLE_CHILD_NOPK = "test_dataloader_child_nopk"; + private final static String[] TEST_KEYS_CHILD_NOPK = { "id", "pid" }; + private final static String[] TEST_COLUMNS_CHILD_NOPK = { "id", "pid" }; - private enum WhichTable { PARENT, CHILD, GRANDCHILD }; + private enum WhichTable { PARENT, CHILD, GRANDCHILD, CHILD_NOPK }; private WhichTable whichTable; @@ -260,6 +263,15 @@ public void testDeleteFkViolationChildTable() throws Exception { whichTable = WhichTable.PARENT; delete(firstId, firstId, "deleteparent", null); } + + @Test + public void testDeleteFkViolationChildTableNoPk() throws Exception { + String firstId = insert(getNextId(), "deleteparentnopk", null); + whichTable = WhichTable.CHILD_NOPK; + insert(getNextId(), firstId); + whichTable = WhichTable.PARENT; + delete(firstId, firstId, "deleteparentnopk", null); + } private String insert(String ...values) { if (shouldTest) { @@ -313,7 +325,16 @@ private void delete(String id, String ...values) { protected void assertTestTableEquals(String testTableId, String[] expectedValues) { String sql = "select " + getSelect(getTestColumns()) + " from " + getTestTable() + " where " + getWhere(getTestKeys()); - Map results = platform.getSqlTemplate().queryForMap(sql, Long.valueOf(testTableId)); + Map results = null; + if (whichTable != WhichTable.CHILD_NOPK) { + results = platform.getSqlTemplate().queryForMap(sql, Long.valueOf(testTableId)); + } else { + Long[] l = new Long[expectedValues.length]; + for (int i = 0; i < expectedValues.length; i++) { + l[i] = Long.valueOf(expectedValues[i]); + } + results = platform.getSqlTemplate().queryForMap(sql, (Object[]) l); + } assertEquals(getTestColumns(), expectedValues, results); } @@ -321,6 +342,9 @@ protected void assertTestTableEquals(String testTableId, String[] expectedValues protected String getTestTable() { if (whichTable == WhichTable.CHILD) return TEST_TABLE_CHILD; else if (whichTable == WhichTable.GRANDCHILD) return TEST_TABLE_GRANDCHILD; + else if (whichTable == WhichTable.CHILD_NOPK) { + return TEST_TABLE_CHILD_NOPK; + } else return TEST_TABLE; } @@ -328,6 +352,9 @@ protected String getTestTable() { protected String[] getTestKeys() { if (whichTable == WhichTable.CHILD) return TEST_KEYS_CHILD; else if (whichTable == WhichTable.GRANDCHILD) return TEST_KEYS_GRANDCHILD; + else if (whichTable == WhichTable.CHILD_NOPK) { + return TEST_KEYS_CHILD_NOPK; + } else return TEST_KEYS; } @@ -335,6 +362,9 @@ protected String[] getTestKeys() { protected String[] getTestColumns() { if (whichTable == WhichTable.CHILD) return TEST_COLUMNS_CHILD; else if (whichTable == WhichTable.GRANDCHILD) return TEST_COLUMNS_GRANDCHILD; + else if (whichTable == WhichTable.CHILD_NOPK) { + return TEST_COLUMNS_CHILD_NOPK; + } else return TEST_COLUMNS; } diff --git a/symmetric-io/src/test/java/org/jumpmind/symmetric/io/AbstractWriterTest.java b/symmetric-io/src/test/java/org/jumpmind/symmetric/io/AbstractWriterTest.java index 2813c2b49f..4ca9293c0c 100644 --- a/symmetric-io/src/test/java/org/jumpmind/symmetric/io/AbstractWriterTest.java +++ b/symmetric-io/src/test/java/org/jumpmind/symmetric/io/AbstractWriterTest.java @@ -261,7 +261,7 @@ protected String getSelect(String[] columns) { protected String getWhere(String[] columns) { StringBuilder str = new StringBuilder(); for (int i = 0; i < columns.length; i++) { - str.append(columns[i]).append(" = ?").append(i + 1 < columns.length ? "," : ""); + str.append(columns[i]).append(" = ?").append(i + 1 < columns.length ? " AND " : ""); } return str.toString(); } diff --git a/symmetric-io/src/test/resources/testDatabaseWriter.xml b/symmetric-io/src/test/resources/testDatabaseWriter.xml index efc95eb0ed..48f858c803 100644 --- a/symmetric-io/src/test/resources/testDatabaseWriter.xml +++ b/symmetric-io/src/test/resources/testDatabaseWriter.xml @@ -75,5 +75,13 @@ + + + + + + + +
\ No newline at end of file diff --git a/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/AbstractJdbcDdlReader.java b/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/AbstractJdbcDdlReader.java index ce6e6bb5a4..c557e9d54f 100644 --- a/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/AbstractJdbcDdlReader.java +++ b/symmetric-jdbc/src/main/java/org/jumpmind/db/platform/AbstractJdbcDdlReader.java @@ -1736,12 +1736,23 @@ public List getExportedForeignTableRows(ISqlTransaction transaction, L if (rows != null) { for (Row row : rows) { - // Return a TableRow with a where statement that can access this foreign table row by its primary key - DmlStatement whereSt = platform.createDmlStatement(DmlType.WHERE, foreignTable.getCatalog(), + DmlStatement whereSt = null; + String whereSql = null; + if (foreignTable.getPrimaryKeyColumns() == null || foreignTable.getPrimaryKeyColumns().length == 0) { + // No primary keys, create a where clause using the foreign key columns + whereSt = platform.createDmlStatement(DmlType.WHERE, foreignTable.getCatalog(), + foreignTable.getSchema(), foreignTable.getName(), keyColumns, + foreignTable.getColumns(), nullValues, null); + whereSql = whereSt.buildDynamicSql(BinaryEncoding.HEX, row, false, true, + keyColumns).substring(6); + } else { + // Return a TableRow with a where statement that can access this foreign table row by its primary key + whereSt = platform.createDmlStatement(DmlType.WHERE, foreignTable.getCatalog(), foreignTable.getSchema(), foreignTable.getName(), foreignTable.getPrimaryKeyColumns(), foreignTable.getColumns(), nullValues, null); - String whereSql = whereSt.buildDynamicSql(BinaryEncoding.HEX, row, false, true, + whereSql = whereSt.buildDynamicSql(BinaryEncoding.HEX, row, false, true, foreignTable.getPrimaryKeyColumns()).substring(6); + } String delimiter = platform.getDatabaseInfo().getSqlCommandDelimiter(); if (delimiter != null && delimiter.length() > 0) { whereSql = whereSql.substring(0, whereSql.length() - delimiter.length());