use of org.apache.derby.iapi.types.RowLocation in project derby by apache.
the class TemporaryRowHolderImpl method isRowAlreadyExist.
/**
* Maintain an unique index based on the input row's row location in the
* base table, this index make sures that we don't insert duplicate rows
* into the temporary heap.
* @param inputRow the row we are inserting to temporary row holder
* @exception StandardException on error
*/
private boolean isRowAlreadyExist(ExecRow inputRow) throws StandardException {
DataValueDescriptor rlColumn;
RowLocation baseRowLocation;
rlColumn = inputRow.getColumn(inputRow.nColumns());
if (CID != 0 && rlColumn instanceof SQLRef) {
baseRowLocation = (RowLocation) (rlColumn).getObject();
if (!uniqueIndexCreated) {
TransactionController tc = activation.getTransactionController();
int numKeys = 2;
uniqueIndexRow = new DataValueDescriptor[numKeys];
uniqueIndexRow[0] = baseRowLocation;
uniqueIndexRow[1] = baseRowLocation;
Properties props = makeIndexProperties(uniqueIndexRow, CID);
uniqueIndexConglomId = tc.createConglomerate("BTREE", uniqueIndexRow, null, // no collation needed for index on row locations.
null, props, (TransactionController.IS_TEMPORARY | TransactionController.IS_KEPT));
uniqueIndex_cc = tc.openConglomerate(uniqueIndexConglomId, false, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_TABLE, TransactionController.ISOLATION_SERIALIZABLE);
uniqueIndexCreated = true;
}
uniqueIndexRow[0] = baseRowLocation;
uniqueIndexRow[1] = baseRowLocation;
// Insert the row into the secondary index.
int status;
if ((status = uniqueIndex_cc.insert(uniqueIndexRow)) != 0) {
if (status == ConglomerateController.ROWISDUPLICATE) {
// okay; we don't insert duplicates
return true;
} else {
if (SanityManager.DEBUG) {
if (status != 0) {
SanityManager.THROWASSERT("got funky status (" + status + ") back from " + "Unique Index insert()");
}
}
}
}
}
return false;
}
use of org.apache.derby.iapi.types.RowLocation in project derby by apache.
the class TemporaryRowHolderResultSet method getNextAppendedRow.
// get the next row inserted into the temporary holder
private ExecRow getNextAppendedRow() throws StandardException {
if (indexsc == null)
return null;
if (!indexsc.fetchNext(indexRow)) {
return null;
}
RowLocation baseRowLocation = (RowLocation) indexRow[1];
boolean base_row_exists = heapCC.fetch(baseRowLocation, currentRow.getRowArray(), (FormatableBitSet) null);
if (SanityManager.DEBUG) {
SanityManager.ASSERT(base_row_exists, "base row disappeared.");
}
numRowsOut++;
return currentRow;
}
use of org.apache.derby.iapi.types.RowLocation in project derby by apache.
the class ScrollInsensitiveResultSet method getRowFromHashTable.
/**
* Get the row at the specified position
* from the hash table.
*
* @param position The specified position.
*
* @return The row at that position.
*
* @exception StandardException thrown on failure
*/
private ExecRow getRowFromHashTable(int position) throws StandardException {
// Get the row from the hash table
positionInHashTable.setValue(position);
DataValueDescriptor[] hashRowArray = getCurrentRowFromHashtable();
if (SanityManager.DEBUG) {
SanityManager.ASSERT(hashRowArray != null, "hashRowArray expected to be non-null");
}
// Copy out the Object[] without the position.
DataValueDescriptor[] resultRowArray = new DataValueDescriptor[hashRowArray.length - extraColumns];
System.arraycopy(hashRowArray, extraColumns, resultRowArray, 0, resultRowArray.length);
resultRow.setRowArray(resultRowArray);
// Reset the current position to the user position
currentPosition = position;
numFromHashTable++;
if (resultRow != null) {
beforeFirst = false;
afterLast = false;
}
if (isForUpdate()) {
RowLocation rowLoc = (RowLocation) hashRowArray[POS_ROWLOCATION];
// Keep source and target with the same currentRow
((NoPutResultSet) target).setCurrentRow(resultRow);
((NoPutResultSet) target).positionScanAtRowLocation(rowLoc);
needsRepositioning = true;
}
setCurrentRow(resultRow);
return resultRow;
}
use of org.apache.derby.iapi.types.RowLocation in project derby by apache.
the class DataDictionaryImpl method getRowLocationTemplate.
public RowLocation getRowLocationTemplate(LanguageConnectionContext lcc, TableDescriptor td) throws StandardException {
RowLocation rl;
ConglomerateController heapCC = null;
TransactionController tc = lcc.getTransactionCompile();
long tableId = td.getHeapConglomerateId();
heapCC = tc.openConglomerate(tableId, false, 0, tc.MODE_RECORD, tc.ISOLATION_READ_COMMITTED);
try {
rl = heapCC.newRowLocationTemplate();
} finally {
heapCC.close();
}
return rl;
}
use of org.apache.derby.iapi.types.RowLocation in project derby by apache.
the class DataDictionaryImpl method addRemovePermissionsDescriptor.
/**
* Add or remove a permission to/from the permission database.
*
* @param add if true then the permission is added, if false the permission is removed
* @param perm
* @param grantee
* @param tc
*
* @return True means revoke has removed a privilege from system
* table and hence the caller of this method should send invalidation
* actions to PermssionDescriptor's dependents.
*/
public boolean addRemovePermissionsDescriptor(boolean add, PermissionsDescriptor perm, String grantee, TransactionController tc) throws StandardException {
int catalogNumber = perm.getCatalogNumber();
// It is possible for grant statements to look like following
// grant execute on function f_abs to mamata2, mamata3;
// grant all privileges on t11 to mamata2, mamata3;
// This means that dd.addRemovePermissionsDescriptor will be called
// twice for TablePermsDescriptor and twice for RoutinePermsDescriptor,
// once for each grantee.
// First it's called for mamta2. When a row is inserted for mamta2
// into the correct system table for the permission descriptor, the
// permission descriptor's uuid gets populated with the uuid of
// the row that just got inserted into the system table for mamta2
// Now, when dd.addRemovePermissionsDescriptor gets called again for
// mamta3, the permission descriptor's uuid will still be set to
// the uuid that was used for mamta2. If we do not reset the
// uuid to null, we will think that there is a duplicate row getting
// inserted for the same uuid. In order to get around this, we should
// reset the UUID of passed PermissionDescriptor everytime this method
// is called. This way, there will be no leftover values from previous
// call of this method.
perm.setUUID(null);
perm.setGrantee(grantee);
TabInfoImpl ti = getNonCoreTI(catalogNumber);
PermissionsCatalogRowFactory rf = (PermissionsCatalogRowFactory) ti.getCatalogRowFactory();
int primaryIndexNumber = rf.getPrimaryKeyIndexNumber();
ConglomerateController heapCC = tc.openConglomerate(ti.getHeapConglomerate(), // do not keep open across commits
false, 0, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ);
RowLocation rl = null;
try {
rl = heapCC.newRowLocationTemplate();
} finally {
heapCC.close();
heapCC = null;
}
ExecIndexRow key = rf.buildIndexKeyRow(primaryIndexNumber, perm);
ExecRow existingRow = ti.getRow(tc, key, primaryIndexNumber);
if (existingRow == null) {
if (!add) {
// permission and hence uuid can't be non-null
return false;
} else {
// We didn't find an entry in system catalog and this is grant so
// so that means we have to enter a new row in system catalog for
// this grant.
ExecRow row = ti.getCatalogRowFactory().makeRow(perm, (TupleDescriptor) null);
int insertRetCode = ti.insertRow(row, tc);
if (SanityManager.DEBUG) {
SanityManager.ASSERT(insertRetCode == TabInfoImpl.ROWNOTDUPLICATE, "Race condition in inserting table privilege.");
}
}
} else {
// add/remove these permissions to/from the existing permissions
boolean[] colsChanged = new boolean[existingRow.nColumns()];
boolean[] indicesToUpdate = new boolean[rf.getNumIndexes()];
int changedColCount = 0;
if (add) {
changedColCount = rf.orPermissions(existingRow, perm, colsChanged);
} else {
changedColCount = rf.removePermissions(existingRow, perm, colsChanged);
}
if (changedColCount == 0) {
// just return
return false;
}
if (!add) {
// set the uuid of the passed permission descriptor to
// corresponding rows's uuid in permissions system table. The
// permission descriptor's uuid is required to have the
// dependency manager send the revoke privilege action to
// all the dependent objects on that permission descriptor.
rf.setUUIDOfThePassedDescriptor(existingRow, perm);
}
if (changedColCount < 0) {
// No permissions left in the current row
ti.deleteRow(tc, key, primaryIndexNumber);
} else if (changedColCount > 0) {
int[] colsToUpdate = new int[changedColCount];
changedColCount = 0;
for (int i = 0; i < colsChanged.length; i++) {
if (colsChanged[i])
colsToUpdate[changedColCount++] = i + 1;
}
if (SanityManager.DEBUG) {
SanityManager.ASSERT(changedColCount == colsToUpdate.length, "return value of " + rf.getClass().getName() + ".orPermissions does not match the number of booleans it set in colsChanged.");
}
ti.updateRow(key, existingRow, primaryIndexNumber, indicesToUpdate, colsToUpdate, tc);
}
}
// Remove cached permissions data. The cache may hold permissions data for this key even if
// the row in the permissions table is new. In that case the cache may have an entry indicating no
// permissions
removePermEntryInCache(perm);
// any invalidation actions to anyone and hence return false
if (add) {
return false;
} else {
return true;
}
}
Aggregations