use of org.apache.derby.iapi.services.io.FormatableBitSet in project derby by apache.
the class PermissionsCacheable method setIdentity.
/* Cacheable interface */
public Cacheable setIdentity(Object key) throws StandardException {
// to access that column subset.
if (key instanceof TablePermsDescriptor) {
TablePermsDescriptor tablePermsKey = (TablePermsDescriptor) key;
permissions = dd.getUncachedTablePermsDescriptor(tablePermsKey);
if (permissions == null) {
// The owner has all privileges unless they have been revoked.
TableDescriptor td = dd.getTableDescriptor(tablePermsKey.getTableUUID());
SchemaDescriptor sd = td.getSchemaDescriptor();
if (sd.isSystemSchema()) {
// RESOLVE The access to system tables is hard coded to SELECT only to everyone.
// Is this the way we want Derby to work? Should we allow revocation of read access
// to system tables? If so we must explicitly add a row to the SYS.SYSTABLEPERMISSIONS
// table for each system table when a database is created.
permissions = new TablePermsDescriptor(dd, tablePermsKey.getGrantee(), (String) null, tablePermsKey.getTableUUID(), "Y", "N", "N", "N", "N", "N");
// give the permission the same UUID as the system table
((TablePermsDescriptor) permissions).setUUID(tablePermsKey.getTableUUID());
} else if (tablePermsKey.getGrantee().equals(sd.getAuthorizationId())) {
permissions = new TablePermsDescriptor(dd, tablePermsKey.getGrantee(), Authorizer.SYSTEM_AUTHORIZATION_ID, tablePermsKey.getTableUUID(), "Y", "Y", "Y", "Y", "Y", "Y");
} else {
permissions = new TablePermsDescriptor(dd, tablePermsKey.getGrantee(), (String) null, tablePermsKey.getTableUUID(), "N", "N", "N", "N", "N", "N");
}
}
} else if (key instanceof ColPermsDescriptor) {
ColPermsDescriptor colPermsKey = (ColPermsDescriptor) key;
permissions = dd.getUncachedColPermsDescriptor(colPermsKey);
if (permissions == null)
permissions = new ColPermsDescriptor(dd, colPermsKey.getGrantee(), (String) null, colPermsKey.getTableUUID(), colPermsKey.getType(), (FormatableBitSet) null);
} else if (key instanceof RoutinePermsDescriptor) {
RoutinePermsDescriptor routinePermsKey = (RoutinePermsDescriptor) key;
permissions = dd.getUncachedRoutinePermsDescriptor(routinePermsKey);
if (permissions == null) {
// The owner has all privileges unless they have been revoked.
try {
AliasDescriptor ad = dd.getAliasDescriptor(routinePermsKey.getRoutineUUID());
SchemaDescriptor sd = dd.getSchemaDescriptor(ad.getSchemaUUID(), ConnectionUtil.getCurrentLCC().getTransactionExecute());
if (sd.isSystemSchema() && !sd.isSchemaWithGrantableRoutines())
permissions = new RoutinePermsDescriptor(dd, routinePermsKey.getGrantee(), (String) null, routinePermsKey.getRoutineUUID(), true);
else if (routinePermsKey.getGrantee().equals(sd.getAuthorizationId()))
permissions = new RoutinePermsDescriptor(dd, routinePermsKey.getGrantee(), Authorizer.SYSTEM_AUTHORIZATION_ID, routinePermsKey.getRoutineUUID(), true);
} catch (java.sql.SQLException sqle) {
throw StandardException.plainWrapException(sqle);
}
}
} else if (key instanceof PermDescriptor) {
PermDescriptor permKey = (PermDescriptor) key;
permissions = dd.getUncachedGenericPermDescriptor(permKey);
if (permissions == null) {
// The owner has all privileges unless they have been revoked.
String objectType = permKey.getObjectType();
String privilege = permKey.getPermission();
UUID protectedObjectsID = permKey.getPermObjectId();
PrivilegedSQLObject pso = PermDescriptor.getProtectedObject(dd, protectedObjectsID, objectType);
SchemaDescriptor sd = pso.getSchemaDescriptor();
if (permKey.getGrantee().equals(sd.getAuthorizationId())) {
permissions = new PermDescriptor(dd, null, objectType, pso.getUUID(), privilege, Authorizer.SYSTEM_AUTHORIZATION_ID, permKey.getGrantee(), true);
}
}
} else {
if (SanityManager.DEBUG)
SanityManager.NOTREACHED();
return null;
}
if (permissions != null) {
return this;
}
return null;
}
use of org.apache.derby.iapi.services.io.FormatableBitSet in project derby by apache.
the class TabInfoImpl method updateRow.
/**
* Updates a set of base rows in a catalog with the same key on an index
* and updates all the corresponding index rows.
*
* @param key key row
* @param newRows new version of the array of rows
* @param indexNumber index that key operates
* @param indicesToUpdate array of booleans, one for each index on the catalog.
* if a boolean is true, that means we must update the
* corresponding index because changes in the newRow
* affect it.
* @param colsToUpdate array of ints indicating which columns (1 based)
* to update. If null, do all.
* @param tc transaction controller
*
* @exception StandardException Thrown on failure
*/
void updateRow(ExecIndexRow key, ExecRow[] newRows, int indexNumber, boolean[] indicesToUpdate, int[] colsToUpdate, TransactionController tc) throws StandardException {
ConglomerateController heapCC;
ScanController drivingScan;
ExecIndexRow drivingIndexRow;
RowLocation baseRowLocation;
ExecRow baseRow = crf.makeEmptyRow();
if (SanityManager.DEBUG) {
SanityManager.ASSERT(indicesToUpdate.length == crf.getNumIndexes(), "Wrong number of indices.");
}
RowChanger rc = getRowChanger(tc, colsToUpdate, baseRow);
// Row level locking
rc.openForUpdate(indicesToUpdate, TransactionController.MODE_RECORD, true);
/* Open the heap conglomerate */
heapCC = tc.openConglomerate(getHeapConglomerate(), false, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ);
drivingScan = tc.openScan(// conglomerate to open
getIndexConglomerate(indexNumber), // don't hold open across commit
false, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ, // all fields as objects
(FormatableBitSet) null, // start position - first row
key.getRowArray(), // startSearchOperation
ScanController.GE, // scanQualifier
null, // stop position - through last row
key.getRowArray(), // stopSearchOperation
ScanController.GT);
// Get an index row based on the base row
drivingIndexRow = getIndexRowFromHeapRow(getIndexRowGenerator(indexNumber), heapCC.newRowLocationTemplate(), crf.makeEmptyRow());
int rowNum = 0;
while (drivingScan.fetchNext(drivingIndexRow.getRowArray())) {
baseRowLocation = (RowLocation) drivingIndexRow.getColumn(drivingIndexRow.nColumns());
boolean base_row_exists = heapCC.fetch(baseRowLocation, baseRow.getRowArray(), (FormatableBitSet) null);
if (SanityManager.DEBUG) {
// it can not be possible for heap row to disappear while
// holding scan cursor on index at ISOLATION_REPEATABLE_READ.
SanityManager.ASSERT(base_row_exists, "base row not found");
}
rc.updateRow(baseRow, (rowNum == newRows.length - 1) ? newRows[rowNum] : newRows[rowNum++], baseRowLocation);
}
rc.finish();
heapCC.close();
drivingScan.close();
rc.close();
}
use of org.apache.derby.iapi.services.io.FormatableBitSet in project derby by apache.
the class TabInfoImpl method getRowInternal.
/**
* @exception StandardException Thrown on failure
*/
private ExecRow getRowInternal(TransactionController tc, ConglomerateController heapCC, ExecIndexRow key, int indexNumber, RowLocation[] rl) throws StandardException {
ScanController drivingScan;
ExecIndexRow drivingIndexRow;
RowLocation baseRowLocation;
ExecRow baseRow = crf.makeEmptyRow();
drivingScan = tc.openScan(getIndexConglomerate(indexNumber), // don't hold open across commit
false, // open for read
0, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ, // all fields as objects
(FormatableBitSet) null, // start position - first row
key.getRowArray(), // startSearchOperation
ScanController.GE, // scanQualifier
null, // stop position - through last row
key.getRowArray(), // stopSearchOperation
ScanController.GT);
// Get an index row based on the base row
drivingIndexRow = getIndexRowFromHeapRow(getIndexRowGenerator(indexNumber), heapCC.newRowLocationTemplate(), crf.makeEmptyRow());
try {
if (drivingScan.fetchNext(drivingIndexRow.getRowArray())) {
rl[0] = baseRowLocation = (RowLocation) drivingIndexRow.getColumn(drivingIndexRow.nColumns());
boolean base_row_exists = heapCC.fetch(baseRowLocation, baseRow.getRowArray(), (FormatableBitSet) null);
if (SanityManager.DEBUG) {
// it can not be possible for heap row to disappear while
// holding scan cursor on index at ISOLATION_REPEATABLE_READ.
SanityManager.ASSERT(base_row_exists, "base row not found");
}
return baseRow;
} else {
return null;
}
} finally {
drivingScan.close();
}
}
use of org.apache.derby.iapi.services.io.FormatableBitSet in project derby by apache.
the class InsertNode method bindStatement.
/**
* Bind this InsertNode. 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>
* Binding an insert will also massage the tree so that
* the collist and select column order/number are the
* same as the layout of the table in the store.
*
* @exception StandardException Thrown on error
*/
@Override
public void bindStatement() throws StandardException {
// We just need select privilege on the expressions
getCompilerContext().pushCurrentPrivType(Authorizer.SELECT_PRIV);
FromList fromList = new FromList(getOptimizerFactory().doJoinOrderOptimization(), getContextManager());
/* If any underlying ResultSetNode is a SelectNode, then we
* need to do a full bind(), including the expressions
* (since the fromList may include a FromSubquery).
*/
DataDictionary dataDictionary = getDataDictionary();
super.bindResultSetsWithTables(dataDictionary);
/*
** Get the TableDescriptor for the table we are inserting into
*/
verifyTargetTable();
// Check the validity of the targetProperties, if they exist
if (targetProperties != null) {
verifyTargetProperties(dataDictionary);
}
/*
** Get the resultColumnList representing the columns in the base
** table or VTI. We don't bother adding any permission checks here
** because they are assumed by INSERT permission on the table.
*/
IgnoreFilter ignorePermissions = new IgnoreFilter();
getCompilerContext().addPrivilegeFilter(ignorePermissions);
getResultColumnList();
/* If we have a target column list, then it must have the same # of
* entries as the result set's RCL.
*/
if (targetColumnList != null) {
/*
* Normalize synonym qualifers for column references.
*/
if (synonymTableName != null) {
normalizeSynonymColumns(targetColumnList, targetTableName);
}
/* Bind the target column list */
getCompilerContext().pushCurrentPrivType(getPrivType());
if (targetTableDescriptor != null) {
targetColumnList.bindResultColumnsByName(targetTableDescriptor, (DMLStatementNode) this);
} else {
targetColumnList.bindResultColumnsByName(targetVTI.getResultColumns(), targetVTI, this);
}
getCompilerContext().popCurrentPrivType();
}
getCompilerContext().removePrivilegeFilter(ignorePermissions);
/* 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()");
}
/* Replace any DEFAULTs with the associated tree, or flag DEFAULTs if
* not allowed (inside top level set operator nodes). Subqueries are
* checked for illegal DEFAULTs elsewhere.
*/
boolean isTableConstructor = (resultSet instanceof UnionNode && ((UnionNode) resultSet).tableConstructor()) || resultSet instanceof RowResultSetNode;
//
// For the MERGE statement, DEFAULT expressions in the SELECT node
// may have been replaced with generated expressions already.
//
ResultColumnList tempRCL = resultSet.getResultColumns();
boolean defaultsWereReplaced = false;
for (int i = 0; i < tempRCL.size(); i++) {
ResultColumn rc = tempRCL.getResultColumn(i + 1);
if (rc.wasDefaultColumn()) {
defaultsWereReplaced = true;
}
}
resultSet.replaceOrForbidDefaults(targetTableDescriptor, targetColumnList, isTableConstructor);
/* Bind the expressions now that the result columns are bound
* NOTE: This will be the 2nd time for those underlying ResultSets
* that have tables (no harm done), but it is necessary for those
* that do not have tables. It's too hard/not work the effort to
* avoid the redundancy.
*/
super.bindExpressions();
//
if (isPrivilegeCollectionRequired()) {
getCompilerContext().pushCurrentPrivType(getPrivType());
getCompilerContext().addRequiredTablePriv(targetTableDescriptor);
getCompilerContext().popCurrentPrivType();
}
// Now stop adding permissions checks.
getCompilerContext().addPrivilegeFilter(ignorePermissions);
/*
** If the result set is a union, it could be a table constructor.
** Bind any nulls in the result columns of the table constructor
** to the types of the table being inserted into.
**
** The types of ? parameters in row constructors and table constructors
** in an INSERT statement come from the result columns.
**
** If there is a target column list, use that instead of the result
** columns for the whole table, since the columns in the result set
** correspond to the target column list.
*/
if (targetColumnList != null) {
if (resultSet.getResultColumns().visibleSize() > targetColumnList.size())
throw StandardException.newException(SQLState.LANG_DB2_INVALID_COLS_SPECIFIED);
resultSet.bindUntypedNullsToResultColumns(targetColumnList);
resultSet.setTableConstructorTypes(targetColumnList);
} else {
if (resultSet.getResultColumns().visibleSize() > resultColumnList.size())
throw StandardException.newException(SQLState.LANG_DB2_INVALID_COLS_SPECIFIED);
resultSet.bindUntypedNullsToResultColumns(resultColumnList);
resultSet.setTableConstructorTypes(resultColumnList);
}
/* Bind the columns of the result set to their expressions */
resultSet.bindResultColumns(fromList);
int resCols = resultSet.getResultColumns().visibleSize();
DataDictionary dd = getDataDictionary();
if (targetColumnList != null) {
if (targetColumnList.size() != resCols)
throw StandardException.newException(SQLState.LANG_DB2_INVALID_COLS_SPECIFIED);
} else {
if (targetTableDescriptor != null && targetTableDescriptor.getNumberOfColumns() != resCols)
throw StandardException.newException(SQLState.LANG_DB2_INVALID_COLS_SPECIFIED);
}
/* See if the ResultSet's RCL needs to be ordered to match the target
* list, or "enhanced" to accommodate defaults. It can only need to
* be ordered if there is a target column list. It needs to be
* enhanced if there are fewer source columns than there are columns
* in the table.
*/
boolean inOrder = true;
int numTableColumns = resultColumnList.size();
/* colMap[] will be the size of the target list, which could be larger
* than the current size of the source list. In that case, the source
* list will be "enhanced" to include defaults.
*/
int[] colMap = new int[numTableColumns];
// set the fields to an unused value
for (int i = 0; i < colMap.length; i++) {
colMap[i] = -1;
}
/* Create the source/target list mapping */
if (targetColumnList != null) {
/*
** There is a target column list, so the result columns might
** need to be ordered. Step through the target column list
** and remember the position in the target table of each column.
** Remember if any of the columns are out of order.
*/
int targetSize = targetColumnList.size();
for (int index = 0; index < targetSize; index++) {
int position = targetColumnList.elementAt(index).getColumnDescriptor().getPosition();
if (index != position - 1) {
inOrder = false;
}
// position is 1-base; colMap indexes and entries are 0-based.
colMap[position - 1] = index;
}
} else {
/*
** There is no target column list, so the result columns in the
** source are presumed to be in the same order as the target
** table.
*/
for (int position = 0; position < resultSet.getResultColumns().visibleSize(); position++) {
colMap[position] = position;
}
}
// Bind the ORDER BY columns
if (orderByList != null) {
orderByList.pullUpOrderByColumns(resultSet);
// The select list may have new columns now, make sure to bind
// those.
super.bindExpressions();
orderByList.bindOrderByColumns(resultSet);
}
bindOffsetFetch(offset, fetchFirst);
resultSet = enhanceAndCheckForAutoincrement(resultSet, inOrder, colMap, defaultsWereReplaced);
resultColumnList.checkStorableExpressions(resultSet.getResultColumns());
/* Insert a NormalizeResultSetNode above the source if the source
* and target column types and lengths do not match.
*/
if (!resultColumnList.columnTypesAndLengthsMatch(resultSet.getResultColumns())) {
resultSet = new NormalizeResultSetNode(resultSet, resultColumnList, null, false, getContextManager());
}
if (targetTableDescriptor != null) {
ResultColumnList sourceRCL = resultSet.getResultColumns();
sourceRCL.copyResultColumnNames(resultColumnList);
/* bind all generation clauses for generated columns */
parseAndBindGenerationClauses(dataDictionary, targetTableDescriptor, sourceRCL, resultColumnList, false, null);
/* Get and bind all constraints on the table */
boolean[] hasDCC = new boolean[] { false /* a priori*/
};
checkConstraints = bindConstraints(dataDictionary, getOptimizerFactory(), targetTableDescriptor, null, sourceRCL, (int[]) null, (FormatableBitSet) null, // we always include triggers in core language
true, hasDCC);
hasDeferrableCheckConstraints = hasDCC[0];
/*
** Deferred if:
** If the target table is also a source table
** Self-referencing foreign key constraint
** trigger
*/
if (resultSet.referencesTarget(targetTableDescriptor.getName(), true) || requiresDeferredProcessing()) {
deferred = true;
/* Disallow bulk insert replace when target table
* is also a source table.
*/
if (bulkInsertReplace && resultSet.referencesTarget(targetTableDescriptor.getName(), true)) {
throw StandardException.newException(SQLState.LANG_INVALID_BULK_INSERT_REPLACE, targetTableDescriptor.getQualifiedName());
}
}
/* Get the list of indexes on the table being inserted into */
getAffectedIndexes(targetTableDescriptor);
TransactionController tc = getLanguageConnectionContext().getTransactionCompile();
autoincRowLocation = dd.computeAutoincRowLocations(tc, targetTableDescriptor);
} else {
deferred = VTIDeferModPolicy.deferIt(DeferModification.INSERT_STATEMENT, targetVTI, null, resultSet);
}
identitySequenceUUIDString = getUUIDofSequenceGenerator();
getCompilerContext().removePrivilegeFilter(ignorePermissions);
getCompilerContext().popCurrentPrivType();
}
use of org.apache.derby.iapi.services.io.FormatableBitSet in project derby by apache.
the class ResultColumnList method getReferencedFormatableBitSet.
/**
* Generate a FormatableBitSet representing the columns that are referenced in this RCL.
* The caller decides if they want this FormatableBitSet if every RC is referenced.
*
* @param positionedUpdate Whether or not the scan that the RCL
* belongs to is for update w/o a column list
* @param always Whether or not caller always wants a non-null FormatableBitSet if
* all RCs are referenced.
* @param onlyBCNs If true, only set bit if expression is a BaseColumnNode,
* otherwise set bit for all referenced RCs.
*
* @return The FormatableBitSet representing the referenced RCs.
*/
FormatableBitSet getReferencedFormatableBitSet(boolean positionedUpdate, boolean always, boolean onlyBCNs) {
int index;
int colsAdded = 0;
int size = size();
FormatableBitSet newReferencedCols = new FormatableBitSet(size);
/*
** For an updatable cursor, we need
** all columns.
*/
if (positionedUpdate) {
if (always) {
/* Set all bits in the bit map */
for (index = 0; index < size; index++) {
newReferencedCols.set(index);
}
return newReferencedCols;
} else {
return null;
}
}
for (index = 0; index < size; index++) {
ResultColumn oldCol = elementAt(index);
if (oldCol.isReferenced()) {
/* Skip RCs whose expression is not a BCN
* when requested to do so.
*/
if (onlyBCNs && !(oldCol.getExpression() instanceof BaseColumnNode)) {
boolean skipable = (!(oldCol.getExpression() instanceof BaseColumnNode)) && (!(oldCol.getExpression() instanceof CurrentRowLocationNode));
if (skipable) {
continue;
}
}
newReferencedCols.set(index);
colsAdded++;
}
}
/* Return the FormatableBitSet if not all RCs are referenced or if
* the caller always wants the FormatableBitSet returned.
*/
if (colsAdded != index || always) {
return newReferencedCols;
} else {
return null;
}
}
Aggregations