use of org.apache.derby.iapi.store.access.ConglomerateController in project derby by apache.
the class DataDictionaryImpl method existsSchemaOwnedBy.
/**
* Return true of there exists a schema whose authorizationId equals
* authid, i.e. SYS.SYSSCHEMAS contains a row whose column
* (AUTHORIZATIONID) equals authid.
*
* @param authid authorizationId
* @param tc TransactionController
* @return true iff there is a matching schema
* @exception StandardException
*/
public boolean existsSchemaOwnedBy(String authid, TransactionController tc) throws StandardException {
TabInfoImpl ti = coreInfo[SYSSCHEMAS_CORE_NUM];
SYSSCHEMASRowFactory rf = (SYSSCHEMASRowFactory) ti.getCatalogRowFactory();
ConglomerateController heapCC = tc.openConglomerate(ti.getHeapConglomerate(), false, 0, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ);
DataValueDescriptor authIdOrderable = new SQLVarchar(authid);
ScanQualifier[][] scanQualifier = exFactory.getScanQualifier(1);
scanQualifier[0][0].setQualifier(SYSSCHEMASRowFactory.SYSSCHEMAS_SCHEMAAID - 1, /* to zero-based */
authIdOrderable, Orderable.ORDER_OP_EQUALS, false, false, false);
ScanController sc = tc.openScan(ti.getHeapConglomerate(), // don't hold open across commit
false, // for update
0, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ, // all fields as objects
(FormatableBitSet) null, // start position -
(DataValueDescriptor[]) null, // startSearchOperation - none
0, //
scanQualifier, // stop position -through last row
(DataValueDescriptor[]) null, // stopSearchOperation - none
0);
boolean result = false;
try {
ExecRow outRow = rf.makeEmptyRow();
if (sc.fetchNext(outRow.getRowArray())) {
result = true;
}
} finally {
if (sc != null) {
sc.close();
}
if (heapCC != null) {
heapCC.close();
}
}
return result;
}
use of org.apache.derby.iapi.store.access.ConglomerateController in project derby by apache.
the class DataDictionaryImpl method getDescriptorViaIndexMinion.
private <T extends TupleDescriptor> T getDescriptorViaIndexMinion(int indexId, ExecIndexRow keyRow, ScanQualifier[][] scanQualifiers, TabInfoImpl ti, TupleDescriptor parentTupleDescriptor, List<? super T> list, Class<T> returnType, boolean forUpdate, int isolationLevel, TransactionController tc) throws StandardException {
CatalogRowFactory rf = ti.getCatalogRowFactory();
ConglomerateController heapCC;
ExecIndexRow indexRow1;
ExecRow outRow;
RowLocation baseRowLocation;
ScanController scanController;
T td = null;
if (SanityManager.DEBUG) {
SanityManager.ASSERT(isolationLevel == TransactionController.ISOLATION_REPEATABLE_READ || isolationLevel == TransactionController.ISOLATION_READ_UNCOMMITTED);
}
outRow = rf.makeEmptyRow();
heapCC = tc.openConglomerate(ti.getHeapConglomerate(), false, 0, TransactionController.MODE_RECORD, isolationLevel);
/* Scan the index and go to the data pages for qualifying rows to
* build the column descriptor.
*/
scanController = tc.openScan(// conglomerate to open
ti.getIndexConglomerate(indexId), // don't hold open across commit
false, (forUpdate) ? TransactionController.OPENMODE_FORUPDATE : 0, TransactionController.MODE_RECORD, isolationLevel, // all fields as objects
(FormatableBitSet) null, // start position - first row
keyRow.getRowArray(), // startSearchOperation
ScanController.GE, // scanQualifier,
scanQualifiers, // stop position - through last row
keyRow.getRowArray(), // stopSearchOperation
ScanController.GT);
while (true) {
// create an index row template
indexRow1 = getIndexRowFromHeapRow(ti.getIndexRowGenerator(indexId), heapCC.newRowLocationTemplate(), outRow);
// from the table.
if (!scanController.fetchNext(indexRow1.getRowArray())) {
break;
}
baseRowLocation = (RowLocation) indexRow1.getColumn(indexRow1.nColumns());
// RESOLVE paulat - remove the try catch block when track 3677 is fixed
// just leave the contents of the try block
// adding to get more info on track 3677
boolean base_row_exists = false;
try {
base_row_exists = heapCC.fetch(baseRowLocation, outRow.getRowArray(), (FormatableBitSet) null);
} catch (RuntimeException re) {
if (SanityManager.DEBUG) {
if (re instanceof AssertFailure) {
StringBuffer strbuf = new StringBuffer("Error retrieving base row in table " + ti.getTableName());
strbuf.append(": An ASSERT was thrown when trying to locate a row matching index row " + indexRow1 + " from index " + ti.getIndexName(indexId) + ", conglom number " + ti.getIndexConglomerate(indexId));
debugGenerateInfo(strbuf, tc, heapCC, ti, indexId);
}
}
throw re;
} catch (StandardException se) {
if (SanityManager.DEBUG) {
// do not want to catch lock timeout errors here
if (se.getSQLState().equals("XSRS9")) {
StringBuffer strbuf = new StringBuffer("Error retrieving base row in table " + ti.getTableName());
strbuf.append(": A StandardException was thrown when trying to locate a row matching index row " + indexRow1 + " from index " + ti.getIndexName(indexId) + ", conglom number " + ti.getIndexConglomerate(indexId));
debugGenerateInfo(strbuf, tc, heapCC, ti, indexId);
}
}
throw se;
}
if (SanityManager.DEBUG) {
// holding scan cursor on index at ISOLATION_REPEATABLE_READ.
if (!base_row_exists && (isolationLevel == TransactionController.ISOLATION_REPEATABLE_READ)) {
StringBuffer strbuf = new StringBuffer("Error retrieving base row in table " + ti.getTableName());
strbuf.append(": could not locate a row matching index row " + indexRow1 + " from index " + ti.getIndexName(indexId) + ", conglom number " + ti.getIndexConglomerate(indexId));
debugGenerateInfo(strbuf, tc, heapCC, ti, indexId);
// RESOLVE: for now, we are going to kill the VM
// to help debug this problem.
System.exit(1);
// RESOLVE: not currently reached
// SanityManager.THROWASSERT(strbuf.toString());
}
}
if (!base_row_exists && (isolationLevel == TransactionController.ISOLATION_READ_UNCOMMITTED)) {
// If isolationLevel == ISOLATION_READ_UNCOMMITTED we may
// possibly see that the base row does not exist even if the
// index row did. This mode is currently only used by
// TableNameInfo's call to hashAllTableDescriptorsByTableId,
// cf. DERBY-3678, and by getStatisticsDescriptors,
// cf. DERBY-4881.
//
// For the former call, a table's schema descriptor is attempted
// read, and if the base row for the schema has gone between
// reading the index and the base table, the table that needs
// this information has gone, too. So, the table should not
// be needed for printing lock timeout or deadlock
// information, so we can safely just return an empty (schema)
// descriptor. Furthermore, neither Timeout or DeadLock
// diagnostics access the schema of a table descriptor, so it
// seems safe to just return an empty schema descriptor for
// the table.
//
// There is a theoretical chance another row may have taken
// the first one's place, but only if a compress of the base
// table managed to run between the time we read the index and
// the base row, which seems unlikely so we ignore that.
//
// Even the index row may be gone in the above use case, of
// course, and that case also returns an empty descriptor
// since no match is found.
td = null;
} else {
// normal case
td = returnType.cast(rf.buildDescriptor(outRow, parentTupleDescriptor, this));
}
/* If list is null, then caller only wants a single descriptor - we're done
* else just add the current descriptor to the list.
*/
if (list == null) {
break;
} else if (td != null) {
list.add(td);
}
}
scanController.close();
heapCC.close();
return td;
}
use of org.apache.derby.iapi.store.access.ConglomerateController in project derby by apache.
the class DataDictionaryImpl method getSetAutoincrementValue.
/**
* @see DataDictionary#getSetAutoincrementValue
*/
public NumberDataValue getSetAutoincrementValue(RowLocation rl, TransactionController tc, boolean doUpdate, NumberDataValue newValue, boolean wait) throws StandardException {
int columnNum = SYSCOLUMNSRowFactory.SYSCOLUMNS_AUTOINCREMENTVALUE;
TabInfoImpl ti = coreInfo[SYSCOLUMNS_CORE_NUM];
ConglomerateController heapCC = null;
SYSCOLUMNSRowFactory rf = (SYSCOLUMNSRowFactory) ti.getCatalogRowFactory();
ExecRow row = rf.makeEmptyRow();
FormatableBitSet columnToRead = new FormatableBitSet(SYSCOLUMNSRowFactory.SYSCOLUMNS_COLUMN_COUNT);
// FormatableBitSet is 0 based.
// current value.
columnToRead.set(columnNum - 1);
// start value.
columnToRead.set(columnNum);
// increment value.
columnToRead.set(columnNum + 1);
try {
/* if wait is true then we need to do a wait while trying to
open/fetch from the conglomerate. note we use wait both to
open as well as fetch from the conglomerate.
*/
heapCC = tc.openConglomerate(ti.getHeapConglomerate(), false, (TransactionController.OPENMODE_FORUPDATE | ((wait) ? 0 : TransactionController.OPENMODE_LOCK_NOWAIT)), TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ);
// fetch the current value
boolean baseRowExists = heapCC.fetch(rl, row.getRowArray(), columnToRead, wait);
if (SanityManager.DEBUG) {
// We're not prepared for a non-existing base row.
SanityManager.ASSERT(baseRowExists, "base row not found");
}
// while the Row interface is 1 based.
NumberDataValue currentAI = (NumberDataValue) row.getColumn(columnNum);
long currentAIValue = currentAI.getLong();
if (doUpdate) {
// increment the value
NumberDataValue increment = (NumberDataValue) row.getColumn(columnNum + 2);
currentAI = currentAI.plus(currentAI, increment, currentAI);
row.setColumn(columnNum, currentAI);
// store the new value in SYSCOLUMNS
FormatableBitSet columnToUpdate = new FormatableBitSet(SYSCOLUMNSRowFactory.SYSCOLUMNS_COLUMN_COUNT);
// current value.
columnToUpdate.set(columnNum - 1);
heapCC.replace(rl, row.getRowArray(), columnToUpdate);
}
// incrementing it.
if (newValue != null) {
// user has passed in an object; set the current value in there and
// return it.
newValue.setValue(currentAIValue);
return newValue;
} else {
// reuse the object read from row.
currentAI.setValue(currentAIValue);
return currentAI;
}
} finally {
if (heapCC != null)
heapCC.close();
}
}
use of org.apache.derby.iapi.store.access.ConglomerateController in project derby by apache.
the class DataDictionaryImpl method getConstraintDescriptorViaIndex.
/**
* Return a (single or list of) ConstraintDescriptor(s) from
* SYSCONSTRAINTS where the access is from the index to the heap.
*
* @param indexId The id of the index (0 to # of indexes on table) to use
* @param keyRow The supplied ExecIndexRow for search
* @param ti The TabInfoImpl to use
* @param td The TableDescriptor, if supplied.
* @param dList The list to build, if supplied. If null, then caller expects
* a single descriptor
* @param forUpdate Whether or not to open scan for update
*
* @return The last matching descriptor
*
* @exception StandardException Thrown on error
*/
protected ConstraintDescriptor getConstraintDescriptorViaIndex(int indexId, ExecIndexRow keyRow, TabInfoImpl ti, TableDescriptor td, ConstraintDescriptorList dList, boolean forUpdate) throws StandardException {
SYSCONSTRAINTSRowFactory rf = (SYSCONSTRAINTSRowFactory) ti.getCatalogRowFactory();
ConglomerateController heapCC;
ConstraintDescriptor cd = null;
ExecIndexRow indexRow1;
ExecRow outRow;
RowLocation baseRowLocation;
ScanController scanController;
TransactionController tc;
// Get the current transaction controller
tc = getTransactionCompile();
outRow = rf.makeEmptyRow();
heapCC = tc.openConglomerate(ti.getHeapConglomerate(), false, 0, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ);
/* Scan the index and go to the data pages for qualifying rows to
* build the column descriptor.
*/
scanController = tc.openScan(// conglomerate to open
ti.getIndexConglomerate(indexId), // don't hold open across commit
false, (forUpdate) ? TransactionController.OPENMODE_FORUPDATE : 0, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ, // all fields as objects
(FormatableBitSet) null, // start position - exact key match.
keyRow.getRowArray(), // startSearchOperation
ScanController.GE, // scanQualifier,
null, // stop position - exact key match.
keyRow.getRowArray(), // stopSearchOperation
ScanController.GT);
while (scanController.next()) {
SubConstraintDescriptor subCD = null;
// create an index row template
indexRow1 = getIndexRowFromHeapRow(ti.getIndexRowGenerator(indexId), heapCC.newRowLocationTemplate(), outRow);
scanController.fetch(indexRow1.getRowArray());
baseRowLocation = (RowLocation) indexRow1.getColumn(indexRow1.nColumns());
boolean base_row_exists = heapCC.fetch(baseRowLocation, outRow.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 doesn't exist");
}
switch(rf.getConstraintType(outRow)) {
case DataDictionary.PRIMARYKEY_CONSTRAINT:
case DataDictionary.FOREIGNKEY_CONSTRAINT:
case DataDictionary.UNIQUE_CONSTRAINT:
subCD = getSubKeyConstraint(rf.getConstraintId(outRow), rf.getConstraintType(outRow));
break;
case DataDictionary.CHECK_CONSTRAINT:
subCD = getSubCheckConstraint(rf.getConstraintId(outRow));
break;
default:
if (SanityManager.DEBUG) {
SanityManager.THROWASSERT("unexpected value " + "from rf.getConstraintType(outRow)" + rf.getConstraintType(outRow));
}
}
if (SanityManager.DEBUG) {
SanityManager.ASSERT(subCD != null, "subCD is expected to be non-null");
}
/* Cache the TD in the SCD so that
* the row factory doesn't need to go
* out to disk to get it.
*/
subCD.setTableDescriptor(td);
cd = (ConstraintDescriptor) rf.buildDescriptor(outRow, subCD, this);
/* If dList is null, then caller only wants a single descriptor - we're done
* else just add the current descriptor to the list.
*/
if (dList == null) {
break;
} else {
dList.add(cd);
}
}
scanController.close();
heapCC.close();
return cd;
}
use of org.apache.derby.iapi.store.access.ConglomerateController 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();
}
Aggregations