use of org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList in project derby by apache.
the class DropConstraintConstantAction method executeConstantAction.
// INTERFACE METHODS
/**
* This is the guts of the Execution-time logic for DROP CONSTRAINT.
*
* @see ConstantAction#executeConstantAction
*
* @exception StandardException Thrown on failure
*/
public void executeConstantAction(Activation activation) throws StandardException {
ConstraintDescriptor conDesc = null;
TableDescriptor td;
UUID indexId = null;
String indexUUIDString;
LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
DataDictionary dd = lcc.getDataDictionary();
DependencyManager dm = dd.getDependencyManager();
TransactionController tc = lcc.getTransactionExecute();
/*
** 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);
td = dd.getTableDescriptor(tableId);
if (td == null) {
throw StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND_DURING_EXECUTION, tableName);
}
/* 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 tdSd = td.getSchemaDescriptor();
SchemaDescriptor constraintSd = constraintSchemaName == null ? tdSd : dd.getSchemaDescriptor(constraintSchemaName, tc, true);
/* Get the constraint descriptor for the index, along
* with an exclusive row lock on the row in sys.sysconstraints
* in order to ensure that no one else compiles against the
* index.
*/
if (// this means "alter table drop primary key"
constraintName == null)
conDesc = dd.getConstraintDescriptors(td).getPrimaryKey();
else
conDesc = dd.getConstraintDescriptorByName(td, constraintSd, constraintName, true);
// Error if constraint doesn't exist
if (conDesc == null) {
String errorName = constraintName == null ? "PRIMARY KEY" : (constraintSd.getSchemaName() + "." + constraintName);
throw StandardException.newException(SQLState.LANG_DROP_OR_ALTER_NON_EXISTING_CONSTRAINT, errorName, td.getQualifiedName());
}
switch(verifyType) {
case DataDictionary.UNIQUE_CONSTRAINT:
if (conDesc.getConstraintType() != verifyType)
throw StandardException.newException(SQLState.LANG_DROP_CONSTRAINT_TYPE, constraintName, "UNIQUE");
break;
case DataDictionary.CHECK_CONSTRAINT:
if (conDesc.getConstraintType() != verifyType)
throw StandardException.newException(SQLState.LANG_DROP_CONSTRAINT_TYPE, constraintName, "CHECK");
break;
case DataDictionary.FOREIGNKEY_CONSTRAINT:
if (conDesc.getConstraintType() != verifyType)
throw StandardException.newException(SQLState.LANG_DROP_CONSTRAINT_TYPE, constraintName, "FOREIGN KEY");
break;
}
boolean cascadeOnRefKey = (cascade && conDesc instanceof ReferencedKeyConstraintDescriptor);
if (!cascadeOnRefKey) {
dm.invalidateFor(conDesc, DependencyManager.DROP_CONSTRAINT, lcc);
}
/*
** If we had a primary/unique key and it is drop cascade,
** drop all the referencing keys now. We MUST do this AFTER
** dropping the referenced key because otherwise we would
** be repeatedly changing the reference count of the referenced
** key and generating unnecessary I/O.
*/
dropConstraint(conDesc, activation, lcc, !cascadeOnRefKey);
if (cascadeOnRefKey) {
ForeignKeyConstraintDescriptor fkcd;
ReferencedKeyConstraintDescriptor cd;
ConstraintDescriptorList cdl;
cd = (ReferencedKeyConstraintDescriptor) conDesc;
cdl = cd.getForeignKeyConstraints(ReferencedKeyConstraintDescriptor.ALL);
int cdlSize = cdl.size();
for (int index = 0; index < cdlSize; index++) {
fkcd = (ForeignKeyConstraintDescriptor) cdl.elementAt(index);
dm.invalidateFor(fkcd, DependencyManager.DROP_CONSTRAINT, lcc);
dropConstraint(fkcd, activation, lcc, true);
}
/*
** We told dropConstraintAndIndex not to
** remove our dependencies, so send an invalidate,
** and drop the dependencies.
*/
dm.invalidateFor(conDesc, DependencyManager.DROP_CONSTRAINT, lcc);
dm.clearDependencies(lcc, conDesc);
}
}
use of org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList in project derby by apache.
the class UpdateNode method getReadMap.
/**
* Gets the map of all columns which must be read out of the base table.
* These are the columns needed to<UL>:
* <LI>maintain indices</LI>
* <LI>maintain foreign keys</LI>
* <LI>maintain generated columns</LI>
* <LI>support Replication's Delta Optimization</LI></UL>
* <p>
* The returned map is a FormatableBitSet with 1 bit for each column in the
* table plus an extra, unsued 0-bit. If a 1-based column id must
* be read from the base table, then the corresponding 1-based bit
* is turned ON in the returned FormatableBitSet.
* <p>
* <B>NOTE</B>: this method is not expected to be called when
* all columns are being updated (i.e. updateColumnList is null).
*
* @param dd the data dictionary to look in
* @param baseTable the base table descriptor
* @param updateColumnList the rcl for the update. CANNOT BE NULL
* @param affectedGeneratedColumns columns whose generation clauses mention columns being updated
*
* @return a FormatableBitSet of columns to be read out of the base table
*
* @exception StandardException Thrown on error
*/
FormatableBitSet getReadMap(DataDictionary dd, TableDescriptor baseTable, ResultColumnList updateColumnList, ColumnDescriptorList affectedGeneratedColumns) throws StandardException {
boolean[] needsDeferredProcessing = new boolean[1];
needsDeferredProcessing[0] = requiresDeferredProcessing();
ArrayList<ConglomerateDescriptor> conglomerates = new ArrayList<ConglomerateDescriptor>();
relevantCdl = new ConstraintDescriptorList();
relevantTriggers = new TriggerDescriptorList();
FormatableBitSet columnMap = getUpdateReadMap(dd, baseTable, updateColumnList, conglomerates, relevantCdl, relevantTriggers, needsDeferredProcessing, affectedGeneratedColumns);
markAffectedIndexes(conglomerates);
adjustDeferredFlag(needsDeferredProcessing[0]);
return columnMap;
}
use of org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList in project derby by apache.
the class RenameNode method renameTableBind.
// do any checking needs to be done at bind time for rename table
private void renameTableBind(DataDictionary dd) throws StandardException {
/* Verify that there are no check constraints on the table */
ConstraintDescriptorList constraintDescriptorList = dd.getConstraintDescriptors(td);
int size = constraintDescriptorList == null ? 0 : constraintDescriptorList.size();
ConstraintDescriptor constraintDescriptor;
// go through all the constraints defined on the table
for (int index = 0; index < size; index++) {
constraintDescriptor = constraintDescriptorList.elementAt(index);
// if it is a check constraint, error
if (constraintDescriptor.getConstraintType() == DataDictionary.CHECK_CONSTRAINT) {
throw StandardException.newException(SQLState.LANG_PROVIDER_HAS_DEPENDENT_OBJECT, "RENAME", td.getName(), "CONSTRAINT", constraintDescriptor.getConstraintName());
}
}
}
use of org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList in project derby by apache.
the class AlterTableNode method prepConstantAction.
/**
* Generate arguments to constant action. Called by makeConstantAction() in this class and in
* our subclass RepAlterTableNode.
*
* @exception StandardException Thrown on failure
*/
private void prepConstantAction() throws StandardException {
if (tableElementList != null) {
genColumnInfo();
}
if (numConstraints > 0) {
conActions = new ConstraintConstantAction[numConstraints];
tableElementList.genConstraintActions(false, conActions, getRelativeName(), schemaDescriptor, getDataDictionary());
for (int conIndex = 0; conIndex < conActions.length; conIndex++) {
ConstraintConstantAction cca = conActions[conIndex];
if (cca instanceof CreateConstraintConstantAction) {
int constraintType = cca.getConstraintType();
if (constraintType == DataDictionary.PRIMARYKEY_CONSTRAINT) {
DataDictionary dd = getDataDictionary();
// Check to see if a constraint of the same type
// already exists
ConstraintDescriptorList cdl = dd.getConstraintDescriptors(baseTable);
if (cdl.getPrimaryKey() != null) {
throw StandardException.newException(SQLState.LANG_ADD_PRIMARY_KEY_FAILED1, baseTable.getQualifiedName());
}
}
}
}
}
}
use of org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList in project derby by apache.
the class DMLModStatementNode method generateFKInfo.
/**
* Generate the FKInfo structures used during code generation.
* For each constraint that isn't a check constraint, add another
* one of these FKInfo structures and then package them up into
* a single array.
*
* @param cdl The constraint descriptor list
* @param dd The DataDictionary
* @param td The TableDescriptor
* @param readColsBitSet columns read
*
* @exception StandardException Thrown on failure
*/
private void generateFKInfo(ConstraintDescriptorList cdl, DataDictionary dd, TableDescriptor td, FormatableBitSet readColsBitSet) throws StandardException {
ArrayList<FKInfo> fkList = new ArrayList<FKInfo>();
int type;
UUID[] uuids;
long[] conglomNumbers;
String[] fkNames;
ConstraintDescriptorList fkcdl;
ReferencedKeyConstraintDescriptor refcd;
boolean[] isSelfReferencingFK;
ConstraintDescriptorList activeList = dd.getActiveConstraintDescriptors(cdl);
int[] rowMap = getRowMap(readColsBitSet, td);
int[] raRules;
boolean[] deferrable;
UUID[] fkIds;
ArrayList<String> refSchemaNames = new ArrayList<String>(1);
ArrayList<String> refTableNames = new ArrayList<String>(1);
ArrayList<Long> refIndexConglomNum = new ArrayList<Long>(1);
ArrayList<Integer> refActions = new ArrayList<Integer>(1);
ArrayList<ColumnDescriptorList> refColDescriptors = new ArrayList<ColumnDescriptorList>(1);
ArrayList<int[]> fkColMap = new ArrayList<int[]>(1);
int activeSize = activeList.size();
for (int index = 0; index < activeSize; index++) {
ConstraintDescriptor cd = activeList.elementAt(index);
if (cd instanceof ForeignKeyConstraintDescriptor) {
/*
** We are saving information for checking the
** primary/unique key that is referenced by this
** foreign key, so type is FOREIGN KEY.
*/
type = FKInfo.FOREIGN_KEY;
refcd = ((ForeignKeyConstraintDescriptor) cd).getReferencedConstraint();
uuids = new UUID[1];
deferrable = new boolean[1];
fkIds = new UUID[1];
conglomNumbers = new long[1];
fkNames = new String[1];
isSelfReferencingFK = new boolean[1];
raRules = new int[1];
fkSetupArrays(dd, (ForeignKeyConstraintDescriptor) cd, 0, uuids, conglomNumbers, fkNames, isSelfReferencingFK, raRules, deferrable, fkIds);
// oops, get the right constraint name -- for error
// handling we want the FK name, not refcd name
fkNames[0] = cd.getConstraintName();
} else if (cd instanceof ReferencedKeyConstraintDescriptor) {
refcd = (ReferencedKeyConstraintDescriptor) cd;
/*
** We are saving information for checking the
** foreign key(s) that is dependent on this referenced
** key, so type is REFERENCED KEY.
*/
type = FKInfo.REFERENCED_KEY;
fkcdl = dd.getActiveConstraintDescriptors(((ReferencedKeyConstraintDescriptor) cd).getForeignKeyConstraints(ConstraintDescriptor.ENABLED));
int size = fkcdl.size();
if (size == 0) {
continue;
}
uuids = new UUID[size];
deferrable = new boolean[size];
fkIds = new UUID[size];
fkNames = new String[size];
conglomNumbers = new long[size];
isSelfReferencingFK = new boolean[size];
raRules = new int[size];
TableDescriptor fktd;
ColumnDescriptorList coldl;
int[] refColumns;
ColumnDescriptor cold;
int[] colArray = remapReferencedColumns(cd, rowMap);
for (int inner = 0; inner < size; inner++) {
ForeignKeyConstraintDescriptor fkcd = (ForeignKeyConstraintDescriptor) fkcdl.elementAt(inner);
fkSetupArrays(dd, fkcd, inner, uuids, conglomNumbers, fkNames, isSelfReferencingFK, raRules, deferrable, fkIds);
if ((raRules[inner] == StatementType.RA_CASCADE) || (raRules[inner] == StatementType.RA_SETNULL)) {
// find the referencing table Name
fktd = fkcd.getTableDescriptor();
refSchemaNames.add(fktd.getSchemaName());
refTableNames.add(fktd.getName());
refActions.add(Integer.valueOf(raRules[inner]));
// find the referencing column name required for update null.
refColumns = fkcd.getReferencedColumns();
coldl = fktd.getColumnDescriptorList();
ColumnDescriptorList releventColDes = new ColumnDescriptorList();
for (int i = 0; i < refColumns.length; i++) {
cold = coldl.elementAt(refColumns[i] - 1);
releventColDes.add(cold);
}
refColDescriptors.add(releventColDes);
refIndexConglomNum.add(Long.valueOf(conglomNumbers[inner]));
fkColMap.add(colArray);
}
}
} else {
continue;
}
final TableDescriptor pktd = refcd.getTableDescriptor();
final UUID pkIndexId = refcd.getIndexId();
final ConglomerateDescriptor pkIndexConglom = pktd.getConglomerateDescriptor(pkIndexId);
final TableDescriptor refTd = cd.getTableDescriptor();
fkList.add(new FKInfo(// foreign key names
fkNames, cd.getSchemaDescriptor().getSchemaName(), // table being modified
refTd.getName(), // INSERT|UPDATE|DELETE
statementType, // FOREIGN_KEY|REFERENCED_KEY
type, // referenced backing index uuid
pkIndexId, pkIndexConglom.getConglomerateNumber(), // referenced backing index conglom
refcd.getUUID(), // referenced constraint is
refcd.deferrable(), // fk backing index uuids
uuids, // fk backing index congloms
conglomNumbers, // is self ref array of bool
isSelfReferencingFK, remapReferencedColumns(cd, rowMap), // columns referenced by key
dd.getRowLocationTemplate(getLanguageConnectionContext(), refTd), // referential action rules
raRules, // deferrable flags
deferrable, // UUID of fks
fkIds));
}
// Now convert the list into an array.
if (!fkList.isEmpty()) {
fkInfo = fkList.toArray(new FKInfo[fkList.size()]);
}
// Convert the ref action info lists to arrays.
int size = refActions.size();
if (size > 0) {
fkTableNames = new String[size];
fkSchemaNames = new String[size];
fkRefActions = new int[size];
fkColDescriptors = new ColumnDescriptorList[size];
fkIndexConglomNumbers = new long[size];
fkColArrays = new int[size][];
for (int i = 0; i < size; i++) {
fkTableNames[i] = refTableNames.get(i);
fkSchemaNames[i] = refSchemaNames.get(i);
fkRefActions[i] = (refActions.get(i)).intValue();
fkColDescriptors[i] = refColDescriptors.get(i);
fkIndexConglomNumbers[i] = (refIndexConglomNum.get(i)).longValue();
fkColArrays[i] = (fkColMap.get(i));
}
}
}
Aggregations