use of org.apache.derby.iapi.types.RowLocation in project derby by apache.
the class T_CreateConglomRet method t_016.
/**
* Test deadlocks during critical times of row level locking.
* <p>
* Use trace points to force errors in split at critical points:
* leaf_split_abort{1,2,3,4}
*
* @exception StandardException Standard exception policy.
* @exception T_Fail Throws T_Fail on any test failure.
*/
protected boolean t_016(TransactionController tc) throws StandardException, T_Fail {
ScanController scan = null;
// SanityManager.DEBUG_SET("LockTrace");
REPORT("Starting t_016");
T_CreateConglomRet create_ret = new T_CreateConglomRet();
// Create the btree so that it only allows 2 rows per page.
createCongloms(tc, 2, false, false, 2, create_ret);
// Open the base table
ConglomerateController base_cc = tc.openConglomerate(create_ret.base_conglomid, false, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_RECORD, TransactionController.ISOLATION_SERIALIZABLE);
// Open the secondary index
ConglomerateController index_cc = tc.openConglomerate(create_ret.index_conglomid, false, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_RECORD, TransactionController.ISOLATION_SERIALIZABLE);
if (!(index_cc instanceof B2IController)) {
throw T_Fail.testFailMsg("openConglomerate returned wrong type");
}
index_cc.checkConsistency();
// Create a row and insert into base table, remembering it's location.
DataValueDescriptor[] r1 = TemplateRow.newU8Row(2);
T_SecondaryIndexRow index_row1 = new T_SecondaryIndexRow();
RowLocation base_rowloc1 = base_cc.newRowLocationTemplate();
index_row1.init(r1, base_rowloc1, 3);
// Commit the create of the tables so that the following aborts don't
// undo that work.
tc.commit();
// Open the base table
base_cc = tc.openConglomerate(create_ret.base_conglomid, false, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_RECORD, TransactionController.ISOLATION_SERIALIZABLE);
// Open the secondary index
index_cc = tc.openConglomerate(create_ret.index_conglomid, false, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_RECORD, TransactionController.ISOLATION_SERIALIZABLE);
// now insert enough rows to cause failure
for (int i = 100; i > 0; i -= 2) {
((SQLLongint) r1[0]).setValue(2);
((SQLLongint) r1[1]).setValue(i);
// Insert the row into the base table;remember its location.
base_cc.insertAndFetchLocation(r1, base_rowloc1);
// Insert the row into the secondary index.
if (index_cc.insert(index_row1.getRow()) != 0) {
throw T_Fail.testFailMsg("insert failed");
}
}
tc.abort();
// Now try simulated deadlocks
// RESOLVE (Mikem) - test out aborts and errors during inserts.
String[] deadlock_debug_strings = { "B2iRowLocking3_1_lockScanRow2", "B2iRowLocking3_2_lockScanRow2", // "BTreeController_doIns2",
"BTreeScan_positionAtStartPosition2", // "BTreeScan_reposition2",
"BTreeScan_fetchNextGroup2" };
for (int errs = 0; errs < deadlock_debug_strings.length; errs++) {
try {
REPORT("Doing deadlock tests: " + deadlock_debug_strings[errs]);
// latch release path through the code.
if (SanityManager.DEBUG)
SanityManager.DEBUG_SET(deadlock_debug_strings[errs]);
// Just scan the rows and make sure you see them all, mostly just
// a test to make sure no errors are thrown by the latch release
// code paths.
scan = tc.openScan(create_ret.index_conglomid, false, 0, TransactionController.MODE_RECORD, TransactionController.ISOLATION_SERIALIZABLE, (FormatableBitSet) null, null, ScanController.NA, null, null, ScanController.NA);
int row_count = 0;
while (scan.next()) {
row_count++;
}
scan.close();
throw T_Fail.testFailMsg("expected deadlock");
} catch (StandardException e) {
if (!e.getMessageId().equals(SQLState.DEADLOCK))
throw e;
ContextService contextFactory = getContextService();
// Get the context manager.
ContextManager cm = contextFactory.getCurrentContextManager();
if (SanityManager.DEBUG)
SanityManager.ASSERT(cm != null);
cm.cleanupOnError(e, isdbActive());
}
}
tc.commit();
REPORT("Ending t_016");
return true;
}
use of org.apache.derby.iapi.types.RowLocation in project derby by apache.
the class ResultColumnList method buildEmptyIndexRow.
/**
* Build an empty index row for the given conglomerate.
*
* @return an empty row of the correct size and shape.
* @exception StandardException Thrown on error
*/
public ExecRow buildEmptyIndexRow(TableDescriptor td, ConglomerateDescriptor cd, StoreCostController scc, DataDictionary dd) throws StandardException {
ResultColumn rc;
if (SanityManager.DEBUG) {
if (!cd.isIndex()) {
SanityManager.THROWASSERT("ConglomerateDescriptor expected to be for index: " + cd);
}
}
int[] baseCols = cd.getIndexDescriptor().baseColumnPositions();
ExecRow row = getExecutionFactory().getValueRow(baseCols.length + 1);
for (int i = 0; i < baseCols.length; i++) {
ColumnDescriptor coldes = td.getColumnDescriptor(baseCols[i]);
DataTypeDescriptor dataType = coldes.getType();
// rc = getResultColumn(baseCols[i]);
// rc = (ResultColumn) at(baseCols[i] - 1);
// dataType = rc.getTypeServices();
DataValueDescriptor dataValue = dataType.getNull();
row.setColumn(i + 1, dataValue);
}
RowLocation rlTemplate = scc.newRowLocationTemplate();
row.setColumn(baseCols.length + 1, rlTemplate);
return row;
}
use of org.apache.derby.iapi.types.RowLocation in project derby by apache.
the class TabInfoImpl method getRowLocation.
/**
* Given an index row and index number return the RowLocation
* in the heap of the first matching row.
* Used by the autoincrement code to get the RowLocation in
* syscolumns given a <tablename, columname> pair.
*
* @see DataDictionaryImpl#computeRowLocation(TransactionController, TableDescriptor, String)
*
* @param tc Transaction Controller to use.
* @param key Index Row to search in the index.
* @param indexNumber Identifies the index to use.
*
* @exception StandardException thrown on failure.
*/
RowLocation getRowLocation(TransactionController tc, ExecIndexRow key, int indexNumber) throws StandardException {
ConglomerateController heapCC;
heapCC = tc.openConglomerate(getHeapConglomerate(), false, // for read only
0, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ);
try {
RowLocation[] rl = new RowLocation[1];
ExecRow notUsed = getRowInternal(tc, heapCC, key, indexNumber, rl);
return rl[0];
} finally {
heapCC.close();
}
}
use of org.apache.derby.iapi.types.RowLocation in project derby by apache.
the class TabInfoImpl method deleteRows.
/**
* @inheritDoc
*/
private int deleteRows(TransactionController tc, ExecIndexRow startKey, int startOp, Qualifier[][] qualifier, TupleFilter filter, ExecIndexRow stopKey, int stopOp, int indexNumber, boolean wait) throws StandardException {
ConglomerateController heapCC;
ScanController drivingScan;
ExecIndexRow drivingIndexRow;
RowLocation baseRowLocation;
RowChanger rc;
ExecRow baseRow = crf.makeEmptyRow();
int rowsDeleted = 0;
boolean passedFilter = true;
rc = getRowChanger(tc, (int[]) null, baseRow);
/*
** If we have a start and a stop key, then we are going to
** get row locks, otherwise, we are getting table locks.
** This may be excessive locking for the case where there
** is a start key and no stop key or vice versa.
*/
int lockMode = ((startKey != null) && (stopKey != null)) ? TransactionController.MODE_RECORD : TransactionController.MODE_TABLE;
/*
** Don't use level 3 if we have the same start/stop key.
*/
int isolation = ((startKey != null) && (stopKey != null) && (startKey == stopKey)) ? TransactionController.ISOLATION_REPEATABLE_READ : TransactionController.ISOLATION_SERIALIZABLE;
// Row level locking
rc.open(lockMode, wait);
DataValueDescriptor[] startKeyRow = startKey == null ? null : startKey.getRowArray();
DataValueDescriptor[] stopKeyRow = stopKey == null ? null : stopKey.getRowArray();
/* Open the heap conglomerate */
heapCC = tc.openConglomerate(getHeapConglomerate(), false, (TransactionController.OPENMODE_FORUPDATE | ((wait) ? 0 : TransactionController.OPENMODE_LOCK_NOWAIT)), lockMode, TransactionController.ISOLATION_REPEATABLE_READ);
drivingScan = tc.openScan(// conglomerate to open
getIndexConglomerate(indexNumber), // don't hold open across commit
false, (TransactionController.OPENMODE_FORUPDATE | ((wait) ? 0 : TransactionController.OPENMODE_LOCK_NOWAIT)), lockMode, isolation, // all fields as objects
(FormatableBitSet) null, // start position - first row
startKeyRow, // startSearchOperation
startOp, // scanQualifier
qualifier, // stop position - through last row
stopKeyRow, // stopSearchOperation
stopOp);
// Get an index row based on the base row
drivingIndexRow = getIndexRowFromHeapRow(getIndexRowGenerator(indexNumber), heapCC.newRowLocationTemplate(), crf.makeEmptyRow());
while (drivingScan.fetchNext(drivingIndexRow.getRowArray())) {
baseRowLocation = (RowLocation) drivingIndexRow.getColumn(drivingIndexRow.nColumns());
boolean base_row_exists = heapCC.fetch(baseRowLocation, baseRow.getRowArray(), (FormatableBitSet) null);
if (SanityManager.DEBUG) {
// it can not be possible for heap row to disappear while
// holding scan cursor on index at ISOLATION_REPEATABLE_READ.
SanityManager.ASSERT(base_row_exists, "base row not found");
}
// only delete rows which pass the base-row filter
if (filter != null) {
passedFilter = filter.execute(baseRow).equals(true);
}
if (passedFilter) {
rc.deleteRow(baseRow, baseRowLocation);
rowsDeleted++;
}
}
heapCC.close();
drivingScan.close();
rc.close();
return rowsDeleted;
}
use of org.apache.derby.iapi.types.RowLocation in project derby by apache.
the class IndexRowToBaseRowResultSet method getNextRowCore.
/**
* Return the requested values computed
* from the next row (if any) for which
* the restriction evaluates to true.
* <p>
* restriction and projection parameters
* are evaluated for each row.
*
* @exception StandardException thrown on failure.
* @exception StandardException ResultSetNotOpen thrown if not yet open.
*
* @return the next row in the result
*/
public ExecRow getNextRowCore() throws StandardException {
if (isXplainOnlyMode())
return null;
ExecRow sourceRow = null;
ExecRow retval = null;
boolean restrict = false;
DataValueDescriptor restrictBoolean;
long beginRT = 0;
beginTime = getCurrentTimeMillis();
if (!isOpen) {
throw StandardException.newException(SQLState.LANG_RESULT_SET_NOT_OPEN, "next");
}
/* Loop until we get a row from the base page that qualifies or
* there's no more rows from the index that qualify. (If the RID
* returned by the index does not qualify, then we have to go back
* to the index to see if there is another RID to consider.)
*/
do {
sourceRow = source.getNextRowCore();
if (sourceRow != null) {
if (SanityManager.DEBUG) {
SanityManager.ASSERT(sourceRow.getColumn(sourceRow.nColumns()) instanceof RowLocation, "Last column of source row is not a RowLocation");
}
baseRowLocation = (RowLocation) sourceRow.getColumn(sourceRow.nColumns());
// Fetch the columns coming from the heap
boolean row_exists = baseCC.fetch(baseRowLocation, rowArray, _includeRowLocation ? _heapColsWithoutRowLocation : accessedHeapCols);
if (row_exists) {
/* We only need to copy columns from the index row
* to our result row once as we will be reusing the
* wrappers in that case.
* NOTE: When the underlying ResultSet got an
* instantaneous lock (BulkTableScan or HashScan)
* then we will be getting all of the columns anew
* from the index (indexCols == null).
*/
if (!copiedFromSource) {
copiedFromSource = true;
// Copy the columns coming from the index into resultRow
for (int index = 0; index < indexCols.length; index++) {
if (indexCols[index] != -1) {
compactRow.setColumn(index + 1, sourceRow.getColumn(indexCols[index] + 1));
}
}
}
setCurrentRow(compactRow);
restrictBoolean = (DataValueDescriptor) ((restriction == null) ? null : restriction.invoke(activation));
restrictionTime += getElapsedMillis(beginRT);
// if the result is null, we make it false --
// so the row won't be returned.
restrict = (restrictBoolean == null) || ((!restrictBoolean.isNull()) && restrictBoolean.getBoolean());
}
if (!restrict || !row_exists) {
rowsFiltered++;
clearCurrentRow();
baseRowLocation = null;
} else {
currentRow = compactRow;
}
if (_includeRowLocation) {
currentRow.setColumn(currentRow.nColumns(), baseRowLocation);
}
/* Update the run time statistics */
rowsSeen++;
retval = currentRow;
} else {
clearCurrentRow();
baseRowLocation = null;
retval = null;
}
} while ((sourceRow != null) && (!restrict));
nextTime += getElapsedMillis(beginTime);
return retval;
}
Aggregations