Transaction rawtran,
LogicalUndoable pageOp,
LimitObjectInput in)
throws StandardException, IOException
{
ControlRow root = null;
ControlRow control_row = null;
DataValueDescriptor[] logged_index_row_template = null;
DataValueDescriptor[] template = null;
Page ret_page = null;
ContainerHandle container = pageOp.getContainer();
RecordHandle rechandle = pageOp.getRecordHandle();
boolean ok_exit = false;
int compare_result = 1;
B2I btree = null;
// Open the btree to associate the open contain handle, thus the
// current xact with all subsequent operations during undo.
try
{
// Need Conglomerate to create templates - get from the root page.
root = ControlRow.get(container, BTree.ROOTPAGEID);
if (SanityManager.DEBUG)
SanityManager.ASSERT(root.getPage().isLatched());
btree = (B2I) root.getConglom(B2I.FORMAT_NUMBER);
if (SanityManager.DEBUG)
SanityManager.ASSERT(btree instanceof B2I);
// create a template for the logged index row from the conglomerate.
logged_index_row_template = btree.createTemplate(rawtran);
// create a template for the page index row from the conglomerate.
template = btree.createTemplate(rawtran);
}
finally
{
if (root != null)
root.release();
}
// Get logged row from record.
pageOp.restoreLoggedRow(logged_index_row_template, in);
// RESOLVE (mikem) - currently restoreLoggedRow() may latch and unlatch
// a page in the container (see ST059).
// Now get the page where the record used to be.
ok_exit = false;
try
{
// "open" the btree, using recovery's already opened container
OpenBTree open_btree = new OpenBTree();
open_btree.init(
(TransactionManager) null, // current user xact - not needed
(TransactionManager) null, // current xact - not needed
pageOp.getContainer(), // recovery already opened container
rawtran,
false,
ContainerHandle.MODE_FORUPDATE,
// open_mode not used - container is
// already opened.
TransactionManager.MODE_NONE,
(BTreeLockingPolicy) null, // don't get locks during undo
btree,
(LogicalUndo) null, // no logical undo necessary, as
// this code only does read.
(DynamicCompiledOpenConglomInfo) null);
// System.out.println(
// "calling logical undo, recordhandle = " + rechandle);
// System.out.println("calling logical undo, record= " +
// logged_index_row_template);
// Get the page where the record was originally, before splits
// could have possibly moved it.
control_row = ControlRow.get(open_btree, rechandle.getPageNumber());
// init compare_result, if record doesn't exist do the search
compare_result = 1;
if (control_row.getPage().recordExists(rechandle, true))
{
if (SanityManager.DEBUG)
{
SanityManager.ASSERT(
control_row.getPage().fetchNumFields(rechandle) ==
logged_index_row_template.length);
}
// create template for the page index row from the conglomerate.
RecordHandle ret_rechandle =
control_row.getPage().fetchFromSlot(
(RecordHandle) null,
control_row.getPage().getSlotNumber(rechandle),
template,
(FetchDescriptor) null,
true);
// compare the 2 rows, and if they are the same then the raw
// store has the right page and record and there is no work to
// be done (this is usual case).
compare_result = ControlRow.compareIndexRowToKey(
template, logged_index_row_template,
logged_index_row_template.length, 1,
open_btree.getColumnSortOrderInfo());
}
if (compare_result == 0)
{
ret_page = control_row.getPage();
}
else
{
// if the 2 don't compare equal, search the btree from the root
// for the logged row, find the leaf, reset the row for the raw
// store, and return the new page latched.
// Create the objects needed for the insert.
SearchParameters sp = new SearchParameters(
logged_index_row_template, ScanController.GE,
template, open_btree, false);
control_row.release();
control_row = null;
control_row =
ControlRow.get(open_btree, BTree.ROOTPAGEID).search(sp);
if (!sp.resultExact)
{
if (SanityManager.DEBUG)
{
SanityManager.THROWASSERT(
"B2IUndo - could not find key being searched for:" +
";key = " +
RowUtil.toString(logged_index_row_template) +
";sp = " + sp +
"control_row = " + control_row +
"control_row.debugPage() = " +
control_row.debugPage(open_btree) +
"control_row.getPage() = " +
control_row.getPage());
}
throw StandardException.newException(
SQLState.BTREE_ROW_NOT_FOUND_DURING_UNDO);
}
else
{
RecordHandle rh =
control_row.getPage().fetchFromSlot(
(RecordHandle) null,
sp.resultSlot, new DataValueDescriptor[0],
(FetchDescriptor) null,
true);
pageOp.resetRecordHandle(rh);
ret_page = control_row.getPage();
}
}
ok_exit = true;
}
finally
{
//System.out.println("B2iUndo returning with rec handle: " +
// pageOp.getRecordHandle());
if ((!ok_exit) && (control_row != null))
control_row.release();
}
return(ret_page);
}