TransactionController tc, ContextManager cm,
FKInfo fkInfo, long fkConglom, long pkConglom,
String fkConstraintName)
throws StandardException
{
ExecRow template;
GroupFetchScanController refScan = null;
GroupFetchScanController fkScan = null;
try
{
template = makeIndexTemplate(fkInfo, fullTemplate, cm);
/*
** The indexes have been dropped and recreated, so
** we need to get the new index conglomerate number.
*/
fkScan =
tc.openGroupFetchScan(
fkConglom,
false, // hold
0, // read only
tc.MODE_TABLE, // doesn't matter,
// already locked
tc.ISOLATION_READ_COMMITTED, // doesn't matter,
// already locked
(FormatableBitSet)null, // retrieve all fields
(DataValueDescriptor[])null, // startKeyValue
ScanController.GE, // startSearchOp
null, // qualifier
(DataValueDescriptor[])null, // stopKeyValue
ScanController.GT // stopSearchOp
);
if (SanityManager.DEBUG)
{
/*
** Bulk insert replace calls this method regardless
** of whether or not any rows were inserted because
** it has to check any referencing foreign keys
** after the replace. Otherwise, we
** make sure that we actually have a row in the fk.
** If not, we have an error because we thought that
** since indexRows != null, we must have gotten some
** rows.
*/
if (! bulkInsertReplace)
{
SanityManager.ASSERT(fkScan.next(),
"No rows in fk index, even though indexRows != null");
/*
** Crank up the scan again.
*/
fkScan.reopenScan(
(DataValueDescriptor[])null, // startKeyValue
ScanController.GE, // startSearchOp
null, // qualifier
(DataValueDescriptor[])null, // stopKeyValue
ScanController.GT // stopSearchOp
);
}
}
/*
** Open the referenced key scan. Use row locking on
** the referenced table unless it is self-referencing
** (in which case we don't need locks)
*/
refScan =
tc.openGroupFetchScan(
pkConglom,
false, // hold
0, // read only
(fkConglom == pkConglom) ?
tc.MODE_TABLE :
tc.MODE_RECORD,
tc.ISOLATION_READ_COMMITTED, // read committed is
// good enough
(FormatableBitSet)null, // retrieve all fields
(DataValueDescriptor[])null, // startKeyValue
ScanController.GE, // startSearchOp
null, // qualifier
(DataValueDescriptor[])null, // stopKeyValue
ScanController.GT // stopSearchOp
);
/*
** Give the scans to the bulk checker to do its
** magic. It will do a merge on the two indexes.
*/
ExecRow firstFailedRow = template.getClone();
RIBulkChecker riChecker = new RIBulkChecker(refScan,
fkScan,
template,
true, // fail on 1st failure
(ConglomerateController)null,