final TransactionController tc = lcc.getTransactionExecute();
final Enumeration<?> e = ht.elements();
DataDictionary dd = lcc.getDataDictionary();
KeyConstraintDescriptor cd = (KeyConstraintDescriptor)
dd.getConstraintDescriptor(constraintId);
if (cd == null) {
// Constraint dropped, nothing to do.
return;
}
long indexCID = cd.getIndexConglomerateDescriptor(dd)
.getConglomerateNumber();
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 sawException = false;
try {
indexSC = tc.openScan(
indexCID,
false,
0, // read only
TransactionController.MODE_RECORD,
TransactionController.ISOLATION_READ_COMMITTED_NOHOLDLOCK,
(FormatableBitSet)null, // retrieve all fields
key,
ScanController.GE, // startSearchOp
null,
key,
ScanController.GT);
if (indexSC.next()) {
if (indexSC.next()) {
// two matching rows found, constraint violated
throw StandardException.newException(
rollbackOnError ?
SQLState.
LANG_DEFERRED_DUPLICATE_KEY_CONSTRAINT_T :
SQLState.
LANG_DEFERRED_DUPLICATE_KEY_CONSTRAINT_S,
cd.getConstraintName(),
cd.getTableDescriptor().getName());
} // else exactly one row contains key: OK
} 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.