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();
/* Remember whether or not we are doing a create table */
forCreateTable = activation.getForCreateTable();
/*
** 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);
}
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();
/* 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(); }
/* 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();
}
UUID constraintId = uuidFactory.createUUID();
/* Now, lets create the constraint descriptor */
DataDescriptorGenerator ddg = dd.getDataDescriptorGenerator();
switch (constraintType)
{
case DataDictionary.PRIMARYKEY_CONSTRAINT:
conDesc = ddg.newPrimaryKeyConstraintDescriptor(
td, constraintName,
false, //deferable,
false, //initiallyDeferred,
genColumnPositions(td, false), //int[],
constraintId,
indexId,
sd,
enabled,
0 // referenceCount
);
dd.addConstraintDescriptor(conDesc, tc);
break;
case DataDictionary.UNIQUE_CONSTRAINT:
conDesc = ddg.newUniqueConstraintDescriptor(
td, constraintName,
false, //deferable,
false, //initiallyDeferred,
genColumnPositions(td, false), //int[],
constraintId,
indexId,
sd,
enabled,
0 // referenceCount
);
dd.addConstraintDescriptor(conDesc, tc);
break;
case DataDictionary.CHECK_CONSTRAINT:
conDesc = ddg.newCheckConstraintDescriptor(
td, constraintName,
false, //deferable,
false, //initiallyDeferred,
constraintId,
constraintText,
new ReferencedColumnsDescriptorImpl(genColumnPositions(td, false)), //int[],
sd,
enabled
);
dd.addConstraintDescriptor(conDesc, tc);
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,
false, //deferable,
false, //initiallyDeferred,
genColumnPositions(td, false), //int[],
constraintId,
indexId,
sd,
referencedConstraint,
enabled,
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(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());
break;
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