use of org.apache.derby.iapi.sql.execute.RowChanger in project derby by apache.
the class TabInfoImpl method updateRow.
/**
* Updates a set of base rows in a catalog with the same key on an index
* and updates all the corresponding index rows.
*
* @param key key row
* @param newRows new version of the array of rows
* @param indexNumber index that key operates
* @param indicesToUpdate array of booleans, one for each index on the catalog.
* if a boolean is true, that means we must update the
* corresponding index because changes in the newRow
* affect it.
* @param colsToUpdate array of ints indicating which columns (1 based)
* to update. If null, do all.
* @param tc transaction controller
*
* @exception StandardException Thrown on failure
*/
void updateRow(ExecIndexRow key, ExecRow[] newRows, int indexNumber, boolean[] indicesToUpdate, int[] colsToUpdate, TransactionController tc) throws StandardException {
ConglomerateController heapCC;
ScanController drivingScan;
ExecIndexRow drivingIndexRow;
RowLocation baseRowLocation;
ExecRow baseRow = crf.makeEmptyRow();
if (SanityManager.DEBUG) {
SanityManager.ASSERT(indicesToUpdate.length == crf.getNumIndexes(), "Wrong number of indices.");
}
RowChanger rc = getRowChanger(tc, colsToUpdate, baseRow);
// Row level locking
rc.openForUpdate(indicesToUpdate, TransactionController.MODE_RECORD, true);
/* Open the heap conglomerate */
heapCC = tc.openConglomerate(getHeapConglomerate(), false, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ);
drivingScan = tc.openScan(// conglomerate to open
getIndexConglomerate(indexNumber), // don't hold open across commit
false, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ, // all fields as objects
(FormatableBitSet) null, // start position - first row
key.getRowArray(), // startSearchOperation
ScanController.GE, // scanQualifier
null, // stop position - through last row
key.getRowArray(), // stopSearchOperation
ScanController.GT);
// Get an index row based on the base row
drivingIndexRow = getIndexRowFromHeapRow(getIndexRowGenerator(indexNumber), heapCC.newRowLocationTemplate(), crf.makeEmptyRow());
int rowNum = 0;
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");
}
rc.updateRow(baseRow, (rowNum == newRows.length - 1) ? newRows[rowNum] : newRows[rowNum++], baseRowLocation);
}
rc.finish();
heapCC.close();
drivingScan.close();
rc.close();
}
use of org.apache.derby.iapi.sql.execute.RowChanger 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.sql.execute.RowChanger in project derby by apache.
the class TabInfoImpl method getRowChanger.
/**
* Gets a row changer for this catalog.
*
* @param tc transaction controller
* @param changedCols the columns to change (1 based), may be null
* @param baseRow used to detemine column types at creation time
* only. The row changer does ***Not*** keep a referance to
* this row or change it in any way.
*
* @return a row changer for this catalog.
* @exception StandardException Thrown on failure
*/
private RowChanger getRowChanger(TransactionController tc, int[] changedCols, ExecRow baseRow) throws StandardException {
RowChanger rc;
int indexCount = crf.getNumIndexes();
IndexRowGenerator[] irgs = new IndexRowGenerator[indexCount];
long[] cids = new long[indexCount];
if (SanityManager.DEBUG) {
if (changedCols != null) {
for (int i = changedCols.length - 1; i >= 0; i--) {
SanityManager.ASSERT(changedCols[i] != 0, "Column id is 0, but should be 1 based");
}
}
}
for (int ictr = 0; ictr < indexCount; ictr++) {
irgs[ictr] = getIndexRowGenerator(ictr);
cids[ictr] = getIndexConglomerate(ictr);
}
rc = crf.getExecutionFactory().getRowChanger(getHeapConglomerate(), (StaticCompiledOpenConglomInfo) null, (DynamicCompiledOpenConglomInfo) null, irgs, cids, (StaticCompiledOpenConglomInfo[]) null, (DynamicCompiledOpenConglomInfo[]) null, crf.getHeapColumnCount(), tc, changedCols, getStreamStorableHeapColIds(baseRow), (Activation) null);
return rc;
}
Aggregations