use of org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor 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));
}
}
}
use of org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor in project derby by apache.
the class DMLModStatementNode method createConstraintDependencies.
/**
* Get all of our dependents due to a constraint.
*
* Makes the calling object (usually a Statement) dependent on all the constraints.
*
* @param dd The data dictionary
* @param cdl The constraint descriptor list
* @param dependent Parent object that will depend on all the constraints
* that we look up. If this argument is null, then we
* use the default dependent (the statement being compiled).
*
* @exception StandardException Thrown on failure
*/
private void createConstraintDependencies(DataDictionary dd, ConstraintDescriptorList cdl, Dependent dependent) throws StandardException {
CompilerContext compilerContext = getCompilerContext();
int cdlSize = cdl.size();
for (int index = 0; index < cdlSize; index++) {
ConstraintDescriptor cd = cdl.elementAt(index);
/*
** The dependent now depends on this constraint.
** the default dependent is the statement
** being compiled.
*/
if (dependent == null) {
compilerContext.createDependency(cd);
} else {
compilerContext.createDependency(dependent, cd);
}
/*
** We are also dependent on all referencing keys --
** if one of them is deleted, we'll have to recompile.
** Also, if there is a BULK_INSERT on the table
** we are going to scan to validate the constraint,
** the index number will change, so we'll add a
** dependency on all tables we will scan.
*/
if (cd instanceof ReferencedKeyConstraintDescriptor) {
ConstraintDescriptorList fkcdl = dd.getActiveConstraintDescriptors(((ReferencedKeyConstraintDescriptor) cd).getForeignKeyConstraints(ConstraintDescriptor.ENABLED));
int fklSize = fkcdl.size();
for (int inner = 0; inner < fklSize; inner++) {
ConstraintDescriptor fkcd = fkcdl.elementAt(inner);
if (dependent == null) {
compilerContext.createDependency(fkcd);
compilerContext.createDependency(fkcd.getTableDescriptor());
} else {
compilerContext.createDependency(dependent, fkcd);
compilerContext.createDependency(dependent, fkcd.getTableDescriptor());
}
}
} else if (cd instanceof ForeignKeyConstraintDescriptor) {
ForeignKeyConstraintDescriptor fkcd = (ForeignKeyConstraintDescriptor) cd;
if (dependent == null) {
compilerContext.createDependency(fkcd.getReferencedConstraint().getTableDescriptor());
} else {
compilerContext.createDependency(dependent, fkcd.getReferencedConstraint().getTableDescriptor());
}
}
}
}
use of org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor 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.ConstraintDescriptor in project derby by apache.
the class DataDictionaryImpl method dropAllConstraintDescriptors.
/**
* Drops all ConstraintDescriptors from the data dictionary
* that are associated with the given table,
*
* @param table The table from which to drop all
* constraint descriptors
* @param tc The TransactionController
*
* @exception StandardException Thrown on error
*/
public void dropAllConstraintDescriptors(TableDescriptor table, TransactionController tc) throws StandardException {
ConstraintDescriptorList cdl = getConstraintDescriptors(table);
// Walk the table's CDL and drop each ConstraintDescriptor.
for (Iterator iterator = cdl.iterator(); iterator.hasNext(); ) {
ConstraintDescriptor cd = (ConstraintDescriptor) iterator.next();
dropConstraintDescriptor(cd, tc);
}
/*
** Null out the table's constraint descriptor list. NOTE: This is
** not really necessary at the time of this writing (11/3/97), because
** we do not cache data dictionary objects while DDL is going on,
** but in the future it might be necessary.
*/
table.setConstraintDescriptorList(null);
}
Aggregations