Skip to content

Commit

Permalink
0003086: Missing foreign key reference of null is not handled properly
Browse files Browse the repository at this point in the history
in the foreign key recovery code
  • Loading branch information
chenson42 committed May 1, 2017
1 parent 51deeed commit 639fbe9
Showing 1 changed file with 37 additions and 19 deletions.
Expand Up @@ -1608,37 +1608,55 @@ protected List<TableRow> getForeignTableRows(List<TableRow> 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<String, Object> 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<String, Object> 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());
}
Expand Down

0 comments on commit 639fbe9

Please sign in to comment.