use of org.apache.derby.iapi.sql.dictionary.DataDictionary in project derby by apache.
the class DropTableConstantAction 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 {
TableDescriptor td;
UUID tableID;
ConglomerateDescriptor[] cds;
LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
DataDictionary dd = lcc.getDataDictionary();
DependencyManager dm = dd.getDependencyManager();
TransactionController tc = lcc.getTransactionExecute();
if ((sd != null) && sd.getSchemaName().equals(SchemaDescriptor.STD_DECLARED_GLOBAL_TEMPORARY_TABLES_SCHEMA_NAME)) {
// check if this is a temp table before checking data dictionary
td = lcc.getTableDescriptorForDeclaredGlobalTempTable(tableName);
if (// td null here means it is not a temporary table. Look for table in physical SESSION schema
td == null)
td = dd.getTableDescriptor(tableName, sd, tc);
if (// td null means tableName is not a temp table and it is not a physical table in SESSION schema
td == null) {
throw StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND_DURING_EXECUTION, fullTableName);
}
if (td.getTableType() == TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE) {
dm.invalidateFor(td, DependencyManager.DROP_TABLE, lcc);
tc.dropConglomerate(td.getHeapConglomerateId());
lcc.dropDeclaredGlobalTempTable(tableName);
return;
}
}
/* Lock the table before we access the data dictionary
* to prevent deadlocks.
*
* Note that for DROP TABLE replayed at Targets during REFRESH,
* the conglomerateNumber will be 0. That's ok. During REFRESH,
* we don't need to lock the conglomerate.
*/
if (conglomerateNumber != 0) {
lockTableForDDL(tc, conglomerateNumber, true);
}
/*
** 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);
/* Get the table descriptor. */
td = dd.getTableDescriptor(tableId);
if (td == null) {
throw StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND_DURING_EXECUTION, fullTableName);
}
/* Get an exclusive table lock on the table. */
long heapId = td.getHeapConglomerateId();
lockTableForDDL(tc, heapId, true);
/* Drop the triggers */
for (TriggerDescriptor trd : dd.getTriggerDescriptors(td)) {
trd.drop(lcc);
}
/* Drop all defaults */
ColumnDescriptorList cdl = td.getColumnDescriptorList();
for (ColumnDescriptor cd : cdl) {
//
if (cd.isAutoincrement() && dd.checkVersion(DataDictionary.DD_VERSION_DERBY_10_11, null)) {
dropIdentitySequence(dd, td, activation);
}
// any dependencies
if (cd.getDefaultInfo() != null) {
DefaultDescriptor defaultDesc = cd.getDefaultDescriptor(dd);
dm.clearDependencies(lcc, defaultDesc);
}
}
/* Drop the columns */
dd.dropAllColumnDescriptors(tableId, tc);
/* Drop all table and column permission descriptors */
dd.dropAllTableAndColPermDescriptors(tableId, tc);
/* Drop the constraints */
dropAllConstraintDescriptors(td, activation);
/*
** Drop all the conglomerates. Drop the heap last, because the
** store needs it for locking the indexes when they are dropped.
*/
cds = td.getConglomerateDescriptors();
long[] dropped = new long[cds.length - 1];
int numDropped = 0;
for (int index = 0; index < cds.length; index++) {
ConglomerateDescriptor cd = cds[index];
/* if it's for an index, since similar indexes share one
* conglomerate, we only drop the conglomerate once
*/
if (cd.getConglomerateNumber() != heapId) {
long thisConglom = cd.getConglomerateNumber();
int i;
for (i = 0; i < numDropped; i++) {
if (dropped[i] == thisConglom)
break;
}
if (// not dropped
i == numDropped) {
dropped[numDropped++] = thisConglom;
tc.dropConglomerate(thisConglom);
dd.dropStatisticsDescriptors(td.getUUID(), cd.getUUID(), tc);
}
}
}
/* Prepare all dependents to invalidate. (This is there chance
* to say that they can't be invalidated. For example, an open
* cursor referencing a table/view that the user is attempting to
* drop.) If no one objects, then invalidate any dependent objects.
* We check for invalidation before we drop the table descriptor
* since the table descriptor may be looked up as part of
* decoding tuples in SYSDEPENDS.
*/
dm.invalidateFor(td, DependencyManager.DROP_TABLE, lcc);
//
// The table itself can depend on the user defined types of its columns.
// Drop all of those dependencies now.
//
adjustUDTDependencies(lcc, dd, td, null, true);
/* Drop the table */
dd.dropTableDescriptor(td, sd, tc);
/* Drop the conglomerate descriptors */
dd.dropAllConglomerateDescriptors(td, tc);
/* Drop the store element at last, to prevent dangling reference
* for open cursor, beetle 4393.
*/
tc.dropConglomerate(heapId);
}
use of org.apache.derby.iapi.sql.dictionary.DataDictionary in project derby by apache.
the class SetConstraintsConstantAction method executeConstantAction.
/**
* This is the guts of the execution time logic for SET CONSTRAINT.
*
* @param activation
*
* @see ConstantAction#executeConstantAction
*
* @exception StandardException Thrown on failure
*/
public void executeConstantAction(Activation activation) throws StandardException {
final LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
final DataDictionary dd = lcc.getDataDictionary();
final List<String> boundConstraints = new ArrayList<String>();
if (constraints != null) {
for (TableName c : constraints) {
final SchemaDescriptor sd = dd.getSchemaDescriptor(c.getSchemaName(), lcc.getTransactionExecute(), true);
final ConstraintDescriptor cd = dd.getConstraintDescriptor(c.getTableName(), sd.getUUID());
if (cd == null) {
throw StandardException.newException(SQLState.LANG_OBJECT_NOT_FOUND, "CONSTRAINT", c.getFullSQLName());
}
final String bound = IdUtil.normalToDelimited(sd.getSchemaName()) + "." + IdUtil.normalToDelimited(cd.getConstraintName());
if (boundConstraints.contains(bound)) {
throw StandardException.newException(SQLState.LANG_DB2_DUPLICATE_NAMES, cd.getConstraintName(), bound);
} else {
boundConstraints.add(bound);
}
if (deferred && !cd.deferrable()) {
throw StandardException.newException(SQLState.LANG_SET_CONSTRAINT_NOT_DEFERRABLE, cd.getConstraintName());
}
lcc.setConstraintDeferred(activation, cd, deferred);
}
} else {
lcc.setDeferredAll(activation, deferred);
}
}
use of org.apache.derby.iapi.sql.dictionary.DataDictionary in project derby by apache.
the class TemporaryRowHolderResultSet method getNewRSOnCurrentRow.
/**
* Whip up a new Temp ResultSet that has a single
* row. This row will either have all the columns from
* the current row of the passed resultset or a subset
* of the columns from the passed resulset. It all depends
* on what columns are needed by the passed trigger and what
* columns exist in the resulset. The Temp resulset
* should only have the columns required by the trigger.
*
* @param triggerd We are building Temp resultset for this trigger
* @param activation the activation
* @param rs the result set
* @param colsReadFromTable The passed resultset is composed of
* these columns. We will create a temp resultset which
* will have either all these columns or only a subset of
* these columns. It all depends on what columns are needed
* by the trigger. If this param is null, then that means that
* all the columns from the trigger table have been read into
* the passed resultset.
*
* @return a single row result set
*
* @exception StandardException on error
*/
public static TemporaryRowHolderResultSet getNewRSOnCurrentRow(TriggerDescriptor triggerd, Activation activation, CursorResultSet rs, int[] colsReadFromTable) throws StandardException {
TemporaryRowHolderImpl singleRow;
DataDictionary dd = activation.getLanguageConnectionContext().getDataDictionary();
// any column reading optimization to maintain backward compatibility
if (!dd.checkVersion(DataDictionary.DD_VERSION_DERBY_10_9, null)) {
singleRow = new TemporaryRowHolderImpl(activation, null, rs.getResultDescription());
singleRow.insert(rs.getCurrentRow());
return (TemporaryRowHolderResultSet) singleRow.getResultSet();
}
// Get columns referenced in trigger action through REFERENCING clause
int[] referencedColsInTriggerAction = triggerd.getReferencedColsInTriggerAction();
// Get trigger column. If null, then it means that all the columns
// have been read because this trigger can be fired for any of the
// columns in the table
int[] referencedColsInTrigger = triggerd.getReferencedCols();
if (// this means not all the columns are being read
(referencedColsInTrigger != null) && (triggerd.isRowTrigger() && referencedColsInTriggerAction != null && referencedColsInTriggerAction.length != 0)) {
// If we are here, then trigger is defined on specific columns and
// it has trigger action columns used through REFERENCING clause
// Make an array which is a superset of trigger columns and
// trigger action columns referenced through REFERENCING clause.
// This superset is what the trigger is looking for in it's
// resulset.
int[] colsInTrigger = supersetofAllColumns(referencedColsInTrigger, referencedColsInTriggerAction);
int colsCountInTrigger = colsInTrigger.length;
int[] colsReallyNeeded = new int[colsCountInTrigger];
// Here, we find out what columns make up the passed resulset
int[] actualColsReadFromTable;
if (// this means not all the columns are being read
colsReadFromTable != null)
actualColsReadFromTable = justTheRequiredColumnsPositions(colsReadFromTable);
else {
int colsInTriggerTable = triggerd.getTableDescriptor().getNumberOfColumns();
actualColsReadFromTable = new int[colsInTriggerTable];
for (int i = 1; i <= colsInTriggerTable; i++) actualColsReadFromTable[i - 1] = i;
}
// Now we have what columns make up the passed resulset and what
// columns are needed by the trigger. We will map a temporary
// resultset for the trigger out of the above information using
// the passed resultset
int indexInActualColsReadFromTable = 0;
for (int i = 0; i < colsCountInTrigger; i++) {
for (; indexInActualColsReadFromTable < actualColsReadFromTable.length; indexInActualColsReadFromTable++) {
/* Return 1-based key column position if column is in the key */
if (actualColsReadFromTable[indexInActualColsReadFromTable] == colsInTrigger[i]) {
colsReallyNeeded[i] = indexInActualColsReadFromTable + 1;
break;
}
}
}
singleRow = new TemporaryRowHolderImpl(activation, null, activation.getLanguageConnectionContext().getLanguageFactory().getResultDescription(rs.getResultDescription(), colsReallyNeeded));
ExecRow row = activation.getExecutionFactory().getValueRow(colsCountInTrigger);
for (int i = 0; i < colsCountInTrigger; i++) row.setColumn(i + 1, rs.getCurrentRow().getColumn(colsReallyNeeded[i]));
singleRow.insert(row);
} else {
singleRow = new TemporaryRowHolderImpl(activation, null, rs.getResultDescription());
singleRow.insert(rs.getCurrentRow());
}
return (TemporaryRowHolderResultSet) singleRow.getResultSet();
}
use of org.apache.derby.iapi.sql.dictionary.DataDictionary in project derby by apache.
the class GenericPrivilegeInfo method executeGrantRevoke.
// /////////////////////////////////////////////////////////////////////////////////
//
// PrivilegeInfo BEHAVIOR
//
// /////////////////////////////////////////////////////////////////////////////////
/**
* This is the guts of the Execution-time logic for GRANT/REVOKE generic privileges.
*
* @param activation
* @param grant true if grant, false if revoke
* @param grantees a list of authorization ids (strings)
*
* @exception StandardException Thrown on failure
*/
public void executeGrantRevoke(Activation activation, boolean grant, List grantees) throws StandardException {
// Check that the current user has permission to grant the privileges.
LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
DataDictionary dd = lcc.getDataDictionary();
String currentUser = lcc.getCurrentUserId(activation);
TransactionController tc = lcc.getTransactionExecute();
SchemaDescriptor sd = _tupleDescriptor.getSchemaDescriptor();
UUID objectID = _tupleDescriptor.getUUID();
String objectTypeName = _tupleDescriptor.getObjectTypeName();
// Check that the current user has permission to grant the privileges.
checkOwnership(currentUser, (TupleDescriptor) _tupleDescriptor, sd, dd);
DataDescriptorGenerator ddg = dd.getDataDescriptorGenerator();
PermDescriptor permDesc = ddg.newPermDescriptor(null, objectTypeName, objectID, _privilege, currentUser, null, false);
dd.startWriting(lcc);
for (Iterator itr = grantees.iterator(); itr.hasNext(); ) {
// Keep track to see if any privileges are revoked by a revoke
// statement. If a privilege is not revoked, we need to raise a
// warning.
boolean privileges_revoked = false;
String grantee = (String) itr.next();
if (dd.addRemovePermissionsDescriptor(grant, permDesc, grantee, tc)) {
//
// We fall in here if we are performing REVOKE.
//
privileges_revoked = true;
int invalidationType = _restrict ? DependencyManager.REVOKE_PRIVILEGE_RESTRICT : DependencyManager.REVOKE_PRIVILEGE;
dd.getDependencyManager().invalidateFor(permDesc, invalidationType, lcc);
// Now invalidate all GPSs refering to the object.
dd.getDependencyManager().invalidateFor(_tupleDescriptor, invalidationType, lcc);
}
addWarningIfPrivilegeNotRevoked(activation, grant, privileges_revoked, grantee);
}
}
use of org.apache.derby.iapi.sql.dictionary.DataDictionary in project derby by apache.
the class SetRoleConstantAction method executeConstantAction.
// INTERFACE METHODS
/**
* This is the guts of the Execution-time logic for SET ROLE.
*
* @see ConstantAction#executeConstantAction
*
* @exception StandardException Thrown on failure
*/
public void executeConstantAction(Activation activation) throws StandardException {
LanguageConnectionContext lcc;
DataDictionary dd;
// find the language context.
lcc = activation.getLanguageConnectionContext();
dd = lcc.getDataDictionary();
String thisRoleName = roleName;
final String currentAuthId = lcc.getCurrentUserId(activation);
final String dbo = lcc.getDataDictionary().getAuthorizationDatabaseOwner();
TransactionController tc = lcc.getTransactionExecute();
// SQL 2003, section 18.3, General rule 1:
if (!tc.isIdle()) {
throw StandardException.newException(SQLState.INVALID_TRANSACTION_STATE_ACTIVE_CONNECTION);
}
if (type == StatementType.SET_ROLE_DYNAMIC) {
ParameterValueSet pvs = activation.getParameterValueSet();
DataValueDescriptor dvs = pvs.getParameter(0);
// SQL 2003, section 18.3, GR2: trim whitespace first, and
// interpret as identifier, then we convert it to case normal form
// here.
String roleId = dvs.getString();
if (roleId == null) {
throw StandardException.newException(SQLState.ID_PARSE_ERROR);
}
thisRoleName = IdUtil.parseRoleId(roleId);
}
RoleGrantDescriptor rdDef = null;
try {
String oldRole = lcc.getCurrentRoleId(activation);
if (oldRole != null && !oldRole.equals(thisRoleName)) {
rdDef = dd.getRoleDefinitionDescriptor(oldRole);
if (rdDef != null) {
dd.getDependencyManager().invalidateFor(rdDef, DependencyManager.RECHECK_PRIVILEGES, lcc);
}
// else: old role else no longer exists, so ignore.
}
if (thisRoleName != null) {
rdDef = dd.getRoleDefinitionDescriptor(thisRoleName);
// SQL 2003, section 18.3, General rule 4:
if (rdDef == null) {
throw StandardException.newException(SQLState.ROLE_INVALID_SPECIFICATION, thisRoleName);
}
if (!lcc.roleIsSettable(activation, thisRoleName)) {
throw StandardException.newException(SQLState.ROLE_INVALID_SPECIFICATION_NOT_GRANTED, thisRoleName);
}
}
} finally {
// reading above changes idle state, so reestablish it
lcc.userCommit();
}
lcc.setCurrentRole(activation, rdDef != null ? thisRoleName : null);
}
Aggregations