use of org.apache.derby.iapi.store.access.ScanController 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.store.access.ScanController in project derby by apache.
the class ReferencedKeyRIChecker method doCheck.
/**
* Check that the row either has a null column(s), or
* has no corresponding foreign keys.
* <p>
* If a foreign key is found, an exception is thrown.
* If not, the scan is closed.
*
* @param a the activation
* @param row the row to check
* @param restrictCheckOnly
* {@code true} if the check is relevant only for RESTRICTED
* referential action.
* @param deferredRowReq
* For referenced keys: The required number of duplicates that
* need to be present. Only used if {@code postCheck==false}.
*
* @exception StandardException on unexpected error, or
* on a primary/unique key violation
*/
@Override
void doCheck(Activation a, ExecRow row, boolean restrictCheckOnly, int deferredRowReq) throws StandardException {
/*
** If any of the columns are null, then the
** check always succeeds.
*/
if (isAnyFieldNull(row)) {
return;
}
if (fkInfo.refConstraintIsDeferrable) {
// violated. DERBY-6559
if (lcc.isEffectivelyDeferred(lcc.getCurrentSQLSessionContext(a), fkInfo.refConstraintID)) {
if (restrictCheckOnly) {
rememberKey(row);
return;
} else {
// rows code path, so go see if we have enough rows
if (isDuplicated(row, deferredRowReq)) {
return;
}
}
}
}
/*
** Otherwise, should be no rows found.
** Check each conglomerate.
*/
ScanController scan;
for (int i = 0; i < fkInfo.fkConglomNumbers.length; i++) {
if (restrictCheckOnly) {
if (fkInfo.raRules[i] != StatementType.RA_RESTRICT)
continue;
}
scan = getScanController(fkInfo.fkConglomNumbers[i], fkScocis[i], fkDcocis[i], row);
if (scan.next()) {
close();
final UUID fkId = fkInfo.fkIds[i];
// NO ACTION. CASCADE and SET NULL handled elsewhere.
if (fkInfo.deferrable[i] && fkInfo.raRules[i] != StatementType.RA_RESTRICT && lcc.isEffectivelyDeferred(lcc.getCurrentSQLSessionContext(a), fkId)) {
deferredRowsHashTable = DeferredConstraintsMemory.rememberFKViolation(lcc, deferredRowsHashTable, fkInfo.fkIds[i], indexQualifierRow.getRowArray(), fkInfo.schemaName, fkInfo.tableName);
} else {
StandardException se = StandardException.newException(SQLState.LANG_FK_VIOLATION, fkInfo.fkConstraintNames[i], fkInfo.tableName, StatementUtil.typeName(fkInfo.stmtType), RowUtil.toString(row, fkInfo.colArray));
throw se;
}
}
/*
** Move off of the current row to release any locks.
*/
scan.next();
}
}
use of org.apache.derby.iapi.store.access.ScanController in project derby by apache.
the class DataDictionaryImpl method isSchemaReferenced.
/**
* Is the schema id referenced by the system table in question?
* Currently assumes that the schema id is in an index.
* NOTE: could be generalized a bit, and possibly used
* elsewhere...
*
* @param tc transaction controller
* @param ti table info for the system table
* @param indexId index id
* @param indexCol 1 based index column
* @param schemaIdOrderable the schemaid in a char orderable
*
* @return true if there is a reference to this schema
*
* @exception StandardException on error
*/
protected boolean isSchemaReferenced(TransactionController tc, TabInfoImpl ti, int indexId, int indexCol, DataValueDescriptor schemaIdOrderable) throws StandardException {
ConglomerateController heapCC = null;
ScanController scanController = null;
boolean foundRow;
FormatableBitSet colToCheck = new FormatableBitSet(indexCol);
if (SanityManager.DEBUG) {
SanityManager.ASSERT(indexId >= 0, "code needs to be enhanced" + " to support a table scan to find the index id");
}
colToCheck.set(indexCol - 1);
ScanQualifier[][] qualifier = exFactory.getScanQualifier(1);
qualifier[0][0].setQualifier(indexCol - 1, schemaIdOrderable, Orderable.ORDER_OP_EQUALS, false, false, false);
try {
heapCC = tc.openConglomerate(ti.getHeapConglomerate(), false, 0, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ);
scanController = tc.openScan(// conglomerate to open
ti.getIndexConglomerate(indexId), // don't hold open across commit
false, // for read
0, // row locking
TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ, // don't get any rows
colToCheck, // start position - first row
null, // startSearchOperation
ScanController.GE, // scanQualifier,
qualifier, // stop position - through last row
null, // stopSearchOperation
ScanController.GT);
foundRow = (scanController.next());
} finally {
if (scanController != null) {
scanController.close();
}
if (heapCC != null) {
heapCC.close();
}
}
return foundRow;
}
use of org.apache.derby.iapi.store.access.ScanController in project derby by apache.
the class DataDictionaryImpl method getRoleGrantGraph.
/**
* Return an in-memory representation of the role grant graph (sans
* grant of roles to users, only role-role relation.
*
* @param tc Transaction Controller
* @param inverse make graph on inverse grant relation
* @return hash map representing role grant graph.
* <ul><li>Key: rolename,</li>
* <li>Value: List<RoleGrantDescriptor> representing a
* grant of that rolename to another role (not user).
* </li>
* </ul>
*
* FIXME: Need to cache graph and invalidate when role graph is modified.
* Currently, we always read from SYSROLES.
*/
HashMap<String, List<RoleGrantDescriptor>> getRoleGrantGraph(TransactionController tc, boolean inverse) throws StandardException {
HashMap<String, List<RoleGrantDescriptor>> hm = new HashMap<String, List<RoleGrantDescriptor>>();
TabInfoImpl ti = getNonCoreTI(SYSROLES_CATALOG_NUM);
SYSROLESRowFactory rf = (SYSROLESRowFactory) ti.getCatalogRowFactory();
DataValueDescriptor isDefOrderable = new SQLVarchar("N");
ScanQualifier[][] scanQualifier = exFactory.getScanQualifier(1);
scanQualifier[0][0].setQualifier(SYSROLESRowFactory.SYSROLES_ISDEF - 1, /* to zero-based */
isDefOrderable, 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);
ExecRow outRow = rf.makeEmptyRow();
RoleGrantDescriptor grantDescr;
while (sc.fetchNext(outRow.getRowArray())) {
grantDescr = (RoleGrantDescriptor) rf.buildDescriptor(outRow, (TupleDescriptor) null, this);
// Next call is potentially inefficient. We could read in
// definitions first in a separate hash table limiting
// this to a 2-pass scan.
RoleGrantDescriptor granteeDef = getRoleDefinitionDescriptor(grantDescr.getGrantee());
if (granteeDef == null) {
// not a role, must be user authid, skip
continue;
}
String hashKey;
if (inverse) {
hashKey = granteeDef.getRoleName();
} else {
hashKey = grantDescr.getRoleName();
}
List<RoleGrantDescriptor> arcs = hm.get(hashKey);
if (arcs == null) {
arcs = new LinkedList<RoleGrantDescriptor>();
}
arcs.add(grantDescr);
hm.put(hashKey, arcs);
}
sc.close();
return hm;
}
use of org.apache.derby.iapi.store.access.ScanController in project derby by apache.
the class DataDictionaryImpl method hashAllTableDescriptorsByTableId.
/**
* Get all of the TableDescriptors in the database and hash them
* by TableId This is useful as a performance optimization for the
* locking VTIs. NOTE: This method will scan SYS.SYSTABLES and
* SYS.SYSSCHEMAS at READ UNCOMMITTED.
*
* @param tc TransactionController for the transaction
*
* @return A Hashtable with all of the Table descriptors in the database
* hashed by TableId
*
* @exception StandardException Thrown on failure
*/
@SuppressWarnings("UseOfObsoleteCollectionType")
public Hashtable<UUID, TableDescriptor> hashAllTableDescriptorsByTableId(TransactionController tc) throws StandardException {
Hashtable<UUID, TableDescriptor> ht = new Hashtable<UUID, TableDescriptor>();
ScanController scanController;
ExecRow outRow;
TabInfoImpl ti = coreInfo[SYSTABLES_CORE_NUM];
SYSTABLESRowFactory rf = (SYSTABLESRowFactory) ti.getCatalogRowFactory();
outRow = rf.makeEmptyRow();
scanController = tc.openScan(// sys.systable
ti.getHeapConglomerate(), // don't hold open across commit
false, // for read
0, // scans whole table.
TransactionController.MODE_RECORD, TransactionController.ISOLATION_READ_UNCOMMITTED, // all fields as objects
(FormatableBitSet) null, // start position - first row
(DataValueDescriptor[]) null, // startSearchOperation
ScanController.GE, // scanQualifier,
(ScanQualifier[][]) null, // stop position-through last row
(DataValueDescriptor[]) null, // stopSearchOperation
ScanController.GT);
// fetch() may find the row deleted or purged from the table.
while (scanController.fetchNext(outRow.getRowArray())) {
TableDescriptor td = (TableDescriptor) rf.buildDescriptor(outRow, (TupleDescriptor) null, this, TransactionController.ISOLATION_READ_UNCOMMITTED);
ht.put(td.getUUID(), td);
}
scanController.close();
return ht;
}
Aggregations