use of org.apache.derby.iapi.sql.dictionary.DataDictionary in project derby by apache.
the class IndexChanger method insertAndCheckDups.
/**
* Insert the given row into the given conglomerate and check for duplicate
* key error.
*
* @param row The row to insert
*
* @exception StandardException Thrown on duplicate key error unless
* we have a deferred constraint. In that
* index rows are saved for checking
* on commit.
*/
private void insertAndCheckDups(ExecIndexRow row) throws StandardException {
openIndexCC();
int insertStatus;
final DataValueDescriptor[] rowArray = row.getRowArray();
if (deferrable) {
insertStatus = indexCC.insert(row.getRowArray());
if (SanityManager.DEBUG) {
// deferrable: we use a non-unique index
SanityManager.ASSERT(insertStatus != ConglomerateController.ROWISDUPLICATE);
}
final DataValueDescriptor[] key = new DataValueDescriptor[rowArray.length - 1];
System.arraycopy(rowArray, 0, key, 0, key.length);
// If the constraint mode is deferred, perform the check without
// waiting for any locks; we will just presume any lock conflicts
// constitute duplicates (not always the case), and check those keys
// again at commit time.
final boolean deferred = lcc.isEffectivelyDeferred(lcc.getCurrentSQLSessionContext(activation), getUniqueConstraintId());
// TODO add assert getUniqueConstraintId() != null
ScanController idxScan = tc.openScan(indexCID, false, (deferred ? TransactionController.OPENMODE_LOCK_ROW_NOWAIT : 0), TransactionController.MODE_RECORD, TransactionController.ISOLATION_READ_COMMITTED_NOHOLDLOCK, // retrieve all fields
(FormatableBitSet) null, key, // startSearchOp
ScanController.GE, null, key, ScanController.GT);
boolean duplicate = false;
try {
final boolean foundOne = idxScan.next();
if (SanityManager.DEBUG) {
SanityManager.ASSERT(foundOne, "IndexChanger: inserted row gone?");
}
duplicate = foundOne && idxScan.next();
} catch (StandardException e) {
if ((e.getSQLState().equals(SQLState.LOCK_TIMEOUT) || e.getSQLState().equals(SQLState.DEADLOCK)) && deferred) {
// Assume there is a duplicate, so we'll check again at
// commit time.
duplicate = true;
} else {
throw e;
}
}
if (duplicate && irg.isUniqueWithDuplicateNulls()) {
int keyParts = rowArray.length - 1;
for (int i = 0; i < keyParts; i++) {
// Keys with null in it are always unique
if (rowArray[i].isNull()) {
duplicate = false;
break;
}
}
}
if (duplicate) {
if (deferred) {
// Save duplicate row so we can check at commit time there is
// no longer any duplicate.
deferredDuplicates = DeferredConstraintsMemory.rememberDuplicate(lcc, deferredDuplicates, getUniqueConstraintId(), row.getRowArray());
} else {
// the constraint is not deferred, so throw
insertStatus = ConglomerateController.ROWISDUPLICATE;
}
}
} else {
// not a deferred constraint
insertStatus = indexCC.insert(row.getRowArray());
}
if (insertStatus == ConglomerateController.ROWISDUPLICATE) {
/*
** We have a duplicate key error.
*/
String indexOrConstraintName = indexName;
// now get table name, and constraint name if needed
LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
DataDictionary dd = lcc.getDataDictionary();
// get the descriptors
ConglomerateDescriptor cd = dd.getConglomerateDescriptor(indexCID);
UUID tableID = cd.getTableID();
TableDescriptor td = dd.getTableDescriptor(tableID);
String tableName = td.getName();
if (// no index name passed in
indexOrConstraintName == null) {
ConstraintDescriptor conDesc = dd.getConstraintDescriptor(td, cd.getUUID());
indexOrConstraintName = conDesc.getConstraintName();
}
StandardException se = StandardException.newException(SQLState.LANG_DUPLICATE_KEY_CONSTRAINT, indexOrConstraintName, tableName);
throw se;
} else {
if (SanityManager.DEBUG) {
if (insertStatus != 0) {
SanityManager.THROWASSERT("Unknown insert status " + insertStatus);
}
}
}
}
use of org.apache.derby.iapi.sql.dictionary.DataDictionary in project derby by apache.
the class DDLConstantAction method storeViewTriggerDependenciesOnPrivileges.
/**
* This method saves dependencies of views and triggers on privileges in
* the dependency system. It gets called by CreateViewConstantAction
* and CreateTriggerConstantAction. Views and triggers and constraints
* run with definer's privileges. If one of the required privileges is
* revoked from the definer, the dependent view/trigger/constraint on
* that privilege will be dropped automatically. In order to implement
* this behavior, we need to save view/trigger/constraint dependencies
* on required privileges in the dependency system. Following method
* accomplishes that part of the equation for views and triggers. The
* dependency collection for constraints is not same as for views and
* triggers and hence constraints are not covered by this method.
* Views and triggers can depend on many different kind of privileges
* where as constraints only depend on REFERENCES privilege on a table.
* Another difference is only one view or trigger can be defined by a
* sql statement and hence all the dependencies collected for the sql
* statement apply to the view or trigger in question. As for constraints,
* one sql statement can defined multiple constraints and hence the
* all the privileges required by the statement are not necessarily
* required by all the constraints defined by that sql statement. We need
* to identify right privileges for right constraints for a given sql
* statement. Because of these differences between constraints and views
* (and triggers), there are 2 different methods in this class to save
* their privileges in the dependency system.
*
* For each required privilege, we now register of a dependency on a role
* if that role was required to find an applicable privilege.
*
* @param activation The execution environment for this constant action.
* @param dependent Make this object depend on required privileges
*
* @exception StandardException Thrown on failure
*/
protected void storeViewTriggerDependenciesOnPrivileges(Activation activation, Dependent dependent) throws StandardException {
LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
DataDictionary dd = lcc.getDataDictionary();
DependencyManager dm = dd.getDependencyManager();
String dbo = dd.getAuthorizationDatabaseOwner();
String currentUser = lcc.getCurrentUserId(activation);
SettableBoolean roleDepAdded = new SettableBoolean();
// access any objects without any restrictions.
if (!currentUser.equals(dbo)) {
PermissionsDescriptor permDesc;
List<StatementPermission> requiredPermissionsList = activation.getPreparedStatement().getRequiredPermissionsList();
if (requiredPermissionsList != null && !requiredPermissionsList.isEmpty()) {
for (StatementPermission statPerm : requiredPermissionsList) {
// Also, StatementRolePermission should not occur here.
if (statPerm instanceof StatementSchemaPermission || statPerm instanceof StatementRolePermission) {
if (SanityManager.DEBUG) {
if (statPerm instanceof StatementRolePermission) {
SanityManager.THROWASSERT("Unexpected StatementRolePermission");
}
}
continue;
}
// See if we can find the required privilege for given authorizer?
permDesc = statPerm.getPermissionDescriptor(currentUser, dd);
if (// privilege not found for given authorizer
permDesc == null) {
// The if condition above means that required privilege does
// not exist at the user level. The privilege has to exist at
// PUBLIC level... ,
permDesc = statPerm.getPermissionDescriptor(Authorizer.PUBLIC_AUTHORIZATION_ID, dd);
boolean roleUsed = false;
// .. or at role level
if (permDesc == null || ((permDesc instanceof ColPermsDescriptor) && !((StatementColumnPermission) statPerm).allColumnsCoveredByUserOrPUBLIC(currentUser, dd))) {
roleUsed = true;
permDesc = findRoleUsage(activation, statPerm);
}
// owner.
if (!permDesc.checkOwner(currentUser)) {
dm.addDependency(dependent, permDesc, lcc.getContextManager());
// dependency, too.
if (roleUsed) {
trackRoleDependency(activation, dependent, roleDepAdded);
}
}
continue;
}
// object's privilege dependency in the dependency system
if (!permDesc.checkOwner(currentUser)) {
dm.addDependency(dependent, permDesc, lcc.getContextManager());
if (permDesc instanceof ColPermsDescriptor) {
// For a given table, the table owner can give privileges
// on some columns at individual user level and privileges
// on some columns at PUBLIC level. Hence, when looking for
// column level privileges, we need to look both at user
// level as well as PUBLIC level(only if user level column
// privileges do not cover all the columns accessed by this
// object). We have finished adding dependency for user level
// columns, now we are checking if some required column
// level privileges are at PUBLIC level.
// A specific eg of a view
// user1
// create table t11(c11 int, c12 int);
// grant select(c11) on t1 to user2;
// grant select(c12) on t1 to PUBLIC;
// user2
// create view v1 as select c11 from user1.t11 where c12=2;
// For the view above, there are 2 column level privilege
// depencies, one for column c11 which exists directly
// for user2 and one for column c12 which exists at PUBLIC level.
StatementColumnPermission statementColumnPermission = (StatementColumnPermission) statPerm;
permDesc = statementColumnPermission.getPUBLIClevelColPermsDescriptor(currentUser, dd);
if (permDesc != null && permDesc.getObjectID() != null) {
// User did not have all required column
// permissions and at least one column is
// covered by PUBLIC.
dm.addDependency(dependent, permDesc, lcc.getContextManager());
}
// upon?
if (!statementColumnPermission.allColumnsCoveredByUserOrPUBLIC(currentUser, dd)) {
trackRoleDependency(activation, dependent, roleDepAdded);
}
}
}
}
}
}
}
use of org.apache.derby.iapi.sql.dictionary.DataDictionary in project derby by apache.
the class DropConstraintConstantAction method executeConstantAction.
// INTERFACE METHODS
/**
* This is the guts of the Execution-time logic for DROP CONSTRAINT.
*
* @see ConstantAction#executeConstantAction
*
* @exception StandardException Thrown on failure
*/
public void executeConstantAction(Activation activation) throws StandardException {
ConstraintDescriptor conDesc = null;
TableDescriptor td;
UUID indexId = null;
String indexUUIDString;
LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
DataDictionary dd = lcc.getDataDictionary();
DependencyManager dm = dd.getDependencyManager();
TransactionController tc = lcc.getTransactionExecute();
/*
** Inform the data dictionary that we are about to write to it.
** There are several calls to data dictionary "get" methods here
** that might be done in "read" mode in the data dictionary, but
** it seemed safer to do this whole operation in "write" mode.
**
** We tell the data dictionary we're done writing at the end of
** the transaction.
*/
dd.startWriting(lcc);
td = dd.getTableDescriptor(tableId);
if (td == null) {
throw StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND_DURING_EXECUTION, tableName);
}
/* Table gets locked in AlterTableConstantAction */
/*
** If the schema descriptor is null, then
** we must have just read ourselves in.
** So we will get the corresponding schema
** descriptor from the data dictionary.
*/
SchemaDescriptor tdSd = td.getSchemaDescriptor();
SchemaDescriptor constraintSd = constraintSchemaName == null ? tdSd : dd.getSchemaDescriptor(constraintSchemaName, tc, true);
/* Get the constraint descriptor for the index, along
* with an exclusive row lock on the row in sys.sysconstraints
* in order to ensure that no one else compiles against the
* index.
*/
if (// this means "alter table drop primary key"
constraintName == null)
conDesc = dd.getConstraintDescriptors(td).getPrimaryKey();
else
conDesc = dd.getConstraintDescriptorByName(td, constraintSd, constraintName, true);
// Error if constraint doesn't exist
if (conDesc == null) {
String errorName = constraintName == null ? "PRIMARY KEY" : (constraintSd.getSchemaName() + "." + constraintName);
throw StandardException.newException(SQLState.LANG_DROP_OR_ALTER_NON_EXISTING_CONSTRAINT, errorName, td.getQualifiedName());
}
switch(verifyType) {
case DataDictionary.UNIQUE_CONSTRAINT:
if (conDesc.getConstraintType() != verifyType)
throw StandardException.newException(SQLState.LANG_DROP_CONSTRAINT_TYPE, constraintName, "UNIQUE");
break;
case DataDictionary.CHECK_CONSTRAINT:
if (conDesc.getConstraintType() != verifyType)
throw StandardException.newException(SQLState.LANG_DROP_CONSTRAINT_TYPE, constraintName, "CHECK");
break;
case DataDictionary.FOREIGNKEY_CONSTRAINT:
if (conDesc.getConstraintType() != verifyType)
throw StandardException.newException(SQLState.LANG_DROP_CONSTRAINT_TYPE, constraintName, "FOREIGN KEY");
break;
}
boolean cascadeOnRefKey = (cascade && conDesc instanceof ReferencedKeyConstraintDescriptor);
if (!cascadeOnRefKey) {
dm.invalidateFor(conDesc, DependencyManager.DROP_CONSTRAINT, lcc);
}
/*
** If we had a primary/unique key and it is drop cascade,
** drop all the referencing keys now. We MUST do this AFTER
** dropping the referenced key because otherwise we would
** be repeatedly changing the reference count of the referenced
** key and generating unnecessary I/O.
*/
dropConstraint(conDesc, activation, lcc, !cascadeOnRefKey);
if (cascadeOnRefKey) {
ForeignKeyConstraintDescriptor fkcd;
ReferencedKeyConstraintDescriptor cd;
ConstraintDescriptorList cdl;
cd = (ReferencedKeyConstraintDescriptor) conDesc;
cdl = cd.getForeignKeyConstraints(ReferencedKeyConstraintDescriptor.ALL);
int cdlSize = cdl.size();
for (int index = 0; index < cdlSize; index++) {
fkcd = (ForeignKeyConstraintDescriptor) cdl.elementAt(index);
dm.invalidateFor(fkcd, DependencyManager.DROP_CONSTRAINT, lcc);
dropConstraint(fkcd, activation, lcc, true);
}
/*
** We told dropConstraintAndIndex not to
** remove our dependencies, so send an invalidate,
** and drop the dependencies.
*/
dm.invalidateFor(conDesc, DependencyManager.DROP_CONSTRAINT, lcc);
dm.clearDependencies(lcc, conDesc);
}
}
use of org.apache.derby.iapi.sql.dictionary.DataDictionary in project derby by apache.
the class DropSchemaConstantAction method executeConstantAction.
// INTERFACE METHODS
/**
* This is the guts of the Execution-time logic for DROP TABLE.
*
* @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();
/*
** Inform the data dictionary that we are about to write to it.
** There are several calls to data dictionary "get" methods here
** that might be done in "read" mode in the data dictionary, but
** it seemed safer to do this whole operation in "write" mode.
**
** We tell the data dictionary we're done writing at the end of
** the transaction.
*/
dd.startWriting(lcc);
SchemaDescriptor sd = dd.getSchemaDescriptor(schemaName, tc, true);
sd.drop(lcc, activation);
}
use of org.apache.derby.iapi.sql.dictionary.DataDictionary in project derby by apache.
the class DropStatisticsConstantAction method executeConstantAction.
public void executeConstantAction(Activation activation) throws StandardException {
TableDescriptor td;
ConglomerateDescriptor cd = null;
LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
DataDictionary dd = lcc.getDataDictionary();
DependencyManager dm = dd.getDependencyManager();
TransactionController tc = lcc.getTransactionExecute();
dd.startWriting(lcc);
if (forTable) {
td = dd.getTableDescriptor(objectName, sd, tc);
} else {
cd = dd.getConglomerateDescriptor(objectName, sd, false);
td = dd.getTableDescriptor(cd.getTableID());
}
/* invalidate all SPS's on the table-- bad plan on SPS, so user drops
* statistics and would want SPS's invalidated so that recompile would
* give good plans; thats the theory anyways....
*/
dm.invalidateFor(td, DependencyManager.DROP_STATISTICS, lcc);
dd.dropStatisticsDescriptors(td.getUUID(), ((cd != null) ? cd.getUUID() : null), tc);
}
Aggregations