From 639fbe9b5a5c757a45eac4dc0eb5675227e85aae Mon Sep 17 00:00:00 2001 From: Chris Henson Date: Mon, 1 May 2017 11:39:43 -0400 Subject: [PATCH] 0003086: Missing foreign key reference of null is not handled properly in the foreign key recovery code --- .../symmetric/service/impl/DataService.java | 56 ++++++++++++------- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/DataService.java b/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/DataService.java index 3e776a6e2c..c8de093242 100644 --- a/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/DataService.java +++ b/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/DataService.java @@ -1608,37 +1608,55 @@ protected List getForeignTableRows(List tableRows) throws Cl } Row whereRow = new Row(fk.getReferenceCount()); String referenceColumnName = null; + boolean[] nullValues = new boolean[fk.getReferenceCount()]; + int index = 0; for (Reference ref : fk.getReferences()) { Column foreignColumn = foreignTable.findColumn(ref.getForeignColumnName()); Object value = tableRow.getRow().get(ref.getLocalColumnName()); + nullValues[index++] = value == null; referenceColumnName = ref.getLocalColumnName(); whereRow.put(foreignColumn.getName(), value); foreignColumn.setPrimaryKey(true); } - DmlStatement whereSt = platform.createDmlStatement(DmlType.WHERE, foreignTable, null); - String whereSql = whereSt.buildDynamicSql(symmetricDialect.getBinaryEncoding(), whereRow, 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()); + boolean allNullValues = true; + for (boolean b : nullValues) { + if (!b) { + allNullValues = false; + break; + } } - Row foreignRow = new Row(foreignTable.getColumnCount()); - if (foreignTable.getForeignKeyCount() > 0) { - DmlStatement selectSt = platform.createDmlStatement(DmlType.SELECT, foreignTable, null); - Object[] keys = whereRow.toArray(foreignTable.getPrimaryKeyColumnNames()); - Map values = sqlTemplate.queryForMap(selectSt.getSql(), keys); - if (values == null) { - log.warn("Unable to reload rows for missing foreign key data for table '{}', parent data not found. Using sql='{}' with keys '{}'",table.getName(), selectSt.getSql(), keys); - } else { - foreignRow.putAll(values); + if (!allNullValues) { + DmlStatement whereSt = platform.createDmlStatement(DmlType.WHERE, foreignTable.getCatalog(), foreignTable.getSchema(), + foreignTable.getName(), foreignTable.getPrimaryKeyColumns(), foreignTable.getColumns(), nullValues, null); + String whereSql = whereSt.buildDynamicSql(symmetricDialect.getBinaryEncoding(), whereRow, 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()); } - } - TableRow foreignTableRow = new TableRow(foreignTable, foreignRow, whereSql,referenceColumnName, fk.getName()); - fkDepList.add(foreignTableRow); - log.debug("Add foreign table reference '{}' whereSql='{}'", foreignTable.getName(), whereSql); + Row foreignRow = new Row(foreignTable.getColumnCount()); + if (foreignTable.getForeignKeyCount() > 0) { + DmlStatement selectSt = platform.createDmlStatement(DmlType.SELECT, foreignTable, null); + Object[] keys = whereRow.toArray(foreignTable.getPrimaryKeyColumnNames()); + Map values = sqlTemplate.queryForMap(selectSt.getSql(), keys); + if (values == null) { + log.warn( + "Unable to reload rows for missing foreign key data for table '{}', parent data not found. Using sql='{}' with keys '{}'", + table.getName(), selectSt.getSql(), keys); + } else { + foreignRow.putAll(values); + } + } + + TableRow foreignTableRow = new TableRow(foreignTable, foreignRow, whereSql, referenceColumnName, fk.getName()); + fkDepList.add(foreignTableRow); + log.debug("Add foreign table reference '{}' whereSql='{}'", foreignTable.getName(), whereSql); + } else { + log.debug("The foreign table reference was null for {}", foreignTable.getName()); + } } else { log.debug("Foreign table '{}' not found for foreign key '{}'", fk.getForeignTableName(), fk.getName()); }