TransactionController tc = lcc.getTransactionExecute();
DataDictionary dd = lcc.getDataDictionary();
ForeignKeyConstraintDescriptor cd =
(ForeignKeyConstraintDescriptor)
dd.getConstraintDescriptor(fkId);
// If the foreign key has been dropped, there is nothing to do.
// See DERBY-6670
//
if (cd == null) {
return;
}
ReferencedKeyConstraintDescriptor rcd =
cd.getReferencedConstraint();
long[] cids = {
cd.getIndexConglomerateDescriptor(dd).getConglomerateNumber(),
rcd.getIndexConglomerateDescriptor(dd).getConglomerateNumber()
};
final Enumeration<?> e = infoRows.elements();
while (e.hasMoreElements()) {
final DataValueDescriptor[] key =
(DataValueDescriptor[])e.nextElement();
// FIXME: This is not very efficient: we could sort the rows in
// the hash table, and then check all rows using a single scan.
ScanController indexSC = null;
boolean violation = false;
for (int idx = 0; idx < 2; idx++) {
boolean sawException = false;
try {
indexSC = tc.openScan(
cids[idx],
false,
0, // read only
TransactionController.MODE_RECORD,
TransactionController.ISOLATION_READ_COMMITTED,
(FormatableBitSet)null, // retrieve all fields
key,
ScanController.GE, // startSearchOp
null,
key,
ScanController.GT);
if (idx == 0) {
if (indexSC.next()) {
// The row with the PK still exists, so we need
// to check the referenced table's index
} else {
// No rows contain key: OK, must have been
// deleted later in transaction, or we got here
// due to pessimistic assumption on a timeout
// while checking on the insert. In any case,
// no need to check the referenced key, so
// leave.
break;
}
} else {
if (indexSC.next()) {
// We found the referenced key, all is good
} else {
// We didn't find it and we know it is present
// as a PK, so we have a violation.
violation = true;
}
}
} catch (StandardException se) {
sawException = true;
throw se;
} finally {
// Clean up resource usage
try {
if (indexSC != null) {
indexSC.close();
}
} catch (StandardException ie) {
if (!sawException) {
throw ie;
} // else: can't let it shadow preceding exception
}
}
}
if (violation) {
final SchemaDescriptor sd =
dd.getSchemaDescriptor(schemaName, tc, true);
final TableDescriptor td =
dd.getTableDescriptor(tableName, sd, tc);
final TableDescriptor rtd = rcd.getTableDescriptor();
throw StandardException.newException(
rollbackOnError ?
SQLState.LANG_DEFERRED_FK_CONSTRAINT_T :
SQLState.LANG_DEFERRED_FK_CONSTRAINT_S,
cd.getConstraintName(),
td.getQualifiedName(),
rcd.getConstraintName(),
rtd.getQualifiedName(),
RowUtil.toString(key));
}