use of org.apache.derby.iapi.sql.dictionary.DataDictionary in project derby by apache.
the class DropIndexNode method bindStatement.
/**
* Bind this DropIndexNode. This means looking up the index,
* verifying it exists and getting the conglomerate number.
*
* @exception StandardException Thrown on error
*/
@Override
public void bindStatement() throws StandardException {
CompilerContext cc = getCompilerContext();
DataDictionary dd = getDataDictionary();
SchemaDescriptor sd;
sd = getSchemaDescriptor();
if (sd.getUUID() != null)
cd = dd.getConglomerateDescriptor(getRelativeName(), sd, false);
if (cd == null) {
throw StandardException.newException(SQLState.LANG_INDEX_NOT_FOUND, getFullName());
}
/* Get the table descriptor */
td = getTableDescriptor(cd.getTableID());
/* Drop index is not allowed on an index backing a constraint -
* user must drop the constraint, which will drop the index.
* Drop constraint drops the constraint before the index,
* so it's okay to drop a backing index if we can't find its
* ConstraintDescriptor.
*/
if (cd.isConstraint()) {
ConstraintDescriptor conDesc;
String constraintName;
conDesc = dd.getConstraintDescriptor(td, cd.getUUID());
if (conDesc != null) {
constraintName = conDesc.getConstraintName();
throw StandardException.newException(SQLState.LANG_CANT_DROP_BACKING_INDEX, getFullName(), constraintName);
}
}
/* Statement is dependent on the TableDescriptor and ConglomerateDescriptor */
cc.createDependency(td);
cc.createDependency(cd);
}
use of org.apache.derby.iapi.sql.dictionary.DataDictionary in project derby by apache.
the class MergeNode method bindStatement.
// /////////////////////////////////////////////////////////////////////////////////
//
// bind() BEHAVIOR
//
// /////////////////////////////////////////////////////////////////////////////////
@Override
public void bindStatement() throws StandardException {
DataDictionary dd = getDataDictionary();
// source table must be a vti or base table
if (!(_sourceTable instanceof FromVTI) && !(_sourceTable instanceof FromBaseTable)) {
throw StandardException.newException(SQLState.LANG_SOURCE_NOT_BASE_OR_VTI);
}
// source and target may not have the same correlation names
if (getExposedName(_targetTable).equals(getExposedName(_sourceTable))) {
throw StandardException.newException(SQLState.LANG_SAME_EXPOSED_NAME);
}
// don't allow derived column lists right now
forbidDerivedColumnLists();
// synonyms not allowed
forbidSynonyms();
//
// Don't add any privileges until we bind the matching clauses.
//
IgnoreFilter ignorePermissions = new IgnoreFilter();
getCompilerContext().addPrivilegeFilter(ignorePermissions);
FromList dfl = new FromList(getContextManager());
FromTable dflSource = cloneFromTable(_sourceTable);
FromBaseTable dflTarget = (FromBaseTable) cloneFromTable(_targetTable);
dfl.addFromTable(dflSource);
dfl.addFromTable(dflTarget);
dfl.bindTables(dd, new FromList(getOptimizerFactory().doJoinOrderOptimization(), getContextManager()));
// target table must be a base table
if (!targetIsBaseTable(dflTarget)) {
notBaseTable();
}
// ready to add permissions
getCompilerContext().removePrivilegeFilter(ignorePermissions);
for (MatchingClauseNode mcn : _matchingClauses) {
FromList dummyFromList = cloneFromList(dd, dflTarget);
FromBaseTable dummyTargetTable = (FromBaseTable) dummyFromList.elementAt(TARGET_TABLE_INDEX);
mcn.bind(dd, this, dummyFromList, dummyTargetTable);
// window function not allowed
SelectNode.checkNoWindowFunctions(mcn, "matching clause");
// aggregates not allowed
checkNoAggregates(mcn);
}
bindLeftJoin(dd);
}
use of org.apache.derby.iapi.sql.dictionary.DataDictionary in project derby by apache.
the class GenericPreparedStatement method makeInvalid.
/**
* Mark the dependent as invalid (due to at least one of
* its dependencies being invalid).
*
* @param action The action causing the invalidation
*
* @exception StandardException Standard Derby error policy.
*/
public void makeInvalid(int action, LanguageConnectionContext lcc) throws StandardException {
boolean alreadyInvalid;
switch(action) {
case DependencyManager.RECHECK_PRIVILEGES:
return;
}
synchronized (this) {
if (compilingStatement) {
// Since the statement is in the process of being compiled,
// and at the end of the compilation it will set isValid to
// true and overwrite whatever we set it to here, set another
// flag to indicate that an invalidation was requested. A
// re-compilation will be triggered if this flag is set, but
// not until the current compilation is done.
invalidatedWhileCompiling = true;
return;
}
alreadyInvalid = !isValid;
// make ourseleves invalid
isValid = false;
// block compiles while we are invalidating
beginCompiling();
}
try {
DependencyManager dm = lcc.getDataDictionary().getDependencyManager();
/* Clear out the old dependencies on this statement as we
* will build the new set during the reprepare in makeValid().
*/
dm.clearDependencies(lcc, this);
/*
** If we are invalidating an EXECUTE STATEMENT because of a stale
** plan, we also need to invalidate the stored prepared statement.
*/
if (execStmtName != null) {
switch(action) {
case DependencyManager.INTERNAL_RECOMPILE_REQUEST:
case DependencyManager.CHANGED_CURSOR:
{
/*
** Get the DataDictionary, so we can get the descriptor for
** the SPP to invalidate it.
*/
DataDictionary dd = lcc.getDataDictionary();
SchemaDescriptor sd = dd.getSchemaDescriptor(execSchemaName, lcc.getTransactionCompile(), true);
SPSDescriptor spsd = dd.getSPSDescriptor(execStmtName, sd);
spsd.makeInvalid(action, lcc);
break;
}
}
}
} finally {
endCompiling();
}
}
use of org.apache.derby.iapi.sql.dictionary.DataDictionary in project derby by apache.
the class GenericStatement method prepMinion.
private PreparedStatement prepMinion(LanguageConnectionContext lcc, boolean cacheMe, Object[] paramDefaults, SchemaDescriptor spsSchema, boolean internalSQL) throws StandardException {
long beginTime = 0;
long parseTime = 0;
long bindTime = 0;
long optimizeTime = 0;
long generateTime = 0;
Timestamp beginTimestamp = null;
Timestamp endTimestamp = null;
StatementContext statementContext = null;
// if it is invalid, we will recompile now.
if (preparedStmt != null) {
if (preparedStmt.upToDate())
return preparedStmt;
}
// Start a new optimizer trace for this statement
if (lcc.optimizerTracingIsOn()) {
lcc.getOptimizerTracer().traceStartStatement(getSource());
}
beginTime = getCurrentTimeMillis(lcc);
/* beginTimestamp only meaningful if beginTime is meaningful.
* beginTime is meaningful if STATISTICS TIMING is ON.
*/
if (beginTime != 0) {
beginTimestamp = new Timestamp(beginTime);
}
/**
* set the prepare isolation from the LanguageConnectionContext now as
* we need to consider it in caching decisions
*/
prepareIsolationLevel = lcc.getPrepareIsolationLevel();
/* a note on statement caching:
*
* A GenericPreparedStatement (GPS) is only added it to the cache if the
* parameter cacheMe is set to TRUE when the GPS is created.
*
* Earlier only CacheStatement (CS) looked in the statement cache for a
* prepared statement when prepare was called. Now the functionality
* of CS has been folded into GenericStatement (GS). So we search the
* cache for an existing PreparedStatement only when cacheMe is TRUE.
* i.e if the user calls prepare with cacheMe set to TRUE:
* then we
* a) look for the prepared statement in the cache.
* b) add the prepared statement to the cache.
*
* In cases where the statement cache has been disabled (by setting the
* relevant Derby property) then the value of cacheMe is irrelevant.
*/
boolean foundInCache = false;
if (preparedStmt == null) {
if (cacheMe)
preparedStmt = (GenericPreparedStatement) ((GenericLanguageConnectionContext) lcc).lookupStatement(this);
if (preparedStmt == null) {
preparedStmt = new GenericPreparedStatement(this);
} else {
foundInCache = true;
}
}
// cache of prepared statement objects...
synchronized (preparedStmt) {
for (; ; ) {
if (foundInCache) {
if (preparedStmt.referencesSessionSchema()) {
// cannot use this state since it is private to a connection.
// switch to a new statement.
foundInCache = false;
preparedStmt = new GenericPreparedStatement(this);
break;
}
}
// did it get updated while we waited for the lock on it?
if (preparedStmt.upToDate()) {
return preparedStmt;
}
if (!preparedStmt.isCompiling()) {
break;
}
try {
preparedStmt.wait();
} catch (InterruptedException ie) {
InterruptStatus.setInterrupted();
}
}
preparedStmt.beginCompiling();
}
try {
HeaderPrintWriter istream = lcc.getLogStatementText() ? Monitor.getStream() : null;
/*
** For stored prepared statements, we want all
** errors, etc in the context of the underlying
** EXECUTE STATEMENT statement, so don't push/pop
** another statement context unless we don't have
** one. We won't have one if it is an internal
** SPS (e.g. jdbcmetadata).
*/
if (!preparedStmt.isStorable() || lcc.getStatementDepth() == 0) {
// since this is for compilation only, set atomic
// param to true and timeout param to 0
statementContext = lcc.pushStatementContext(true, isForReadOnly, getSource(), null, false, 0L);
}
/*
** RESOLVE: we may ultimately wish to pass in
** whether we are a jdbc metadata query or not to
** get the CompilerContext to make the createDependency()
** call a noop.
*/
CompilerContext cc = lcc.pushCompilerContext(compilationSchema);
if (prepareIsolationLevel != TransactionControl.UNSPECIFIED_ISOLATION_LEVEL) {
cc.setScanIsolationLevel(prepareIsolationLevel);
}
if (internalSQL || (spsSchema != null) && (spsSchema.isSystemSchema()) && (spsSchema.equals(compilationSchema))) {
cc.setReliability(CompilerContext.INTERNAL_SQL_LEGAL);
}
try {
// Statement logging if lcc.getLogStatementText() is true
if (istream != null) {
String xactId = lcc.getTransactionExecute().getActiveStateTxIdString();
istream.printlnWithHeader(LanguageConnectionContext.xidStr + xactId + "), " + LanguageConnectionContext.lccStr + lcc.getInstanceNumber() + "), " + LanguageConnectionContext.dbnameStr + lcc.getDbname() + "), " + LanguageConnectionContext.drdaStr + lcc.getDrdaID() + "), Begin compiling prepared statement: " + getSource() + " :End prepared statement");
}
Parser p = cc.getParser();
cc.setCurrentDependent(preparedStmt);
// Only top level statements go through here, nested statement
// will invoke this method from other places
StatementNode qt = (StatementNode) p.parseStatement(statementText, paramDefaults);
parseTime = getCurrentTimeMillis(lcc);
// Call user-written tree-printer if it exists
walkAST(lcc, qt, ASTVisitor.AFTER_PARSE);
if (SanityManager.DEBUG) {
if (SanityManager.DEBUG_ON("DumpParseTree")) {
SanityManager.GET_DEBUG_STREAM().print("\n\n============PARSE===========\n\n");
qt.treePrint();
lcc.getPrintedObjectsMap().clear();
}
if (SanityManager.DEBUG_ON("StopAfterParsing")) {
lcc.setLastQueryTree(qt);
throw StandardException.newException(SQLState.LANG_STOP_AFTER_PARSING);
}
}
/*
** Tell the data dictionary that we are about to do
** a bunch of "get" operations that must be consistent with
** each other.
*/
DataDictionary dataDictionary = lcc.getDataDictionary();
int ddMode = dataDictionary == null ? 0 : dataDictionary.startReading(lcc);
try {
// start a nested transaction -- all locks acquired by bind
// and optimize will be released when we end the nested
// transaction.
lcc.beginNestedTransaction(true);
qt.bindStatement();
bindTime = getCurrentTimeMillis(lcc);
// Call user-written tree-printer if it exists
walkAST(lcc, qt, ASTVisitor.AFTER_BIND);
if (SanityManager.DEBUG) {
if (SanityManager.DEBUG_ON("DumpBindTree")) {
SanityManager.GET_DEBUG_STREAM().print("\n\n============BIND===========\n\n");
qt.treePrint();
lcc.getPrintedObjectsMap().clear();
}
if (SanityManager.DEBUG_ON("StopAfterBinding")) {
throw StandardException.newException(SQLState.LANG_STOP_AFTER_BINDING);
}
}
// we do the check here.
if (preparedStmt.referencesSessionSchema(qt)) {
if (foundInCache)
((GenericLanguageConnectionContext) lcc).removeStatement(this);
}
// stop adding privileges for user-defined types
cc.skipTypePrivileges(true);
qt.optimizeStatement();
optimizeTime = getCurrentTimeMillis(lcc);
// Call user-written tree-printer if it exists
walkAST(lcc, qt, ASTVisitor.AFTER_OPTIMIZE);
// Statement logging if lcc.getLogStatementText() is true
if (istream != null) {
String xactId = lcc.getTransactionExecute().getActiveStateTxIdString();
istream.printlnWithHeader(LanguageConnectionContext.xidStr + xactId + "), " + LanguageConnectionContext.lccStr + lcc.getInstanceNumber() + "), " + LanguageConnectionContext.dbnameStr + lcc.getDbname() + "), " + LanguageConnectionContext.drdaStr + lcc.getDrdaID() + "), End compiling prepared statement: " + getSource() + " :End prepared statement");
}
} catch (StandardException se) {
lcc.commitNestedTransaction();
// Statement logging if lcc.getLogStatementText() is true
if (istream != null) {
String xactId = lcc.getTransactionExecute().getActiveStateTxIdString();
istream.printlnWithHeader(LanguageConnectionContext.xidStr + xactId + "), " + LanguageConnectionContext.lccStr + lcc.getInstanceNumber() + "), " + LanguageConnectionContext.dbnameStr + lcc.getDbname() + "), " + LanguageConnectionContext.drdaStr + lcc.getDrdaID() + "), Error compiling prepared statement: " + getSource() + " :End prepared statement");
}
throw se;
} finally {
/* Tell the data dictionary that we are done reading */
if (dataDictionary != null)
dataDictionary.doneReading(ddMode, lcc);
}
/* we need to move the commit of nested sub-transaction
* after we mark PS valid, during compilation, we might need
* to get some lock to synchronize with another thread's DDL
* execution, in particular, the compilation of insert/update/
* delete vs. create index/constraint (see Beetle 3976). We
* can't release such lock until after we mark the PS valid.
* Otherwise we would just erase the DDL's invalidation when
* we mark it valid.
*/
try // put in try block, commit sub-transaction if bad
{
if (SanityManager.DEBUG) {
if (SanityManager.DEBUG_ON("DumpOptimizedTree")) {
SanityManager.GET_DEBUG_STREAM().print("\n\n============OPT===========\n\n");
qt.treePrint();
lcc.getPrintedObjectsMap().clear();
}
if (SanityManager.DEBUG_ON("StopAfterOptimizing")) {
throw StandardException.newException(SQLState.LANG_STOP_AFTER_OPTIMIZING);
}
}
GeneratedClass ac = qt.generate(preparedStmt.getByteCodeSaver());
generateTime = getCurrentTimeMillis(lcc);
/* endTimestamp only meaningful if generateTime is meaningful.
* generateTime is meaningful if STATISTICS TIMING is ON.
*/
if (generateTime != 0) {
endTimestamp = new Timestamp(generateTime);
}
if (SanityManager.DEBUG) {
if (SanityManager.DEBUG_ON("StopAfterGenerating")) {
throw StandardException.newException(SQLState.LANG_STOP_AFTER_GENERATING);
}
}
/*
copy over the compile-time created objects
to the prepared statement. This always happens
at the end of a compile, so there is no need
to erase the previous entries on a re-compile --
this erases as it replaces. Set the activation
class in case it came from a StorablePreparedStatement
*/
preparedStmt.setConstantAction(qt.makeConstantAction());
preparedStmt.setSavedObjects(cc.getSavedObjects());
preparedStmt.setRequiredPermissionsList(cc.getRequiredPermissionsList());
preparedStmt.incrementVersionCounter();
preparedStmt.setActivationClass(ac);
preparedStmt.setNeedsSavepoint(qt.needsSavepoint());
preparedStmt.setCursorInfo((CursorInfo) cc.getCursorInfo());
preparedStmt.setIsAtomic(qt.isAtomic());
preparedStmt.setExecuteStatementNameAndSchema(qt.executeStatementName(), qt.executeSchemaName());
preparedStmt.setSPSName(qt.getSPSName());
preparedStmt.completeCompile(qt);
preparedStmt.setCompileTimeWarnings(cc.getWarnings());
// Schedule updates of any stale index statistics we may
// have detected when creating the plan.
TableDescriptor[] tds = qt.updateIndexStatisticsFor();
if (tds.length > 0) {
IndexStatisticsDaemon isd = lcc.getDataDictionary().getIndexStatsRefresher(true);
if (isd != null) {
for (int i = 0; i < tds.length; i++) {
isd.schedule(tds[i]);
}
}
}
} catch (// hold it, throw it
StandardException e) {
lcc.commitNestedTransaction();
throw e;
}
if (lcc.getRunTimeStatisticsMode()) {
preparedStmt.setCompileTimeMillis(// parse time
parseTime - beginTime, // bind time
bindTime - parseTime, // optimize time
optimizeTime - bindTime, // generate time
generateTime - optimizeTime, // total compile time
generateTime - beginTime, beginTimestamp, endTimestamp);
}
} finally // for block introduced by pushCompilerContext()
{
lcc.popCompilerContext(cc);
}
} catch (StandardException se) {
if (foundInCache)
((GenericLanguageConnectionContext) lcc).removeStatement(this);
throw se;
} finally {
preparedStmt.endCompiling();
}
lcc.commitNestedTransaction();
if (statementContext != null)
lcc.popStatementContext(statementContext, null);
return preparedStmt;
}
use of org.apache.derby.iapi.sql.dictionary.DataDictionary in project derby by apache.
the class IndexStatisticsDaemonImpl method writeUpdatedStats.
/**
* Writes updated statistics for the specified index to the data dictionary.
*
* @param lcc connection context to use to perform the work
* @param td the base table
* @param index the index of the base table
* @param numRows number of rows in the base table
* @param cardinality the number of unique values in the index (per number
* of leading columns)
* @param asBackgroundTask whether the update is done automatically as
* part of a background task or if explicitly invoked by the user
* @throws StandardException if updating the data dictionary fails
*/
private void writeUpdatedStats(LanguageConnectionContext lcc, TableDescriptor td, UUID index, long numRows, long[] cardinality, boolean asBackgroundTask) throws StandardException {
TransactionController tc = lcc.getTransactionExecute();
trace(1, "writing new stats (xid=" + tc.getTransactionIdString() + ")");
UUID table = td.getUUID();
DataDictionary dd = lcc.getDataDictionary();
UUIDFactory uf = dd.getUUIDFactory();
// Update the heap row count estimate.
setHeapRowEstimate(tc, td.getHeapConglomerateId(), numRows);
// Drop existing index statistics for this index.
if (!lcc.dataDictionaryInWriteMode()) {
dd.startWriting(lcc);
}
dd.dropStatisticsDescriptors(table, index, tc);
// invalidation control flag
boolean conglomerateGone = false;
// Don't write statistics if the table is empty.
if (numRows == 0) {
trace(2, "empty table, no stats written");
} else {
// Construct and add the statistics entries.
for (int i = 0; i < cardinality.length; i++) {
StatisticsDescriptor statDesc = new StatisticsDescriptor(dd, uf.createUUID(), index, table, "I", new StatisticsImpl(numRows, cardinality[i]), i + 1);
dd.addDescriptor(statDesc, null, DataDictionary.SYSSTATISTICS_CATALOG_NUM, true, tc);
}
// Log some information.
ConglomerateDescriptor cd = dd.getConglomerateDescriptor(index);
log(asBackgroundTask, td, "wrote stats for index " + (cd == null ? "n/a" : cd.getDescriptorName()) + " (" + index + "): rows=" + numRows + ", card=" + cardToStr(cardinality));
// for non-existent indexes in SYSSTATISTICS.
if (asBackgroundTask && cd == null) {
log(asBackgroundTask, td, "rolled back index stats because index has been dropped");
lcc.internalRollback();
}
conglomerateGone = (cd == null);
}
if (!conglomerateGone) {
// Invalidate statments accessing the given table.
invalidateStatements(lcc, td, asBackgroundTask);
}
// Only commit tx as we go if running as background task.
if (asBackgroundTask) {
lcc.internalCommit(true);
}
}
Aggregations