use of org.apache.derby.iapi.sql.dictionary.DataDictionary in project derby by apache.
the class TablePrivilegeInfo method executeGrantRevoke.
/**
* This is the guts of the Execution-time logic for GRANT/REVOKE of a table privilege
*
* @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 {
LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
DataDictionary dd = lcc.getDataDictionary();
String currentUser = lcc.getCurrentUserId(activation);
TransactionController tc = lcc.getTransactionExecute();
SchemaDescriptor sd = td.getSchemaDescriptor();
// Check that the current user has permission to grant the privileges.
checkOwnership(currentUser, td, sd, dd, lcc, grant);
DataDescriptorGenerator ddg = dd.getDataDescriptorGenerator();
TablePermsDescriptor tablePermsDesc = ddg.newTablePermsDescriptor(td, getPermString(SELECT_ACTION, false), getPermString(DELETE_ACTION, false), getPermString(INSERT_ACTION, false), getPermString(UPDATE_ACTION, false), getPermString(REFERENCES_ACTION, false), getPermString(TRIGGER_ACTION, false), currentUser);
ColPermsDescriptor[] colPermsDescs = new ColPermsDescriptor[columnBitSets.length];
for (int i = 0; i < columnBitSets.length; i++) {
if (columnBitSets[i] != null || // should be removed.
(!grant) && hasColumnPermissions(i) && actionAllowed[i]) {
colPermsDescs[i] = ddg.newColPermsDescriptor(td, getActionString(i, false), columnBitSets[i], currentUser);
}
}
dd.startWriting(lcc);
// Add or remove the privileges to/from the SYS.SYSTABLEPERMS and SYS.SYSCOLPERMS tables
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. For table privileges, we do not check if privilege for
// a specific action has been revoked or not. Also, we do not check
// privileges for specific columns. If at least one privilege has
// been revoked, we do not raise a warning. This has to be refined
// further to check for specific actions/columns and raise warning
// if any privilege has not been revoked.
boolean privileges_revoked = false;
String grantee = (String) itr.next();
if (tablePermsDesc != null) {
if (dd.addRemovePermissionsDescriptor(grant, tablePermsDesc, grantee, tc)) {
privileges_revoked = true;
dd.getDependencyManager().invalidateFor(tablePermsDesc, DependencyManager.REVOKE_PRIVILEGE, lcc);
// When revoking a privilege from a Table we need to
// invalidate all GPSs refering to it. But GPSs aren't
// Dependents of TablePermsDescr, but of the
// TableDescriptor itself, so we must send
// INTERNAL_RECOMPILE_REQUEST to the TableDescriptor's
// Dependents.
dd.getDependencyManager().invalidateFor(td, DependencyManager.INTERNAL_RECOMPILE_REQUEST, lcc);
}
}
for (int i = 0; i < columnBitSets.length; i++) {
if (colPermsDescs[i] != null) {
if (dd.addRemovePermissionsDescriptor(grant, colPermsDescs[i], grantee, tc)) {
privileges_revoked = true;
dd.getDependencyManager().invalidateFor(colPermsDescs[i], DependencyManager.REVOKE_PRIVILEGE, lcc);
// When revoking a privilege from a Table we need to
// invalidate all GPSs refering to it. But GPSs aren't
// Dependents of colPermsDescs[i], but of the
// TableDescriptor itself, so we must send
// INTERNAL_RECOMPILE_REQUEST to the TableDescriptor's
// Dependents.
dd.getDependencyManager().invalidateFor(td, DependencyManager.INTERNAL_RECOMPILE_REQUEST, lcc);
}
}
}
addWarningIfPrivilegeNotRevoked(activation, grant, privileges_revoked, grantee);
}
}
use of org.apache.derby.iapi.sql.dictionary.DataDictionary in project derby by apache.
the class SetSchemaConstantAction method executeConstantAction.
// INTERFACE METHODS
/**
* This is the guts of the Execution-time logic for SET SCHEMA.
*
* @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 thisSchemaName = schemaName;
if (type == StatementType.SET_SCHEMA_DYNAMIC) {
ParameterValueSet pvs = activation.getParameterValueSet();
DataValueDescriptor dvs = pvs.getParameter(0);
thisSchemaName = dvs.getString();
// null parameter is not allowed
if (thisSchemaName == null || thisSchemaName.length() > Limits.MAX_IDENTIFIER_LENGTH)
throw StandardException.newException(SQLState.LANG_DB2_REPLACEMENT_ERROR, "CURRENT SCHEMA");
} else if (type == StatementType.SET_SCHEMA_USER) {
thisSchemaName = lcc.getCurrentUserId(activation);
}
SchemaDescriptor sd = dd.getSchemaDescriptor(thisSchemaName, lcc.getTransactionExecute(), true);
lcc.setDefaultSchema(activation, sd);
}
use of org.apache.derby.iapi.sql.dictionary.DataDictionary in project derby by apache.
the class ClobStreamHeaderGenerator method determineHeaderFormat.
/**
* Determines which header format to use.
* <p>
* <em>Implementation note:</em> The header format is determined by
* consulting the data dictionary throught the context service. If there is
* no context, the operation will fail.
*
* @throws IllegalStateException if there is no context
*/
private void determineHeaderFormat() {
DatabaseContext dbCtx = (DatabaseContext) getContext(DatabaseContext.CONTEXT_ID);
if (dbCtx == null) {
throw new IllegalStateException("No context, unable to determine " + "which stream header format to generate");
} else {
DataDictionary dd = dbCtx.getDatabase().getDataDictionary();
try {
isPreDerbyTenFive = Boolean.valueOf(!dd.checkVersion(DataDictionary.DD_VERSION_DERBY_10_5, null));
} catch (StandardException se) {
// This should never happen as long as the second argument
// above is null. If it happens, just bomb out.
IllegalStateException ise = new IllegalStateException(se.getMessage());
ise.initCause(se);
throw ise;
}
// Update the DVD with information about the mode the database is
// being accessed in. It is assumed that a DVD is only shared
// within a single database, i.e. the mode doesn't change during
// the lifetime of the DVD.
callbackDVD.setStreamHeaderFormat(isPreDerbyTenFive);
}
}
use of org.apache.derby.iapi.sql.dictionary.DataDictionary in project derby by apache.
the class DeleteNode method bindStatement.
/**
* Bind this DeleteNode. This means looking up tables and columns and
* getting their types, and figuring out the result types of all
* expressions, as well as doing view resolution, permissions checking,
* etc.
* <p>
* If any indexes need to be updated, we add all the columns in the
* base table to the result column list, so that we can use the column
* values as look-up keys for the index rows to be deleted. Binding a
* delete will also massage the tree so that the ResultSetNode has
* column containing the RowLocation of the base row.
*
* @exception StandardException Thrown on error
*/
@Override
public void bindStatement() throws StandardException {
// We just need select privilege on the where clause tables
getCompilerContext().pushCurrentPrivType(Authorizer.SELECT_PRIV);
try {
FromList fromList = new FromList(getOptimizerFactory().doJoinOrderOptimization(), getContextManager());
ResultColumn rowLocationColumn = null;
CurrentRowLocationNode rowLocationNode;
TableName cursorTargetTableName = null;
CurrentOfNode currentOfNode = null;
//
// Don't add privilege requirements for the UDT types of columns.
// The compiler will attempt to add these when generating the full column list during
// binding of the tables.
//
IgnoreFilter ignorePermissions = new IgnoreFilter();
getCompilerContext().addPrivilegeFilter(ignorePermissions);
DataDictionary dataDictionary = getDataDictionary();
// for DELETE clause of a MERGE statement, the tables have already been bound
if (!inMatchingClause()) {
super.bindTables(dataDictionary);
}
// for positioned delete, get the cursor's target table.
if (SanityManager.DEBUG)
SanityManager.ASSERT(resultSet != null && resultSet instanceof SelectNode, "Delete must have a select result set");
SelectNode sel = (SelectNode) resultSet;
targetTable = (FromTable) sel.fromList.elementAt(0);
if (targetTable instanceof CurrentOfNode) {
currentOfNode = (CurrentOfNode) targetTable;
cursorTargetTableName = inMatchingClause() ? targetTableName : currentOfNode.getBaseCursorTargetTableName();
// instead of an assert, we might say the cursor is not updatable.
if (SanityManager.DEBUG)
SanityManager.ASSERT(cursorTargetTableName != null);
}
if (targetTable instanceof FromVTI) {
targetVTI = (FromVTI) targetTable;
targetVTI.setTarget();
} else {
// we get it from the cursor supplying the position.
if (targetTableName == null) {
// verify we have current of
if (SanityManager.DEBUG)
SanityManager.ASSERT(cursorTargetTableName != null);
targetTableName = cursorTargetTableName;
} else // the named table is the same as the cursor's target (base table name).
if (cursorTargetTableName != null) {
// be the same as a base name in the cursor.
if (!targetTableName.equals(cursorTargetTableName)) {
throw StandardException.newException(SQLState.LANG_CURSOR_DELETE_MISMATCH, targetTableName, currentOfNode.getCursorName());
}
}
}
// descriptor must exist, tables already bound.
verifyTargetTable();
/* Generate a select list for the ResultSetNode - CurrentRowLocation(). */
if (SanityManager.DEBUG) {
SanityManager.ASSERT((resultSet.getResultColumns() == null), "resultColumns is expected to be null until bind time");
}
if (targetTable instanceof FromVTI) {
getResultColumnList();
resultColumnList = targetTable.getResultColumnsForList(null, resultColumnList, null);
/* Set the new result column list in the result set */
resultSet.setResultColumns(resultColumnList);
} else {
/*
** Start off assuming no columns from the base table
** are needed in the rcl.
*/
resultColumnList = new ResultColumnList(getContextManager());
FromBaseTable fbt = getResultColumnList(resultColumnList);
readColsBitSet = getReadMap(dataDictionary, targetTableDescriptor);
resultColumnList = fbt.addColsToList(resultColumnList, readColsBitSet);
/*
** If all bits are set, then behave as if we chose all
** in the first place
*/
int i = 1;
int size = targetTableDescriptor.getMaxColumnID();
for (; i <= size; i++) {
if (!readColsBitSet.get(i)) {
break;
}
}
if (i > size) {
readColsBitSet = null;
}
/* Generate the RowLocation column */
rowLocationNode = new CurrentRowLocationNode(getContextManager());
rowLocationColumn = new ResultColumn(COLUMNNAME, rowLocationNode, getContextManager());
rowLocationColumn.markGenerated();
/* Append to the ResultColumnList */
resultColumnList.addResultColumn(rowLocationColumn);
/* Force the added columns to take on the table's correlation name, if any */
correlateAddedColumns(resultColumnList, targetTable);
/* Add the new result columns to the driving result set */
ResultColumnList originalRCL = resultSet.getResultColumns();
if (originalRCL != null) {
originalRCL.appendResultColumns(resultColumnList, false);
resultColumnList = originalRCL;
}
resultSet.setResultColumns(resultColumnList);
}
// done excluding column types from privilege checking
getCompilerContext().removePrivilegeFilter(ignorePermissions);
/* Bind the expressions before the ResultColumns are bound */
// only add privileges when we're inside the WHERE clause
ScopeFilter scopeFilter = new ScopeFilter(getCompilerContext(), CompilerContext.WHERE_SCOPE, 1);
getCompilerContext().addPrivilegeFilter(scopeFilter);
super.bindExpressions();
getCompilerContext().removePrivilegeFilter(scopeFilter);
/* Bind untyped nulls directly under the result columns */
resultSet.getResultColumns().bindUntypedNullsToResultColumns(resultColumnList);
if (!(targetTable instanceof FromVTI)) {
/* Bind the new ResultColumn */
rowLocationColumn.bindResultColumnToExpression();
bindConstraints(dataDictionary, getOptimizerFactory(), targetTableDescriptor, null, resultColumnList, (int[]) null, readColsBitSet, // we alway include triggers in core language
true, // dummy
new boolean[1]);
/* If the target table is also a source table, then
* the delete will have to be in deferred mode
* For deletes, this means that the target table appears in a
* subquery. Also, self-referencing foreign key deletes
* are deferred. And triggers cause the delete to be deferred.
*/
if (resultSet.subqueryReferencesTarget(targetTableDescriptor.getName(), true) || requiresDeferredProcessing()) {
deferred = true;
}
} else {
deferred = VTIDeferModPolicy.deferIt(DeferModification.DELETE_STATEMENT, targetVTI, null, sel.getWhereClause());
}
/* Verify that all underlying ResultSets reclaimed their FromList */
if (SanityManager.DEBUG) {
SanityManager.ASSERT(fromList.size() == 0, "fromList.size() is expected to be 0, not " + fromList.size() + " on return from RS.bindExpressions()");
}
// the ref action dependent tables and bind them.
if (fkTableNames != null) {
String currentTargetTableName = targetTableDescriptor.getSchemaName() + "." + targetTableDescriptor.getName();
if (!isDependentTable) {
// graph node
dependentTables = new HashSet<String>();
}
/*Check whether the current target has already been explored.
*If we are seeing the same table name which we binded earlier
*means we have cyclic references.
*/
if (dependentTables.add(currentTargetTableName)) {
cascadeDelete = true;
int noDependents = fkTableNames.length;
dependentNodes = new StatementNode[noDependents];
for (int i = 0; i < noDependents; i++) {
dependentNodes[i] = getDependentTableNode(fkSchemaNames[i], fkTableNames[i], fkRefActions[i], fkColDescriptors[i]);
dependentNodes[i].bindStatement();
}
}
} else {
// case where current dependent table does not have dependent tables
if (isDependentTable) {
String currentTargetTableName = targetTableDescriptor.getSchemaName() + "." + targetTableDescriptor.getName();
dependentTables.add(currentTargetTableName);
}
}
// add need for DELETE privilege on the target table
getCompilerContext().pushCurrentPrivType(getPrivType());
getCompilerContext().addRequiredTablePriv(targetTableDescriptor);
getCompilerContext().popCurrentPrivType();
} finally {
getCompilerContext().popCurrentPrivType();
}
}
use of org.apache.derby.iapi.sql.dictionary.DataDictionary in project derby by apache.
the class DropAliasNode method bindStatement.
/**
* Bind this DropMethodAliasNode.
*
* @exception StandardException Thrown on error
*/
@Override
public void bindStatement() throws StandardException {
DataDictionary dataDictionary = getDataDictionary();
String aliasName = getRelativeName();
AliasDescriptor ad = null;
SchemaDescriptor sd = getSchemaDescriptor();
if (sd.getUUID() != null) {
ad = dataDictionary.getAliasDescriptor(sd.getUUID().toString(), aliasName, nameSpace);
}
if (ad == null) {
throw StandardException.newException(SQLState.LANG_OBJECT_DOES_NOT_EXIST, statementToString(), aliasName);
}
// User cannot drop a system alias
if (ad.getSystemAlias()) {
throw StandardException.newException(SQLState.LANG_CANNOT_DROP_SYSTEM_ALIASES, aliasName);
}
// Statement is dependent on the AliasDescriptor
getCompilerContext().createDependency(ad);
}
Aggregations