/** * This is the guts of the Execution-time logic for DROP ROLE. * * @see org.apache.derby.iapi.sql.execute.ConstantAction#executeConstantAction */ 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); RoleGrantDescriptor rdDef = dd.getRoleDefinitionDescriptor(roleName); if (rdDef == null) { throw StandardException.newException(SQLState.ROLE_INVALID_SPECIFICATION, roleName); } // When a role is dropped, for every role in its grantee closure, we // call the REVOKE_ROLE action. It is used to invalidate dependent // objects (constraints, triggers and views). Note that until // DERBY-1632 is fixed, we risk dropping objects not really dependent // on this role, but one some other role just because it inherits from // this one. See also RevokeRoleConstantAction. RoleClosureIterator rci = dd.createRoleClosureIterator(activation.getTransactionController(), roleName, false); String role; while ((role = rci.next()) != null) { RoleGrantDescriptor r = dd.getRoleDefinitionDescriptor(role); dd.getDependencyManager().invalidateFor(r, DependencyManager.REVOKE_ROLE, lcc); } rdDef.drop(lcc); /* * We dropped a role, now drop all dependents: * - role grants to this role * - grants of this role to other roles or users * - privilege grants to this role */ dd.dropRoleGrantsByGrantee(roleName, tc); dd.dropRoleGrantsByName(roleName, tc); dd.dropAllPermsByGrantee(roleName, tc); }
public String next() throws StandardException { if (initial) { // Optimization so we don't compute the closure for the current // role if unnecessary (when next is only called once). initial = false; seenSoFar.put(root, null); return root; } else if (graph == null) { // We get here the second time next is called. graph = dd.getRoleGrantGraph(tc, inverse); List outArcs = (List) graph.get(root); if (outArcs != null) { currNodeIter = outArcs.iterator(); } } RoleGrantDescriptor result = null; while (result == null) { while (currNodeIter.hasNext()) { RoleGrantDescriptor r = (RoleGrantDescriptor) currNodeIter.next(); if (seenSoFar.containsKey(inverse ? r.getRoleName() : r.getGrantee())) { continue; } else { lifo.add(r); result = r; break; } } if (result == null) { // not more candidates located outgoing from the // latest found node, pick another and continue RoleGrantDescriptor newNode = null; currNodeIter = null; while (lifo.size() > 0 && currNodeIter == null) { newNode = (RoleGrantDescriptor) lifo.remove(lifo.size() - 1); // In the example (see interface doc), the // iterator of outgoing arcs for f (grant inverse) // would contain {e,c,d}. List outArcs = (List) graph.get(inverse ? newNode.getRoleName() : newNode.getGrantee()); if (outArcs != null) { currNodeIter = outArcs.iterator(); } // else: leaf node, pop next candidate, if any } if (currNodeIter == null) { // candidate stack is empty, done currNodeIter = null; break; } } } if (result != null) { String role = inverse ? result.getRoleName() : result.getGrantee(); seenSoFar.put(role, null); return role; } else { return null; } }