use of org.apache.derby.iapi.store.access.TransactionController in project derby by apache.
the class GenericLanguageConnectionContext method cleanupTempTableOnCommitOrRollback.
/**
* If dropAndRedeclare is true, that means we have come here for temp
* tables with on commit delete rows and no held curosr open on them. We
* will drop the existing conglomerate and redeclare a new conglomerate
* similar to old conglomerate. This is a more efficient way of deleting
* all rows from the table.
*
* If dropAndRedeclare is false, that means we have come here for the
* rollback cleanup work. We are trying to restore old definition of the
* temp table (because the drop on it is being rolled back).
*/
private TableDescriptor cleanupTempTableOnCommitOrRollback(TableDescriptor td, boolean dropAndRedeclare) throws StandardException {
TransactionController tc = getTransactionExecute();
// create new conglomerate with same properties as the old conglomerate
// and same row template as the old conglomerate
long conglomId = tc.createConglomerate(// we're requesting a heap conglomerate
"heap", // row template
td.getEmptyExecRow().getRowArray(), // column sort order - not required for heap
null, // same ids as old conglomerate
td.getColumnCollationIds(), // properties
null, (TransactionController.IS_TEMPORARY | TransactionController.IS_KEPT));
long cid = td.getHeapConglomerateId();
// remove the old conglomerate descriptor from the table descriptor
ConglomerateDescriptor cgd = td.getConglomerateDescriptor(cid);
td.getConglomerateDescriptorList().dropConglomerateDescriptorByUUID(cgd.getUUID());
// add the new conglomerate descriptor to the table descriptor
cgd = getDataDictionary().getDataDescriptorGenerator().newConglomerateDescriptor(conglomId, null, false, null, false, null, td.getUUID(), td.getSchemaDescriptor().getUUID());
ConglomerateDescriptorList conglomList = td.getConglomerateDescriptorList();
conglomList.add(cgd);
// reset the heap conglomerate number in table descriptor to -1 so it
// will be refetched next time with the new value
td.resetHeapConglomNumber();
if (dropAndRedeclare) {
// remove the old conglomerate from the system
tc.dropConglomerate(cid);
replaceDeclaredGlobalTempTable(td.getName(), td);
}
return (td);
}
use of org.apache.derby.iapi.store.access.TransactionController in project derby by apache.
the class GenericLanguageConnectionContext method internalRollbackToSavepoint.
/**
* Let the context deal with a rollback to savepoint
*
* @param savepointName Name of the savepoint that needs to be rolled back
* @param refreshStyle boolean indicating whether or not the controller should close
* open conglomerates and scans. Also used to determine if language should close
* open activations.
* @param kindOfSavepoint A NULL value means it is an internal savepoint (ie not a user defined savepoint)
* Non NULL value means it is a user defined savepoint which can be a SQL savepoint or a JDBC savepoint
* A String value for kindOfSavepoint would mean it is SQL savepoint
* A JDBC Savepoint object value for kindOfSavepoint would mean it is JDBC savepoint
*
* @exception StandardException thrown if something goes wrong
*/
public void internalRollbackToSavepoint(String savepointName, boolean refreshStyle, Object kindOfSavepoint) throws StandardException {
// now rollback the Store transaction to the savepoint
TransactionController tc = getTransactionExecute();
if (tc != null) {
boolean closeConglomerates;
if (refreshStyle) {
closeConglomerates = true;
// bug 5145 - don't forget to close the activations while rolling
// back to a savepoint
endTransactionActivationHandling(true);
} else {
closeConglomerates = false;
}
currentSavepointLevel = tc.rollbackToSavePoint(savepointName, closeConglomerates, kindOfSavepoint);
}
if (tc != null && refreshStyle && allDeclaredGlobalTempTables != null)
tempTablesAndRollback();
}
use of org.apache.derby.iapi.store.access.TransactionController in project derby by apache.
the class CreateConstraintConstantAction method executeConstantAction.
// INTERFACE METHODS
/**
* This is the guts of the Execution-time logic for CREATE CONSTRAINT.
* <P>
* A constraint is represented as:
* <UL>
* <LI> ConstraintDescriptor.
* </UL>
* If a backing index is required then the index will
* be created through an CreateIndexConstantAction setup
* by the compiler.
* <BR>
* Dependencies are created as:
* <UL>
* <LI> ConstraintDescriptor depends on all the providers collected
* at compile time and passed into the constructor.
* <LI> For a FOREIGN KEY constraint ConstraintDescriptor depends
* on the ConstraintDescriptor for the referenced constraints
* and the privileges required to create the constraint.
* </UL>
*
* @see ConstraintDescriptor
* @see CreateIndexConstantAction
* @see ConstantAction#executeConstantAction
*
* @exception StandardException Thrown on failure
*/
public void executeConstantAction(Activation activation) throws StandardException {
ConglomerateDescriptor conglomDesc = null;
ConglomerateDescriptor[] conglomDescs = null;
ConstraintDescriptor conDesc = null;
TableDescriptor td = null;
UUID indexId = null;
String uniqueName;
String backingIndexName;
/* RESOLVE - blow off not null constraints for now (and probably for ever) */
if (constraintType == DataDictionary.NOTNULL_CONSTRAINT) {
return;
}
LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
DataDictionary dd = lcc.getDataDictionary();
DependencyManager dm = dd.getDependencyManager();
TransactionController tc = lcc.getTransactionExecute();
cf = lcc.getLanguageConnectionFactory().getClassFactory();
/*
** 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);
/* Table gets locked in AlterTableConstantAction */
/*
** If the schema descriptor is null, then
** we must have just read ourselves in.
** So we will get the corresponding schema
** descriptor from the data dictionary.
*/
SchemaDescriptor sd = dd.getSchemaDescriptor(schemaName, tc, true);
/* Try to get the TableDescriptor from
* the Activation. We will go to the
* DD if not there. (It should always be
* there except when in a target.)
*/
td = activation.getDDLTableDescriptor();
if (td == null) {
/* tableId will be non-null if adding a
* constraint to an existing table.
*/
if (tableId != null) {
td = dd.getTableDescriptor(tableId);
} else {
td = dd.getTableDescriptor(tableName, sd, tc);
}
if (td == null) {
throw StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND_DURING_EXECUTION, tableName);
}
activation.setDDLTableDescriptor(td);
}
/* Generate the UUID for the backing index. This will become the
* constraint's name, if no name was specified.
*/
UUIDFactory uuidFactory = dd.getUUIDFactory();
UUID constrId = uuidFactory.createUUID();
/* Create the index, if there's one for this constraint */
if (indexAction != null) {
if (indexAction.getIndexName() == null) {
/* Set the index name */
backingIndexName = uuidFactory.createUUID().toString();
indexAction.setIndexName(backingIndexName);
} else {
backingIndexName = indexAction.getIndexName();
}
indexAction.setConstraintID(constrId);
/* Create the index */
indexAction.executeConstantAction(activation);
/* Get the conglomerate descriptor for the backing index */
conglomDescs = td.getConglomerateDescriptors();
for (int index = 0; index < conglomDescs.length; index++) {
conglomDesc = conglomDescs[index];
/* Check for conglomerate being an index first, since
* name is null for heap.
*/
if (conglomDesc.isIndex() && backingIndexName.equals(conglomDesc.getConglomerateName())) {
break;
}
}
if (SanityManager.DEBUG) {
SanityManager.ASSERT(conglomDesc != null, "conglomDesc is expected to be non-null after search for backing index");
SanityManager.ASSERT(conglomDesc.isIndex(), "conglomDesc is expected to be indexable after search for backing index");
SanityManager.ASSERT(conglomDesc.getConglomerateName().equals(backingIndexName), "conglomDesc name expected to be the same as backing index name after search for backing index");
}
indexId = conglomDesc.getUUID();
}
boolean[] defaults = new boolean[] { ConstraintDefinitionNode.DEFERRABLE_DEFAULT, ConstraintDefinitionNode.INITIALLY_DEFERRED_DEFAULT, ConstraintDefinitionNode.ENFORCED_DEFAULT };
for (int i = 0; i < characteristics.length; i++) {
if (characteristics[i] != defaults[i]) {
dd.checkVersion(DataDictionary.DD_VERSION_DERBY_10_11, "DEFERRED CONSTRAINTS");
if (constraintType == DataDictionary.NOTNULL_CONSTRAINT || !characteristics[2]) /* not enforced */
{
// Remove when feature DERBY-532 is completed
if (!PropertyUtil.getSystemProperty("derby.constraintsTesting", "false").equals("true")) {
throw StandardException.newException(SQLState.NOT_IMPLEMENTED, "non-default constraint characteristics");
}
}
}
}
/* Now, lets create the constraint descriptor */
DataDescriptorGenerator ddg = dd.getDataDescriptorGenerator();
switch(constraintType) {
case DataDictionary.PRIMARYKEY_CONSTRAINT:
conDesc = ddg.newPrimaryKeyConstraintDescriptor(td, constraintName, // deferable,
characteristics[0], // initiallyDeferred,
characteristics[1], // int[],
genColumnPositions(td, false), constrId, indexId, sd, characteristics[2], // referenceCount
0);
dd.addConstraintDescriptor(conDesc, tc);
break;
case DataDictionary.UNIQUE_CONSTRAINT:
conDesc = ddg.newUniqueConstraintDescriptor(td, constraintName, // deferable,
characteristics[0], // initiallyDeferred,
characteristics[1], // int[],
genColumnPositions(td, false), constrId, indexId, sd, characteristics[2], // referenceCount
0);
dd.addConstraintDescriptor(conDesc, tc);
break;
case DataDictionary.CHECK_CONSTRAINT:
conDesc = ddg.newCheckConstraintDescriptor(td, constraintName, // deferable,
characteristics[0], // initiallyDeferred,
characteristics[1], constrId, constraintText, // int[],
new ReferencedColumnsDescriptorImpl(genColumnPositions(td, false)), sd, characteristics[2]);
dd.addConstraintDescriptor(conDesc, tc);
storeConstraintDependenciesOnPrivileges(activation, conDesc, null, providerInfo);
break;
case DataDictionary.FOREIGNKEY_CONSTRAINT:
ReferencedKeyConstraintDescriptor referencedConstraint = DDUtils.locateReferencedConstraint(dd, td, constraintName, columnNames, otherConstraintInfo);
DDUtils.validateReferentialActions(dd, td, constraintName, otherConstraintInfo, columnNames);
conDesc = ddg.newForeignKeyConstraintDescriptor(td, constraintName, // deferable,
characteristics[0], // initiallyDeferred,
characteristics[1], // int[],
genColumnPositions(td, false), constrId, indexId, sd, referencedConstraint, characteristics[2], otherConstraintInfo.getReferentialActionDeleteRule(), otherConstraintInfo.getReferentialActionUpdateRule());
// try to create the constraint first, because it
// is expensive to do the bulk check, find obvious
// errors first
dd.addConstraintDescriptor(conDesc, tc);
/* No need to do check if we're creating a
* table.
*/
if ((!forCreateTable) && dd.activeConstraint(conDesc)) {
validateFKConstraint(activation, tc, dd, (ForeignKeyConstraintDescriptor) conDesc, referencedConstraint, ((CreateIndexConstantAction) indexAction).getIndexTemplateRow());
}
/* Create stored dependency on the referenced constraint */
dm.addDependency(conDesc, referencedConstraint, lcc.getContextManager());
// store constraint's dependency on REFERENCES privileges in the dependeny system
storeConstraintDependenciesOnPrivileges(activation, conDesc, referencedConstraint.getTableId(), providerInfo);
break;
case DataDictionary.MODIFY_CONSTRAINT:
throw StandardException.newException(SQLState.NOT_IMPLEMENTED, "ALTER CONSTRAINT");
default:
if (SanityManager.DEBUG) {
SanityManager.THROWASSERT("contraintType (" + constraintType + ") has unexpected value");
}
break;
}
/* Create stored dependencies for each provider */
if (providerInfo != null) {
for (int ix = 0; ix < providerInfo.length; ix++) {
Provider provider = null;
/* We should always be able to find the Provider */
provider = (Provider) providerInfo[ix].getDependableFinder().getDependable(dd, providerInfo[ix].getObjectId());
dm.addDependency(conDesc, provider, lcc.getContextManager());
}
}
/* Finally, invalidate off of the table descriptor(s)
* to ensure that any dependent statements get
* re-compiled.
*/
if (!forCreateTable) {
dm.invalidateFor(td, DependencyManager.CREATE_CONSTRAINT, lcc);
}
if (constraintType == DataDictionary.FOREIGNKEY_CONSTRAINT) {
if (SanityManager.DEBUG) {
SanityManager.ASSERT(conDesc != null, "conDesc expected to be non-null");
if (!(conDesc instanceof ForeignKeyConstraintDescriptor)) {
SanityManager.THROWASSERT("conDesc expected to be instance of ForeignKeyConstraintDescriptor, not " + conDesc.getClass().getName());
}
}
dm.invalidateFor(((ForeignKeyConstraintDescriptor) conDesc).getReferencedConstraint().getTableDescriptor(), DependencyManager.CREATE_CONSTRAINT, lcc);
}
this.constraintId = constrId;
}
use of org.apache.derby.iapi.store.access.TransactionController in project derby by apache.
the class CreateSequenceConstantAction method executeConstantAction.
// INTERFACE METHODS
/**
* This is the guts of the Execution-time logic for CREATE SEQUENCE.
*
* @throws org.apache.derby.shared.common.error.StandardException
* Thrown on failure
* @see org.apache.derby.iapi.sql.execute.ConstantAction#executeConstantAction
*/
public void executeConstantAction(Activation activation) throws StandardException {
SchemaDescriptor schemaDescriptor;
LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
DataDictionary dd = lcc.getDataDictionary();
TransactionController tc = lcc.getTransactionExecute();
DataDescriptorGenerator ddg = dd.getDataDescriptorGenerator();
dd.startWriting(lcc);
schemaDescriptor = DDLConstantAction.getSchemaDescriptorForCreate(dd, activation, _schemaName);
//
// Check if this sequence already exists. If it does, throw.
//
SequenceDescriptor seqDef = dd.getSequenceDescriptor(schemaDescriptor, _sequenceName);
if (seqDef != null) {
throw StandardException.newException(SQLState.LANG_OBJECT_ALREADY_EXISTS, seqDef.getDescriptorType(), _sequenceName);
}
seqDef = ddg.newSequenceDescriptor(schemaDescriptor, dd.getUUIDFactory().createUUID(), _sequenceName, _dataType, // current value
_initialValue, _initialValue, _minValue, _maxValue, _stepValue, // whether the sequence can wrap-around
_cycle);
dd.addDescriptor(seqDef, // parent
null, DataDictionary.SYSSEQUENCES_CATALOG_NUM, // duplicatesAllowed
false, tc);
}
use of org.apache.derby.iapi.store.access.TransactionController in project derby by apache.
the class CreateTriggerConstantAction method executeConstantAction.
/**
* This is the guts of the Execution-time logic for CREATE TRIGGER.
*
* @see ConstantAction#executeConstantAction
*
* @exception StandardException Thrown on failure
*/
public void executeConstantAction(Activation activation) throws StandardException {
SPSDescriptor whenspsd = null;
SPSDescriptor actionspsd;
LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
DataDictionary dd = lcc.getDataDictionary();
DependencyManager dm = dd.getDependencyManager();
TransactionController tc = lcc.getTransactionExecute();
/*
** Indicate that we are about to modify the data dictionary.
**
** We tell the data dictionary we're done writing at the end of
** the transaction.
*/
dd.startWriting(lcc);
SchemaDescriptor triggerSd = getSchemaDescriptorForCreate(dd, activation, triggerSchemaName);
if (spsCompSchemaId == null) {
SchemaDescriptor def = lcc.getDefaultSchema();
if (def.getUUID() == null) {
// Descriptor for default schema is stale,
// look it up in the dictionary
def = dd.getSchemaDescriptor(def.getDescriptorName(), tc, false);
}
/*
** It is possible for spsCompSchemaId to be null. For instance,
** the current schema may not have been physically created yet but
** it exists "virtually". In this case, its UUID will have the
** value of null meaning that it is not persistent. e.g.:
**
** CONNECT 'db;create=true' user 'ernie';
** CREATE TABLE bert.t1 (i INT);
** CREATE TRIGGER bert.tr1 AFTER INSERT ON bert.t1
** FOR EACH STATEMENT MODE DB2SQL
** SELECT * FROM SYS.SYSTABLES;
**
** Note that in the above case, the trigger action statement have a
** null compilation schema. A compilation schema with null value
** indicates that the trigger action statement text does not have
** any dependencies with the CURRENT SCHEMA. This means:
**
** o It is safe to compile this statement in any schema since
** there is no dependency with the CURRENT SCHEMA. i.e.: All
** relevent identifiers are qualified with a specific schema.
**
** o The statement cache mechanism can utilize this piece of
** information to enable better statement plan sharing across
** connections in different schemas; thus, avoiding unnecessary
** statement compilation.
*/
if (def != null)
spsCompSchemaId = def.getUUID();
}
String tabName;
if (triggerTable != null) {
triggerTableId = triggerTable.getUUID();
tabName = triggerTable.getName();
} else
tabName = "with UUID " + triggerTableId;
/* We need to get table descriptor again. We simply can't trust the
* one we got at compile time, the lock on system table was released
* when compile was done, and the table might well have been dropped.
*/
triggerTable = dd.getTableDescriptor(triggerTableId);
if (triggerTable == null) {
throw StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND_DURING_EXECUTION, tabName);
}
/* Lock the table for DDL. Otherwise during our execution, the table
* might be changed, even dropped. Beetle 4269
*/
lockTableForDDL(tc, triggerTable.getHeapConglomerateId(), true);
/* get triggerTable again for correctness, in case it's changed before
* the lock is aquired
*/
triggerTable = dd.getTableDescriptor(triggerTableId);
if (triggerTable == null) {
throw StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND_DURING_EXECUTION, tabName);
}
/*
** Send an invalidate on the table from which
** the triggering event emanates. This it
** to make sure that DML statements on this table
** will be recompiled. Do this before we create
** our trigger spses lest we invalidate them just
** after creating them.
*/
dm.invalidateFor(triggerTable, DependencyManager.CREATE_TRIGGER, lcc);
/*
** Lets get our trigger id up front, we'll use it when
** we create our spses.
*/
UUID tmpTriggerId = dd.getUUIDFactory().createUUID();
actionSPSId = (actionSPSId == null) ? dd.getUUIDFactory().createUUID() : actionSPSId;
if (whenSPSId == null && whenText != null) {
whenSPSId = dd.getUUIDFactory().createUUID();
}
DataDescriptorGenerator ddg = dd.getDataDescriptorGenerator();
/*
** Create the trigger descriptor first so the trigger action
** compilation can pick up the relevant trigger especially in
** the case of self triggering.
*/
TriggerDescriptor triggerd = ddg.newTriggerDescriptor(triggerSd, tmpTriggerId, triggerName, eventMask, isBefore, isRow, isEnabled, triggerTable, whenSPSId, actionSPSId, makeCreationTimestamp(dd), referencedCols, referencedColsInTriggerAction, originalActionText, referencingOld, referencingNew, oldReferencingName, newReferencingName, originalWhenText);
dd.addDescriptor(triggerd, triggerSd, DataDictionary.SYSTRIGGERS_CATALOG_NUM, false, tc);
/*
** If we have a WHEN action we create it now.
*/
if (whenText != null) {
// The WHEN clause is just a search condition and not a full
// SQL statement. Turn in into a VALUES statement.
String whenValuesStmt = "VALUES " + whenText;
whenspsd = createSPS(lcc, ddg, dd, tc, tmpTriggerId, triggerSd, whenSPSId, spsCompSchemaId, whenValuesStmt, true, triggerTable);
}
/*
** Create the trigger action
*/
actionspsd = createSPS(lcc, ddg, dd, tc, tmpTriggerId, triggerSd, actionSPSId, spsCompSchemaId, actionText, false, triggerTable);
/*
** Make underlying spses dependent on the trigger.
*/
if (whenspsd != null) {
dm.addDependency(triggerd, whenspsd, lcc.getContextManager());
}
dm.addDependency(triggerd, actionspsd, lcc.getContextManager());
dm.addDependency(triggerd, triggerTable, lcc.getContextManager());
// from the triggered statement or the WHEN clause.
for (ProviderInfo info : providerInfo) {
Provider provider = (Provider) info.getDependableFinder().getDependable(dd, info.getObjectId());
dm.addDependency(triggerd, provider, lcc.getContextManager());
}
// store trigger's dependency on various privileges in the dependeny system
storeViewTriggerDependenciesOnPrivileges(activation, triggerd);
}
Aggregations