use of org.apache.derby.iapi.store.access.TransactionController in project derby by apache.
the class DDLConstantAction method executeCAPreferSubTrans.
private static void executeCAPreferSubTrans(CreateSchemaConstantAction csca, TransactionController tc, Activation activation) throws StandardException {
TransactionController useTc;
TransactionController nestedTc = null;
try {
nestedTc = tc.startNestedUserTransaction(false, true);
useTc = nestedTc;
} catch (StandardException e) {
if (SanityManager.DEBUG) {
SanityManager.THROWASSERT("Unexpected: not able to start nested transaction " + "to auto-create schema", e);
}
useTc = tc;
}
// once in the outer transaction.
while (true) {
try {
csca.executeConstantAction(activation, useTc);
} catch (StandardException se) {
if (se.isLockTimeout()) {
if (!se.getMessageId().equals(SQLState.LOCK_TIMEOUT_LOG)) {
if (useTc == nestedTc) {
// clean up after use of nested transaction,
// then try again in outer transaction
useTc = tc;
nestedTc.destroy();
continue;
}
}
} else if (se.getMessageId().equals(SQLState.LANG_OBJECT_ALREADY_EXISTS)) {
// probably created it after we checked for it
break;
}
// transaction; we had better pass that on
if (useTc == nestedTc) {
nestedTc.destroy();
}
throw se;
}
break;
}
// Clean up if we did this in a nested transaction.
if (useTc == nestedTc) {
nestedTc.commit();
nestedTc.destroy();
}
}
use of org.apache.derby.iapi.store.access.TransactionController in project derby by apache.
the class DDLConstantAction method adjustUDTDependencies.
/**
* Adjust dependencies of a table on ANSI UDTs. We only add one dependency
* between a table and a UDT. If the table already depends on the UDT, we don't add
* a redundant dependency.
*/
protected void adjustUDTDependencies(LanguageConnectionContext lcc, DataDictionary dd, TableDescriptor td, ColumnInfo[] columnInfos, boolean dropWholeTable) throws StandardException {
if ((!dropWholeTable) && (columnInfos == null)) {
return;
}
TransactionController tc = lcc.getTransactionExecute();
int changedColumnCount = columnInfos == null ? 0 : columnInfos.length;
HashMap<String, AliasDescriptor> addUdtMap = new HashMap<String, AliasDescriptor>();
HashMap<String, AliasDescriptor> dropUdtMap = new HashMap<String, AliasDescriptor>();
HashSet<String> addColumnNames = new HashSet<String>();
HashSet<String> dropColumnNames = new HashSet<String>();
// and the old ones which are candidates for removal
for (int i = 0; i < changedColumnCount; i++) {
ColumnInfo ci = columnInfos[i];
// skip this column if it is not a UDT
AliasDescriptor ad = dd.getAliasDescriptorForUDT(tc, columnInfos[i].dataType);
if (ad == null) {
continue;
}
String key = ad.getObjectID().toString();
if (ci.action == ColumnInfo.CREATE) {
addColumnNames.add(ci.name);
// no need to add the descriptor if it is already on the list
if (addUdtMap.get(key) != null) {
continue;
}
addUdtMap.put(key, ad);
} else if (ci.action == ColumnInfo.DROP) {
dropColumnNames.add(ci.name);
dropUdtMap.put(key, ad);
}
}
// and this is not a DROP TABLE command
if (!dropWholeTable && addUdtMap.isEmpty() && dropUdtMap.isEmpty()) {
return;
}
//
// Now prune from the add list all udt descriptors for which we already have dependencies.
// These are the udts for old columns. This supports the ALTER TABLE ADD COLUMN
// case.
//
// Also prune from the drop list add udt descriptors which will still be
// referenced by the remaining columns.
//
ColumnDescriptorList cdl = td.getColumnDescriptorList();
int totalColumnCount = cdl.size();
for (int i = 0; i < totalColumnCount; i++) {
ColumnDescriptor cd = cdl.elementAt(i);
// skip columns that are being added and dropped. we only want the untouched columns
if (addColumnNames.contains(cd.getColumnName()) || dropColumnNames.contains(cd.getColumnName())) {
continue;
}
// nothing to do if the old column isn't a UDT
AliasDescriptor ad = dd.getAliasDescriptorForUDT(tc, cd.getType());
if (ad == null) {
continue;
}
String key = ad.getObjectID().toString();
// ha, it is a UDT.
if (dropWholeTable) {
dropUdtMap.put(key, ad);
} else {
if (addUdtMap.get(key) != null) {
addUdtMap.remove(key);
}
if (dropUdtMap.get(key) != null) {
dropUdtMap.remove(key);
}
}
}
adjustUDTDependencies(lcc, dd, td, addUdtMap, dropUdtMap);
}
use of org.apache.derby.iapi.store.access.TransactionController in project derby by apache.
the class GrantRoleConstantAction method executeConstantAction.
// INTERFACE METHODS
/**
* This is the guts of the Execution-time logic for GRANT role.
*
* @see ConstantAction#executeConstantAction
*
* @exception StandardException Thrown on failure
*/
public void executeConstantAction(Activation activation) throws StandardException {
LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
DataDictionary dd = lcc.getDataDictionary();
TransactionController tc = lcc.getTransactionExecute();
DataDescriptorGenerator ddg = dd.getDataDescriptorGenerator();
final String grantor = lcc.getCurrentUserId(activation);
dd.startWriting(lcc);
for (Iterator rIter = roleNames.iterator(); rIter.hasNext(); ) {
String role = (String) rIter.next();
if (role.equals(Authorizer.PUBLIC_AUTHORIZATION_ID)) {
throw StandardException.newException(SQLState.AUTH_PUBLIC_ILLEGAL_AUTHORIZATION_ID);
}
for (Iterator gIter = grantees.iterator(); gIter.hasNext(); ) {
String grantee = (String) gIter.next();
// check that role exists
RoleGrantDescriptor rdDef = dd.getRoleDefinitionDescriptor(role);
if (rdDef == null) {
throw StandardException.newException(SQLState.ROLE_INVALID_SPECIFICATION, role);
}
// :
if (grantor.equals(lcc.getDataDictionary().getAuthorizationDatabaseOwner())) {
// All ok, we are database owner
if (SanityManager.DEBUG) {
SanityManager.ASSERT(rdDef.getGrantee().equals(grantor), "expected database owner in role grant descriptor");
SanityManager.ASSERT(rdDef.isWithAdminOption(), "expected role definition to have ADMIN OPTION");
}
} else {
throw StandardException.newException(SQLState.AUTH_ROLE_DBO_ONLY, "GRANT role");
}
// Has it already been granted?
RoleGrantDescriptor rgd = dd.getRoleGrantDescriptor(role, grantee, grantor);
if (rgd != null && withAdminOption && !rgd.isWithAdminOption()) {
// NOTE: Never called yet, withAdminOption not yet
// implemented.
// Remove old descriptor and add a new one with admin
// option: cf. SQL 2003, section 12.5, general rule 3
rgd.drop(lcc);
rgd.setWithAdminOption(true);
dd.addDescriptor(rgd, // parent
null, DataDictionary.SYSROLES_CATALOG_NUM, // no duplicatesAllowed
false, tc);
} else if (rgd == null) {
// Check if the grantee is a role (if not, it is a user)
RoleGrantDescriptor granteeDef = dd.getRoleDefinitionDescriptor(grantee);
if (granteeDef != null) {
checkCircularity(role, grantee, grantor, tc, dd);
}
rgd = ddg.newRoleGrantDescriptor(dd.getUUIDFactory().createUUID(), role, grantee, // dbo for now
grantor, withAdminOption, // not definition
false);
dd.addDescriptor(rgd, // parent
null, DataDictionary.SYSROLES_CATALOG_NUM, // no duplicatesAllowed
false, tc);
}
// else exists already, no need to add
}
}
}
use of org.apache.derby.iapi.store.access.TransactionController in project derby by apache.
the class HashScanResultSet method openCore.
/**
* open a scan on the table. scan parameters are evaluated
* at each open, so there is probably some way of altering
* their values...
*
* @exception StandardException thrown on failure to open
*/
public void openCore() throws StandardException {
TransactionController tc;
beginTime = getCurrentTimeMillis();
if (SanityManager.DEBUG)
SanityManager.ASSERT(!isOpen, "HashScanResultSet already open");
// Get the current transaction controller
tc = activation.getTransactionController();
initIsolationLevel();
if (startKeyGetter != null) {
startPosition = (ExecIndexRow) startKeyGetter.invoke(activation);
if (sameStartStopPosition) {
stopPosition = startPosition;
}
}
if (stopKeyGetter != null) {
stopPosition = (ExecIndexRow) stopKeyGetter.invoke(activation);
}
// (and must) skip the scan, because no rows can qualify
if (skipScan(startPosition, stopPosition)) {
// Do nothing
;
} else if (!hashtableBuilt) {
DataValueDescriptor[] startPositionRow = startPosition == null ? null : startPosition.getRowArray();
DataValueDescriptor[] stopPositionRow = stopPosition == null ? null : stopPosition.getRowArray();
hashtable = tc.createBackingStoreHashtableFromScan(// conglomerate to open
conglomId, (forUpdate ? TransactionController.OPENMODE_FORUPDATE : 0), lockMode, isolationLevel, accessedCols, startPositionRow, startSearchOperator, scanQualifiers, stopPositionRow, stopSearchOperator, // no limit on total rows.
-1, keyColumns, // remove duplicates?
eliminateDuplicates, // RESOLVE - is there a row estimate?
-1, maxCapacity, // in memory Hashtable initial capacity
initialCapacity, // in memory Hashtable load factor
loadFactor, runTimeStatisticsOn, skipNullKeyColumns, keepAfterCommit, fetchRowLocations);
if (runTimeStatisticsOn) {
hashtableSize = hashtable.size();
if (scanProperties == null) {
scanProperties = new Properties();
}
try {
if (hashtable != null) {
hashtable.getAllRuntimeStats(scanProperties);
}
} catch (StandardException se) {
// ignore
}
}
/* Remember that we created the hash table */
hashtableBuilt = true;
/*
** Tell the activation about the number of qualifying rows.
** Do this only here, not in reopen, because we don't want
** to do this costly operation too often.
*/
activation.informOfRowCount(this, (long) hashtableSize);
}
isOpen = true;
resetProbeVariables();
numOpens++;
openTime += getElapsedMillis(beginTime);
}
use of org.apache.derby.iapi.store.access.TransactionController in project derby by apache.
the class InsertResultSet method getOldStyleIdentityValue.
/**
* Identity generation logic used in pre-10.11 databases.
*
* @param index 0-based index into aiCache
*/
private NumberDataValue getOldStyleIdentityValue(int index) throws StandardException {
NumberDataValue newValue;
TransactionController nestedTC = null;
TransactionController tcToUse;
try {
// DERBY-5780, defaulting log syncing to false, which improves
// performance of identity value generation. If system
// crashes may reuse an identity value because commit did not
// sync, but only if no subsequent user transaction has
// committed or aborted and thus no row can exist that used
// the previous value. Without this identity values pay
// a synchronous I/O to the log file for each new value no
// matter how many are inserted in a single transaction.
nestedTC = tc.startNestedUserTransaction(false, false);
tcToUse = nestedTC;
} catch (StandardException se) {
// If I cannot start a Nested User Transaction use the parent
// transaction to do all the work.
tcToUse = tc;
}
try {
/* If tcToUse == tc, then we are using parent xaction-- this
can happen if for some reason we couldn't start a nested
transaction
*/
newValue = dd.getSetAutoincrementValue(constants.autoincRowLocation[index], tcToUse, true, (NumberDataValue) aiCache[index], (tcToUse == tc));
} catch (StandardException se) {
if (tcToUse == tc) {
/* we've using the parent xaction and we've timed out; just
throw an error and exit.
*/
throw se;
}
if (se.getMessageId().equals(SQLState.LOCK_TIMEOUT) || se.isSelfDeadlock()) {
// if we couldn't do this with a nested xaction, retry with
// parent-- we need to wait this time!
newValue = dd.getSetAutoincrementValue(constants.autoincRowLocation[index], tc, true, (NumberDataValue) aiCache[index], true);
} else if (se.getMessageId().equals(SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE)) {
// error message
throw StandardException.newException(SQLState.LANG_AI_OVERFLOW, se, constants.getTableName(), constants.getColumnName(index));
} else
throw se;
} finally {
if (nestedTC != null) {
// DERBY-5493 - prior to fix all nested user update
// transactions did a nosync commit when commit() was
// called, this default has been changed to do synced
// commit. Changed this commit to be commitNoSync to
// not introduce performce degredation for autoincrement
// keys. As before, if server crashes the changes
// made in the nested transaction may be lost. If any
// subsequent user transaction is commited, including any
// inserts that would depend on the autoincrement value
// change then the nested tranaction is guaranteed on
// system crash.
nestedTC.commitNoSync(TransactionController.RELEASE_LOCKS);
nestedTC.destroy();
}
}
return newValue;
}
Aggregations