use of org.apache.derby.iapi.sql.conn.LanguageConnectionContext in project derby by apache.
the class ConsistencyChecker method checkTable.
/**
* Check the named table, ensuring that all of its indexes are consistent
* with the base table.
* Use this
* method only within an SQL-J statement; do not call it directly.
* <P>When tables are consistent, the method returns true. Otherwise, the method throws an exception.
* <p>To check the consistency of a single table:
* <p><code>
* VALUES ConsistencyChecker::checkTable(<i>SchemaName</i>, <i>TableName</i>)</code></p>
* <P>For example, to check the consistency of the table <i>APP.Flights</i>:
* <p><code>
* VALUES ConsistencyChecker::checkTable('APP', 'FLIGHTS')</code></p>
* <p>To check the consistency of all of the tables in the 'APP' schema,
* stopping at the first failure:
*
* <P><code>SELECT tablename, ConsistencyChecker::checkTable(<br>
* 'APP', tablename)<br>
* FROM sys.sysschemas s, sys.systables t
* WHERE s.schemaname = 'APP' AND s.schemaid = t.schemaid</code>
*
* <p> To check the consistency of an entire database, stopping at the first failure:
*
* <p><code>SELECT schemaname, tablename,<br>
* ConsistencyChecker::checkTable(schemaname, tablename)<br>
* FROM sys.sysschemas s, sys.systables t<br>
* WHERE s.schemaid = t.schemaid</code>
*
* @param schemaName The schema name of the table.
* @param tableName The name of the table
*
* @return true, if the table is consistent, exception thrown if inconsistent
*
* @exception SQLException Thrown if some inconsistency
* is found, or if some unexpected
* exception is thrown..
*/
public static boolean checkTable(String schemaName, String tableName) throws SQLException {
DataDictionary dd;
TableDescriptor td;
long baseRowCount = -1;
TransactionController tc;
ConglomerateDescriptor heapCD;
ConglomerateDescriptor indexCD;
ExecRow baseRow;
ExecRow indexRow;
RowLocation rl = null;
RowLocation scanRL = null;
ScanController scan = null;
int[] baseColumnPositions;
int baseColumns = 0;
DataValueFactory dvf;
long indexRows;
ConglomerateController baseCC = null;
ConglomerateController indexCC = null;
SchemaDescriptor sd;
ConstraintDescriptor constraintDesc;
LanguageConnectionContext lcc = ConnectionUtil.getCurrentLCC();
tc = lcc.getTransactionExecute();
try {
// make sure that application code doesn't bypass security checks
// by calling this public entry point
SecurityUtil.authorize(Securable.CHECK_TABLE);
dd = lcc.getDataDictionary();
dvf = lcc.getDataValueFactory();
ExecutionFactory ef = lcc.getLanguageConnectionFactory().getExecutionFactory();
sd = dd.getSchemaDescriptor(schemaName, tc, true);
td = dd.getTableDescriptor(tableName, sd, tc);
if (td == null) {
throw StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND, schemaName + "." + tableName);
}
/* Skip views */
if (td.getTableType() == TableDescriptor.VIEW_TYPE) {
return true;
}
/* Open the heap for reading */
baseCC = tc.openConglomerate(td.getHeapConglomerateId(), false, 0, TransactionController.MODE_TABLE, TransactionController.ISOLATION_SERIALIZABLE);
/* Check the consistency of the heap */
baseCC.checkConsistency();
heapCD = td.getConglomerateDescriptor(td.getHeapConglomerateId());
/* Get a row template for the base table */
baseRow = ef.getValueRow(td.getNumberOfColumns());
/* Fill the row with nulls of the correct type */
ColumnDescriptorList cdl = td.getColumnDescriptorList();
int cdlSize = cdl.size();
for (int index = 0; index < cdlSize; index++) {
ColumnDescriptor cd = (ColumnDescriptor) cdl.elementAt(index);
baseRow.setColumn(cd.getPosition(), cd.getType().getNull());
}
/* Look at all the indexes on the table */
ConglomerateDescriptor[] cds = td.getConglomerateDescriptors();
for (int index = 0; index < cds.length; index++) {
indexCD = cds[index];
/* Skip the heap */
if (!indexCD.isIndex())
continue;
/* Check the internal consistency of the index */
indexCC = tc.openConglomerate(indexCD.getConglomerateNumber(), false, 0, TransactionController.MODE_TABLE, TransactionController.ISOLATION_SERIALIZABLE);
indexCC.checkConsistency();
indexCC.close();
indexCC = null;
if (indexCD.isConstraint()) {
constraintDesc = dd.getConstraintDescriptor(td, indexCD.getUUID());
if (constraintDesc == null) {
throw StandardException.newException(SQLState.LANG_OBJECT_NOT_FOUND, "CONSTRAINT for INDEX", indexCD.getConglomerateName());
}
}
/*
** Set the base row count when we get to the first index.
** We do this here, rather than outside the index loop, so
** we won't do the work of counting the rows in the base table
** if there are no indexes to check.
*/
if (baseRowCount < 0) {
scan = tc.openScan(heapCD.getConglomerateNumber(), // hold
false, // not forUpdate
0, TransactionController.MODE_TABLE, TransactionController.ISOLATION_SERIALIZABLE, RowUtil.EMPTY_ROW_BITSET, // startKeyValue
null, // not used with null start posn.
0, // qualifier
null, // stopKeyValue
null, // not used with null stop posn.
0);
/* Also, get the row location template for index rows */
rl = scan.newRowLocationTemplate();
scanRL = scan.newRowLocationTemplate();
for (baseRowCount = 0; scan.next(); baseRowCount++) ;
/* Empty statement */
scan.close();
scan = null;
}
baseColumnPositions = indexCD.getIndexDescriptor().baseColumnPositions();
baseColumns = baseColumnPositions.length;
FormatableBitSet indexColsBitSet = new FormatableBitSet();
for (int i = 0; i < baseColumns; i++) {
indexColsBitSet.grow(baseColumnPositions[i]);
indexColsBitSet.set(baseColumnPositions[i] - 1);
}
/* Get one row template for the index scan, and one for the fetch */
indexRow = ef.getValueRow(baseColumns + 1);
/* Fill the row with nulls of the correct type */
for (int column = 0; column < baseColumns; column++) {
/* Column positions in the data dictionary are one-based */
ColumnDescriptor cd = td.getColumnDescriptor(baseColumnPositions[column]);
indexRow.setColumn(column + 1, cd.getType().getNull());
}
/* Set the row location in the last column of the index row */
indexRow.setColumn(baseColumns + 1, rl);
/* Do a full scan of the index */
scan = tc.openScan(indexCD.getConglomerateNumber(), // hold
false, // not forUpdate
0, TransactionController.MODE_TABLE, TransactionController.ISOLATION_SERIALIZABLE, (FormatableBitSet) null, // startKeyValue
null, // not used with null start posn.
0, // qualifier
null, // stopKeyValue
null, // not used with null stop posn.
0);
DataValueDescriptor[] baseRowIndexOrder = new DataValueDescriptor[baseColumns];
DataValueDescriptor[] baseObjectArray = baseRow.getRowArray();
for (int i = 0; i < baseColumns; i++) {
baseRowIndexOrder[i] = baseObjectArray[baseColumnPositions[i] - 1];
}
/* Get the index rows and count them */
for (indexRows = 0; scan.fetchNext(indexRow.getRowArray()); indexRows++) {
/*
** Get the base row using the RowLocation in the index row,
** which is in the last column.
*/
RowLocation baseRL = (RowLocation) indexRow.getColumn(baseColumns + 1);
boolean base_row_exists = baseCC.fetch(baseRL, baseObjectArray, indexColsBitSet);
/* Throw exception if fetch() returns false */
if (!base_row_exists) {
String indexName = indexCD.getConglomerateName();
throw StandardException.newException(SQLState.LANG_INCONSISTENT_ROW_LOCATION, (schemaName + "." + tableName), indexName, baseRL.toString(), indexRow.toString());
}
/* Compare all the column values */
for (int column = 0; column < baseColumns; column++) {
DataValueDescriptor indexColumn = indexRow.getColumn(column + 1);
DataValueDescriptor baseColumn = baseRowIndexOrder[column];
/*
** With this form of compare(), null is considered equal
** to null.
*/
if (indexColumn.compare(baseColumn) != 0) {
ColumnDescriptor cd = td.getColumnDescriptor(baseColumnPositions[column]);
throw StandardException.newException(SQLState.LANG_INDEX_COLUMN_NOT_EQUAL, indexCD.getConglomerateName(), td.getSchemaName(), td.getName(), baseRL.toString(), cd.getColumnName(), indexColumn.toString(), baseColumn.toString(), indexRow.toString());
}
}
}
/* Clean up after the index scan */
scan.close();
scan = null;
/*
** The index is supposed to have the same number of rows as the
** base conglomerate.
*/
if (indexRows != baseRowCount) {
throw StandardException.newException(SQLState.LANG_INDEX_ROW_COUNT_MISMATCH, indexCD.getConglomerateName(), td.getSchemaName(), td.getName(), Long.toString(indexRows), Long.toString(baseRowCount));
}
}
/* check that all constraints have backing index */
ConstraintDescriptorList constraintDescList = dd.getConstraintDescriptors(td);
for (int index = 0; index < constraintDescList.size(); index++) {
constraintDesc = constraintDescList.elementAt(index);
if (constraintDesc.hasBackingIndex()) {
ConglomerateDescriptor conglomDesc;
conglomDesc = td.getConglomerateDescriptor(constraintDesc.getConglomerateId());
if (conglomDesc == null) {
throw StandardException.newException(SQLState.LANG_OBJECT_NOT_FOUND, "INDEX for CONSTRAINT", constraintDesc.getConstraintName());
}
}
}
} catch (StandardException se) {
throw PublicAPI.wrapStandardException(se);
} finally {
try {
/* Clean up before we leave */
if (baseCC != null) {
baseCC.close();
baseCC = null;
}
if (indexCC != null) {
indexCC.close();
indexCC = null;
}
if (scan != null) {
scan.close();
scan = null;
}
} catch (StandardException se) {
throw PublicAPI.wrapStandardException(se);
}
}
return true;
}
use of org.apache.derby.iapi.sql.conn.LanguageConnectionContext in project derby by apache.
the class PropertyInfo method setDatabaseProperty.
/**
* Set or delete the value of a property of the database on the current connection.
* For security reasons (see DERBY-6616), this code is duplicated in SystemProcedures.
*
* @param key the property key
* @param value the new value, if null the property is deleted.
*
* @exception SQLException on error
*/
public static void setDatabaseProperty(String key, String value) throws SQLException {
LanguageConnectionContext lcc = ConnectionUtil.getCurrentLCC();
try {
SecurityUtil.authorize(Securable.SET_DATABASE_PROPERTY);
Authorizer a = lcc.getAuthorizer();
a.authorize((Activation) null, Authorizer.PROPERTY_WRITE_OP);
// Get the current transaction controller
TransactionController tc = lcc.getTransactionExecute();
tc.setProperty(key, value, false);
} catch (StandardException se) {
throw PublicAPI.wrapStandardException(se);
}
}
use of org.apache.derby.iapi.sql.conn.LanguageConnectionContext in project derby by apache.
the class SPSDescriptor method getPreparedStatement.
/**
* Get the preparedStatement for this statement.
* Expects the prepared statement to have already
* been added to SYS.SYSSTATEMENTS.
* <p>
* Side Effects: will update SYS.SYSSTATEMENTS with
* the new plan if it needs to be recompiled.
*
* @param recompIfInvalid if false, never recompile even
* if statement is invalid
*
* @return the preparedStatement
*
* @exception StandardException on error
*/
public final synchronized ExecPreparedStatement getPreparedStatement(boolean recompIfInvalid) throws StandardException {
/*
** Recompile if we are invalid, we don't have
** a prepared statement, or the statements activation
** has been cleared and cannot be reconstituted.
*/
if (recompIfInvalid && (!valid || (preparedStatement == null))) {
ContextManager cm = getContextService().getCurrentContextManager();
/*
** Find the language connection context. Get
** it each time in case a connection is dropped.
*/
LanguageConnectionContext lcc = (LanguageConnectionContext) cm.getContext(LanguageConnectionContext.CONTEXT_ID);
if (!lcc.getDataDictionary().isReadOnlyUpgrade()) {
final String savepoint = lcc.getUniqueSavepointName();
// First try compiling in a nested transaction so we can
// release the locks after the compilation, and not have them
// sit around in the parent transaction. But if we get lock
// time out in the nested transaction, then go ahead and do
// the compilation in the user transaction. When doing the
// compilation in the user transaction, the locks acquired for
// recompilation will be released at the end of the user
// transaction (commit or abort).
TransactionController nestedTC;
try {
nestedTC = lcc.getTransactionCompile().startNestedUserTransaction(false, true);
// DERBY-3693: The nested transaction may run into a lock
// conflict with its parent transaction, in which case we
// don't want to wait for a timeout. If a lock timeout is
// detected while we're executing the nested transaction,
// we ignore the error and retry in the user transaction.
// When retrying in the user transaction, we'll wait for
// locks if necessary.
nestedTC.setNoLockWait(true);
// Set a savepoint so that the work in the nested
// transaction can be rolled back on error without
// aborting the parent transaction.
nestedTC.setSavePoint(savepoint, null);
} catch (StandardException se) {
// If I cannot start a Nested User Transaction use the
// parent transaction to do all the work.
nestedTC = null;
}
try {
prepareAndRelease(lcc, null, nestedTC);
updateSYSSTATEMENTS(lcc, RECOMPILE, nestedTC);
} catch (StandardException se) {
if (nestedTC != null) {
// Roll back to savepoint to undo any work done by
// the nested transaction. We cannot abort the nested
// transaction in order to achieve the same, since
// that would also abort the parent transaction.
nestedTC.rollbackToSavePoint(savepoint, false, null);
}
if ((nestedTC != null) && (se.isLockTimeout() || se.isSelfDeadlock())) {
// Locks were set nowait, so a lock timeout here
// means that some lock request in the nested
// transaction immediately conflicted. A conflict
// with a parent lock would lead to a undetected
// deadlock so must give up trying in the nested
// transaction and retry with parent transaction.
nestedTC.commit();
nestedTC.destroy();
nestedTC = null;
// if we couldn't do this with a nested transaction,
// retry with parent-- we need to wait this time!
// Lock conflicts at this point are with other
// transactions, so must wait.
prepareAndRelease(lcc, null, null);
updateSYSSTATEMENTS(lcc, RECOMPILE, null);
} else {
throw se;
}
} finally {
// not abort the parent here.
if (nestedTC != null) {
nestedTC.commit();
nestedTC.destroy();
}
}
}
}
return preparedStatement;
}
use of org.apache.derby.iapi.sql.conn.LanguageConnectionContext in project derby by apache.
the class EmbedConnection method xa_prepare.
/*
** methods to be overridden by subimplementations wishing to insert
** their classes into the mix.
** The reason we need to override them is because we want to create a
** Local20/LocalStatment object (etc) rather than a Local/LocalStatment
** object (etc).
*/
/*
** XA support
*/
/**
* Do not use this method directly use XATransactionState.xa_prepare
* instead because it also maintains/cancels the timeout task which is
* scheduled to cancel/rollback the global transaction.
*
* @return One of {@link org.apache.derby.iapi.store.access.XATransactionController#XA_OK} or
* {@link org.apache.derby.iapi.store.access.XATransactionController#XA_RDONLY}
* @throws java.sql.SQLException
*/
public final int xa_prepare() throws SQLException {
synchronized (getConnectionSynchronization()) {
setupContextStack();
try {
LanguageConnectionContext lcc = privilegedGetLCC();
XATransactionController tc = (XATransactionController) lcc.getTransactionExecute();
try {
lcc.checkIntegrity();
} catch (StandardException e) {
lcc.xaRollback();
throw e;
}
int ret = tc.xa_prepare();
if (ret == XATransactionController.XA_RDONLY) {
// On a prepare call, xa allows an optimization that if the
// transaction is read only, the RM can just go ahead and
// commit it. So if store returns this read only status -
// meaning store has taken the liberty to commit already - we
// needs to turn around and call internalCommit (without
// committing the store again) to make sure the state is
// consistent. Since the transaction is read only, there is
// probably not much that needs to be done.
lcc.internalCommit(false);
}
InterruptStatus.restoreIntrFlagIfSeen(lcc);
return ret;
} catch (StandardException t) {
throw handleException(t);
} finally {
restoreContextStack();
}
}
}
use of org.apache.derby.iapi.sql.conn.LanguageConnectionContext in project derby by apache.
the class EmbedConnection method resetFromPool.
/**
* Reset the connection before it is returned from a PooledConnection
* to a new application request (wrapped by a BrokeredConnection).
* Examples of reset covered here is dropping session temporary tables
* and reseting IDENTITY_VAL_LOCAL.
* Most JDBC level reset is handled by calling standard java.sql.Connection
* methods from EmbedPooledConnection.
*/
public void resetFromPool() throws SQLException {
synchronized (getConnectionSynchronization()) {
setupContextStack();
try {
LanguageConnectionContext lcc = privilegedGetLCC();
lcc.resetFromPool();
InterruptStatus.restoreIntrFlagIfSeen(lcc);
} catch (StandardException t) {
throw handleException(t);
} finally {
restoreContextStack();
}
}
}
Aggregations