use of org.apache.derby.iapi.sql.dictionary.ColumnDescriptor in project derby by apache.
the class ResultColumnList method bindResultColumnsByName.
/**
* Bind the result columns by their names. This is useful for update
* VTI statements, and for INSERT statements like "insert into new t() (a, b, c)
* values (1, 2, 3)" where the user specified a column list.
* Also, verify that the result column list does not contain any duplicates.
* NOTE: We pass the ResultColumns position in the ResultColumnList so
* that the VirtualColumnId gets set.
*
* @param fullRCL The full RCL for the target table
* @param statement DMLStatementNode containing this list
*
* @exception StandardException Thrown on error
*/
void bindResultColumnsByName(ResultColumnList fullRCL, FromVTI targetVTI, DMLStatementNode statement) throws StandardException {
int size = size();
HashSet<String> seenNames = new HashSet<String>(size + 2, 0.999f);
for (int index = 0; index < size; index++) {
ResultColumn matchRC;
ResultColumn rc = elementAt(index);
/* Verify that this column's name is unique within the list */
String colName = rc.getName();
boolean alreadySeen = !seenNames.add(colName);
if (alreadySeen) {
if (SanityManager.DEBUG) {
SanityManager.ASSERT((statement instanceof UpdateNode) || (statement instanceof InsertNode), "statement is expected to be instanceof UpdateNode or InsertNode");
}
if (statement instanceof UpdateNode) {
throw StandardException.newException(SQLState.LANG_DUPLICATE_COLUMN_NAME_UPDATE, colName);
} else {
throw StandardException.newException(SQLState.LANG_DUPLICATE_COLUMN_NAME_INSERT, colName);
}
}
matchRC = fullRCL.getResultColumn(null, rc.getName());
if (matchRC == null) {
throw StandardException.newException(SQLState.LANG_COLUMN_NOT_FOUND_IN_TABLE, rc.getName(), targetVTI.getMethodCall().getJavaClassName());
}
/* We have a match. We need to create a dummy ColumnDescriptor
* since calling code expects one to get column info.
*/
ColumnDescriptor cd = new ColumnDescriptor(rc.getName(), matchRC.getVirtualColumnId(), matchRC.getType(), null, null, (TableDescriptor) null, null, 0, 0, false);
rc.setColumnDescriptor(null, cd);
rc.setVirtualColumnId(index + 1);
}
}
use of org.apache.derby.iapi.sql.dictionary.ColumnDescriptor in project derby by apache.
the class SYSCOLUMNSRowFactory method buildDescriptor.
// /////////////////////////////////////////////////////////////////////////
//
// ABSTRACT METHODS TO BE IMPLEMENTED BY CHILDREN OF CatalogRowFactory
//
// /////////////////////////////////////////////////////////////////////////
/**
* Make a ColumnDescriptor out of a SYSCOLUMNS row
*
* @param row a SYSCOLUMNS row
* @param parentTupleDescriptor The UniqueTupleDescriptor for the object that is tied
* to this column
* @param dd dataDictionary
*
* @return a column descriptor equivalent to a SYSCOLUMNS row
*
* @exception StandardException thrown on failure
*/
public TupleDescriptor buildDescriptor(ExecRow row, TupleDescriptor parentTupleDescriptor, DataDictionary dd) throws StandardException {
if (SanityManager.DEBUG) {
int expectedCols = dd.checkVersion(DataDictionary.DD_VERSION_DERBY_10_14, null) ? SYSCOLUMNS_COLUMN_COUNT : (SYSCOLUMNS_COLUMN_COUNT - 1);
SanityManager.ASSERT(row.nColumns() == expectedCols, "Wrong number of columns for a SYSCOLUMNS row");
}
int columnNumber;
String columnName;
String defaultID;
DefaultInfoImpl defaultInfo = null;
ColumnDescriptor colDesc;
DataValueDescriptor defaultValue = null;
UUID defaultUUID = null;
UUID uuid = null;
UUIDFactory uuidFactory = getUUIDFactory();
long autoincStart, autoincInc, autoincValue;
boolean autoincCycle = false;
DataDescriptorGenerator ddg = dd.getDataDescriptorGenerator();
/*
** We're going to be getting the UUID for this sucka
** so make sure it is a UniqueTupleDescriptor.
*/
if (parentTupleDescriptor != null) {
if (SanityManager.DEBUG) {
if (!(parentTupleDescriptor instanceof UniqueTupleDescriptor)) {
SanityManager.THROWASSERT(parentTupleDescriptor.getClass().getName() + " not instanceof UniqueTupleDescriptor");
}
}
uuid = ((UniqueTupleDescriptor) parentTupleDescriptor).getUUID();
} else {
/* 1st column is REFERENCEID (char(36)) */
uuid = uuidFactory.recreateUUID(row.getColumn(SYSCOLUMNS_REFERENCEID).getString());
}
/* NOTE: We get columns 5 and 6 next in order to work around
* a 1.3.0 HotSpot bug. (#4361550)
*/
// 5th column is COLUMNDEFAULT (serialiazable)
Object object = row.getColumn(SYSCOLUMNS_COLUMNDEFAULT).getObject();
if (object instanceof DataValueDescriptor) {
defaultValue = (DataValueDescriptor) object;
} else if (object instanceof DefaultInfoImpl) {
defaultInfo = (DefaultInfoImpl) object;
defaultValue = defaultInfo.getDefaultValue();
}
/* 6th column is DEFAULTID (char(36)) */
defaultID = row.getColumn(SYSCOLUMNS_COLUMNDEFAULTID).getString();
if (defaultID != null) {
defaultUUID = uuidFactory.recreateUUID(defaultID);
}
/* 2nd column is COLUMNNAME (varchar(128)) */
columnName = row.getColumn(SYSCOLUMNS_COLUMNNAME).getString();
/* 3rd column is COLUMNNUMBER (int) */
columnNumber = row.getColumn(SYSCOLUMNS_COLUMNNUMBER).getInt();
/* 4th column is COLUMNDATATYPE */
/*
** What is stored in the column is a TypeDescriptorImpl, which
** points to a BaseTypeIdImpl. These are simple types that are
** intended to be movable to the client, so they don't have
** the entire implementation. We need to wrap them in DataTypeServices
** and TypeId objects that contain the full implementations for
** language processing.
*/
TypeDescriptor catalogType = (TypeDescriptor) row.getColumn(SYSCOLUMNS_COLUMNDATATYPE).getObject();
DataTypeDescriptor dataTypeServices = DataTypeDescriptor.getType(catalogType);
/* 7th column is AUTOINCREMENTVALUE (long) */
autoincValue = row.getColumn(SYSCOLUMNS_AUTOINCREMENTVALUE).getLong();
/* 8th column is AUTOINCREMENTSTART (long) */
autoincStart = row.getColumn(SYSCOLUMNS_AUTOINCREMENTSTART).getLong();
/* 9th column is AUTOINCREMENTINC (long) */
autoincInc = row.getColumn(SYSCOLUMNS_AUTOINCREMENTINC).getLong();
if (row.nColumns() >= 10) {
DataValueDescriptor col = row.getColumn(SYSCOLUMNS_AUTOINCREMENTINCCYCLE);
autoincCycle = col.getBoolean();
}
DataValueDescriptor col = row.getColumn(SYSCOLUMNS_AUTOINCREMENTSTART);
autoincStart = col.getLong();
col = row.getColumn(SYSCOLUMNS_AUTOINCREMENTINC);
autoincInc = col.getLong();
// Hard upgraded tables <=10.13 come with a false autoincCyle before they are first
// explicitly set with cycle or no cycle command.
colDesc = new ColumnDescriptor(columnName, columnNumber, dataTypeServices, defaultValue, defaultInfo, uuid, defaultUUID, autoincStart, autoincInc, autoincValue, autoincCycle);
return colDesc;
}
use of org.apache.derby.iapi.sql.dictionary.ColumnDescriptor in project derby by apache.
the class AlterTableConstantAction method dropColumnFromTable.
/**
* Workhorse for dropping a column from a table.
*
* This routine drops a column from a table, taking care
* to properly handle the various related schema objects.
*
* The syntax which gets you here is:
*
* ALTER TABLE tbl DROP [COLUMN] col [CASCADE|RESTRICT]
*
* The keyword COLUMN is optional, and if you don't
* specify CASCADE or RESTRICT, the default is CASCADE
* (the default is chosen in the parser, not here).
*
* If you specify RESTRICT, then the column drop should be
* rejected if it would cause a dependent schema object
* to become invalid.
*
* If you specify CASCADE, then the column drop should
* additionally drop other schema objects which have
* become invalid.
*
* You may not drop the last (only) column in a table.
*
* Schema objects of interest include:
* - views
* - triggers
* - constraints
* - check constraints
* - primary key constraints
* - foreign key constraints
* - unique key constraints
* - not null constraints
* - privileges
* - indexes
* - default values
*
* Dropping a column may also change the column position
* numbers of other columns in the table, which may require
* fixup of schema objects (such as triggers and column
* privileges) which refer to columns by column position number.
*
* Indexes are a bit interesting. The official SQL spec
* doesn't talk about indexes; they are considered to be
* an imlementation-specific performance optimization.
* The current Derby behavior is that:
* - CASCADE/RESTRICT doesn't matter for indexes
* - when a column is dropped, it is removed from any indexes
* which contain it.
* - if that column was the only column in the index, the
* entire index is dropped.
*
* @param columnName the name of the column specfication in the ALTER
* statement-- currently we allow only one.
* @exception StandardException thrown on failure.
*/
private void dropColumnFromTable(String columnName) throws StandardException {
boolean cascade = (behavior == StatementType.DROP_CASCADE);
// drop any generated columns which reference this column
ColumnDescriptorList generatedColumnList = td.getGeneratedColumns();
int generatedColumnCount = generatedColumnList.size();
ArrayList<String> cascadedDroppedColumns = new ArrayList<String>();
for (int i = 0; i < generatedColumnCount; i++) {
ColumnDescriptor generatedColumn = generatedColumnList.elementAt(i);
String[] referencedColumnNames = generatedColumn.getDefaultInfo().getReferencedColumnNames();
int referencedColumnCount = referencedColumnNames.length;
for (int j = 0; j < referencedColumnCount; j++) {
if (columnName.equals(referencedColumnNames[j])) {
String generatedColumnName = generatedColumn.getColumnName();
// we're trying to drop
if (!cascade) {
//
throw StandardException.newException(SQLState.LANG_PROVIDER_HAS_DEPENDENT_OBJECT, dm.getActionString(DependencyManager.DROP_COLUMN), columnName, "GENERATED COLUMN", generatedColumnName);
} else {
cascadedDroppedColumns.add(generatedColumnName);
}
}
}
}
DataDescriptorGenerator ddg = dd.getDataDescriptorGenerator();
int cascadedDrops = cascadedDroppedColumns.size();
int sizeAfterCascadedDrops = td.getColumnDescriptorList().size() - cascadedDrops;
// can NOT drop a column if it is the only one in the table
if (sizeAfterCascadedDrops == 1) {
throw StandardException.newException(SQLState.LANG_PROVIDER_HAS_DEPENDENT_OBJECT, dm.getActionString(DependencyManager.DROP_COLUMN), "THE *LAST* COLUMN " + columnName, "TABLE", td.getQualifiedName());
}
// now drop dependent generated columns
for (int i = 0; i < cascadedDrops; i++) {
String generatedColumnName = cascadedDroppedColumns.get(i);
activation.addWarning(StandardException.newWarning(SQLState.LANG_GEN_COL_DROPPED, generatedColumnName, td.getName()));
//
// We can only recurse 2 levels since a generation clause cannot
// refer to other generated columns.
//
dropColumnFromTable(generatedColumnName);
}
/*
* Cascaded drops of dependent generated columns may require us to
* rebuild the table descriptor.
*/
td = dd.getTableDescriptor(tableId);
ColumnDescriptor columnDescriptor = td.getColumnDescriptor(columnName);
// We already verified this in bind, but do it again
if (columnDescriptor == null) {
throw StandardException.newException(SQLState.LANG_COLUMN_NOT_FOUND_IN_TABLE, columnName, td.getQualifiedName());
}
int size = td.getColumnDescriptorList().size();
droppedColumnPosition = columnDescriptor.getPosition();
FormatableBitSet toDrop = new FormatableBitSet(size + 1);
toDrop.set(droppedColumnPosition);
td.setReferencedColumnMap(toDrop);
dm.invalidateFor(td, (cascade ? DependencyManager.DROP_COLUMN : DependencyManager.DROP_COLUMN_RESTRICT), lcc);
// If column has a default we drop the default and any dependencies
if (columnDescriptor.getDefaultInfo() != null) {
dm.clearDependencies(lcc, columnDescriptor.getDefaultDescriptor(dd));
}
// then we need to drop the system-generated sequence backing it.
if (columnDescriptor.isAutoincrement() && dd.checkVersion(DataDictionary.DD_VERSION_DERBY_10_11, null)) {
DropTableConstantAction.dropIdentitySequence(dd, td, activation);
}
// columns which are used through REFERENCING clause
for (TriggerDescriptor trd : dd.getTriggerDescriptors(td)) {
// If we find that the trigger is dependent on the column being
// dropped because column is part of trigger columns list, then
// we will give a warning or drop the trigger based on whether
// ALTER TABLE DROP COLUMN is RESTRICT or CASCADE. In such a
// case, no need to check if the trigger action columns referenced
// through REFERENCING clause also used the column being dropped.
boolean triggerDroppedAlready = false;
int[] referencedCols = trd.getReferencedCols();
if (referencedCols != null) {
int refColLen = referencedCols.length, j;
boolean changed = false;
for (j = 0; j < refColLen; j++) {
if (referencedCols[j] > droppedColumnPosition) {
// Trigger is not defined on the column being dropped
// but the column position of trigger column is changing
// because the position of the column being dropped is
// before the the trigger column
changed = true;
} else if (referencedCols[j] == droppedColumnPosition) {
// the trigger is defined on the column being dropped
if (cascade) {
trd.drop(lcc);
triggerDroppedAlready = true;
activation.addWarning(StandardException.newWarning(SQLState.LANG_TRIGGER_DROPPED, trd.getName(), td.getName()));
} else {
// otherwsie there would be unexpected behaviors
throw StandardException.newException(SQLState.LANG_PROVIDER_HAS_DEPENDENT_OBJECT, dm.getActionString(DependencyManager.DROP_COLUMN), columnName, "TRIGGER", trd.getName());
}
break;
}
}
// drop column.
if (j == refColLen && changed) {
dd.dropTriggerDescriptor(trd, tc);
for (j = 0; j < refColLen; j++) {
if (referencedCols[j] > droppedColumnPosition)
referencedCols[j]--;
}
trd.setReferencedCols(referencedCols);
dd.addDescriptor(trd, sd, DataDictionary.SYSTRIGGERS_CATALOG_NUM, false, tc);
}
}
// loop above, then move to next trigger
if (triggerDroppedAlready)
continue;
// Column being dropped is not one of trigger columns. Check if
// that column is getting used inside the trigger action through
// REFERENCING clause. This can be tracked only for triggers
// created in 10.7 and higher releases. Derby releases prior to
// that did not keep track of trigger action columns used
// through the REFERENCING clause.
int[] referencedColsInTriggerAction = trd.getReferencedColsInTriggerAction();
if (referencedColsInTriggerAction != null) {
int refColInTriggerActionLen = referencedColsInTriggerAction.length, j;
boolean changedColPositionInTriggerAction = false;
for (j = 0; j < refColInTriggerActionLen; j++) {
if (referencedColsInTriggerAction[j] > droppedColumnPosition) {
changedColPositionInTriggerAction = true;
} else if (referencedColsInTriggerAction[j] == droppedColumnPosition) {
if (cascade) {
trd.drop(lcc);
triggerDroppedAlready = true;
activation.addWarning(StandardException.newWarning(SQLState.LANG_TRIGGER_DROPPED, trd.getName(), td.getName()));
} else {
// we'd better give an error if don't drop it,
throw StandardException.newException(SQLState.LANG_PROVIDER_HAS_DEPENDENT_OBJECT, dm.getActionString(DependencyManager.DROP_COLUMN), columnName, "TRIGGER", trd.getName());
}
break;
}
}
// column has been actually dropped from the table descriptor.
if (j == refColInTriggerActionLen && changedColPositionInTriggerAction) {
dd.dropTriggerDescriptor(trd, tc);
for (j = 0; j < refColInTriggerActionLen; j++) {
if (referencedColsInTriggerAction[j] > droppedColumnPosition)
referencedColsInTriggerAction[j]--;
}
trd.setReferencedColsInTriggerAction(referencedColsInTriggerAction);
dd.addDescriptor(trd, sd, DataDictionary.SYSTRIGGERS_CATALOG_NUM, false, tc);
}
}
}
ConstraintDescriptorList csdl = dd.getConstraintDescriptors(td);
int csdl_size = csdl.size();
ArrayList<ConstantAction> newCongloms = new ArrayList<ConstantAction>();
// we want to remove referenced primary/unique keys in the second
// round. This will ensure that self-referential constraints will
// work OK.
int tbr_size = 0;
ConstraintDescriptor[] toBeRemoved = new ConstraintDescriptor[csdl_size];
// let's go downwards, don't want to get messed up while removing
for (int i = csdl_size - 1; i >= 0; i--) {
ConstraintDescriptor cd = csdl.elementAt(i);
int[] referencedColumns = cd.getReferencedColumns();
int numRefCols = referencedColumns.length, j;
boolean changed = false;
for (j = 0; j < numRefCols; j++) {
if (referencedColumns[j] > droppedColumnPosition)
changed = true;
if (referencedColumns[j] == droppedColumnPosition)
break;
}
if (// column not referenced
j == numRefCols) {
if ((cd instanceof CheckConstraintDescriptor) && changed) {
dd.dropConstraintDescriptor(cd, tc);
for (j = 0; j < numRefCols; j++) {
if (referencedColumns[j] > droppedColumnPosition)
referencedColumns[j]--;
}
((CheckConstraintDescriptor) cd).setReferencedColumnsDescriptor(new ReferencedColumnsDescriptorImpl(referencedColumns));
dd.addConstraintDescriptor(cd, tc);
}
continue;
}
if (!cascade) {
//
throw StandardException.newException(SQLState.LANG_PROVIDER_HAS_DEPENDENT_OBJECT, dm.getActionString(DependencyManager.DROP_COLUMN), columnName, "CONSTRAINT", cd.getConstraintName());
}
if (cd instanceof ReferencedKeyConstraintDescriptor) {
// restrict will raise an error in invalidate if referenced
toBeRemoved[tbr_size++] = cd;
continue;
}
// drop now in all other cases
dm.invalidateFor(cd, DependencyManager.DROP_CONSTRAINT, lcc);
dropConstraint(cd, td, newCongloms, activation, lcc, true);
activation.addWarning(StandardException.newWarning(SQLState.LANG_CONSTRAINT_DROPPED, cd.getConstraintName(), td.getName()));
}
for (int i = tbr_size - 1; i >= 0; i--) {
ConstraintDescriptor cd = toBeRemoved[i];
dropConstraint(cd, td, newCongloms, activation, lcc, false);
activation.addWarning(StandardException.newWarning(SQLState.LANG_CONSTRAINT_DROPPED, cd.getConstraintName(), td.getName()));
if (cascade) {
ConstraintDescriptorList fkcdl = dd.getForeignKeys(cd.getUUID());
for (ConstraintDescriptor fkcd : fkcdl) {
dm.invalidateFor(fkcd, DependencyManager.DROP_CONSTRAINT, lcc);
dropConstraint(fkcd, td, newCongloms, activation, lcc, true);
activation.addWarning(StandardException.newWarning(SQLState.LANG_CONSTRAINT_DROPPED, fkcd.getConstraintName(), fkcd.getTableDescriptor().getName()));
}
}
dm.invalidateFor(cd, DependencyManager.DROP_CONSTRAINT, lcc);
dm.clearDependencies(lcc, cd);
}
/* If there are new backing conglomerates which must be
* created to replace a dropped shared conglomerate
* (where the shared conglomerate was dropped as part
* of a "drop constraint" call above), then create them
* now. We do this *after* dropping all dependent
* constraints because we don't want to waste time
* creating a new conglomerate if it's just going to be
* dropped again as part of another "drop constraint".
*/
createNewBackingCongloms(newCongloms, (long[]) null);
/*
* The work we've done above, specifically the possible
* dropping of primary key, foreign key, and unique constraints
* and their underlying indexes, may have affected the table
* descriptor. By re-reading the table descriptor here, we
* ensure that the compressTable code is working with an
* accurate table descriptor. Without this line, we may get
* conglomerate-not-found errors and the like due to our
* stale table descriptor.
*/
td = dd.getTableDescriptor(tableId);
compressTable();
ColumnDescriptorList tab_cdl = td.getColumnDescriptorList();
// drop the column from syscolumns
dd.dropColumnDescriptor(td.getUUID(), columnName, tc);
ColumnDescriptor[] cdlArray = new ColumnDescriptor[size - columnDescriptor.getPosition()];
//
for (int i = columnDescriptor.getPosition(), j = 0; i < size; i++, j++) {
ColumnDescriptor cd = tab_cdl.elementAt(i);
dd.dropColumnDescriptor(td.getUUID(), cd.getColumnName(), tc);
cd.setPosition(i);
if (cd.isAutoincrement()) {
cd.setAutoinc_create_or_modify_Start_Increment(ColumnDefinitionNode.CREATE_AUTOINCREMENT);
}
cdlArray[j] = cd;
}
dd.addDescriptorArray(cdlArray, td, DataDictionary.SYSCOLUMNS_CATALOG_NUM, false, tc);
// By this time, the column has been removed from the table descriptor.
// Now, go through all the triggers and regenerate their trigger action
// SPS and rebind the generated trigger action sql. If the trigger
// action is using the dropped column, it will get detected here. If
// not, then we will have generated the internal trigger action sql
// which matches the trigger action sql provided by the user.
//
// eg of positive test case
// create table atdc_16_tab1 (a1 integer, b1 integer, c1 integer);
// create table atdc_16_tab2 (a2 integer, b2 integer, c2 integer);
// create trigger atdc_16_trigger_1
// after update of b1 on atdc_16_tab1
// REFERENCING NEW AS newt
// for each row
// update atdc_16_tab2 set c2 = newt.c1
// The internal representation for the trigger action before the column
// is dropped is as follows
// update atdc_16_tab2 set c2 =
// org.apache.derby.iapi.db.Factory::getTriggerExecutionContext().
// getONewRow().getInt(3)
// After the drop column shown as below
// alter table DERBY4998_SOFT_UPGRADE_RESTRICT drop column c11
// The above internal representation of tigger action sql is not
// correct anymore because column position of c1 in atdc_16_tab1 has
// now changed from 3 to 2. Following while loop will regenerate it and
// change it to as follows
// update atdc_16_tab2 set c2 =
// org.apache.derby.iapi.db.Factory::getTriggerExecutionContext().
// getONewRow().getInt(2)
//
// We could not do this before the actual column drop, because the
// rebind would have still found the column being dropped in the
// table descriptor and hence use of such a column in the trigger
// action rebind would not have been caught.
// For the table on which ALTER TABLE is getting performed, find out
// all the SPSDescriptors that use that table as a provider. We are
// looking for SPSDescriptors that have been created internally for
// trigger action SPSes. Through those SPSDescriptors, we will be
// able to get to the triggers dependent on the table being altered
// Following will get all the dependent objects that are using
// ALTER TABLE table as provider
List<DependencyDescriptor> depsOnAlterTableList = dd.getProvidersDescriptorList(td.getObjectID().toString());
for (DependencyDescriptor depOnAT : depsOnAlterTableList) {
// Go through all the dependent objects on the table being altered
DependableFinder dependent = depOnAT.getDependentFinder();
// stored prepared statement.
if (dependent.getSQLObjectType().equals(Dependable.STORED_PREPARED_STATEMENT)) {
// Look for all the dependent objects that are using this
// stored prepared statement as provider. We are only
// interested in dependents that are triggers.
List<DependencyDescriptor> depsTrigger = dd.getProvidersDescriptorList(depOnAT.getUUID().toString());
for (DependencyDescriptor depsTriggerDesc : depsTrigger) {
DependableFinder providerIsTrigger = depsTriggerDesc.getDependentFinder();
// it is a trigger
if (providerIsTrigger.getSQLObjectType().equals(Dependable.TRIGGER)) {
// Drop and recreate the trigger after regenerating
// it's trigger action plan. If the trigger action
// depends on the column being dropped, it will be
// caught here.
TriggerDescriptor trdToBeDropped = dd.getTriggerDescriptor(depsTriggerDesc.getUUID());
// First check for dependencies in the trigger's WHEN
// clause, if there is one.
UUID whenClauseId = trdToBeDropped.getWhenClauseId();
boolean gotDropped = false;
if (whenClauseId != null) {
gotDropped = columnDroppedAndTriggerDependencies(trdToBeDropped, whenClauseId, true, cascade, columnName);
}
// dependencies.
if (!gotDropped) {
columnDroppedAndTriggerDependencies(trdToBeDropped, trdToBeDropped.getActionId(), false, cascade, columnName);
}
}
}
}
}
// Adjust the column permissions rows in SYSCOLPERMS to reflect the
// changed column positions due to the dropped column:
dd.updateSYSCOLPERMSforDropColumn(td.getUUID(), tc, columnDescriptor);
// remove column descriptor from table descriptor. this fixes up the
// list in case we were called recursively in order to cascade-drop a
// dependent generated column.
tab_cdl.remove(td.getColumnDescriptor(columnName));
}
use of org.apache.derby.iapi.sql.dictionary.ColumnDescriptor in project derby by apache.
the class AlterTableConstantAction method addNewColumnToTable.
/**
* Workhorse for adding a new column to a table.
*
* @param ix the index of the column specfication in the ALTER
* statement-- currently we allow only one.
* @exception StandardException thrown on failure.
*/
private void addNewColumnToTable(int ix) throws StandardException {
ColumnDescriptor columnDescriptor = td.getColumnDescriptor(columnInfo[ix].name);
DataValueDescriptor storableDV;
int colNumber = td.getMaxColumnID() + ix;
/* We need to verify that the table does not have an existing
* column with the same name before we try to add the new
* one as addColumnDescriptor() is a void method.
*/
if (columnDescriptor != null) {
throw StandardException.newException(SQLState.LANG_OBJECT_ALREADY_EXISTS_IN_OBJECT, columnDescriptor.getDescriptorType(), columnInfo[ix].name, td.getDescriptorType(), td.getQualifiedName());
}
if (columnInfo[ix].defaultValue != null)
storableDV = columnInfo[ix].defaultValue;
else
storableDV = columnInfo[ix].dataType.getNull();
// Add the column to the conglomerate.(Column ids in store are 0-based)
tc.addColumnToConglomerate(td.getHeapConglomerateId(), colNumber, storableDV, columnInfo[ix].dataType.getCollationType());
UUID defaultUUID = columnInfo[ix].newDefaultUUID;
/* Generate a UUID for the default, if one exists
* and there is no default id yet.
*/
if (columnInfo[ix].defaultInfo != null && defaultUUID == null) {
defaultUUID = dd.getUUIDFactory().createUUID();
}
// Add the column to syscolumns.
// Column ids in system tables are 1-based
columnDescriptor = new ColumnDescriptor(columnInfo[ix].name, colNumber + 1, columnInfo[ix].dataType, columnInfo[ix].defaultValue, columnInfo[ix].defaultInfo, td, defaultUUID, columnInfo[ix].autoincStart, columnInfo[ix].autoincInc, columnInfo[ix].autoinc_create_or_modify_Start_Increment, columnInfo[ix].autoincCycle);
dd.addDescriptor(columnDescriptor, td, DataDictionary.SYSCOLUMNS_CATALOG_NUM, false, tc);
// now add the column to the tables column descriptor list.
td.getColumnDescriptorList().add(columnDescriptor);
if (columnDescriptor.isAutoincrement()) {
//
// Create a sequence generator for the auto-increment column.
// See DERBY-6542.
//
CreateSequenceConstantAction csca = CreateTableConstantAction.makeCSCA(columnInfo[ix], TableDescriptor.makeSequenceName(td.getUUID()));
csca.executeConstantAction(activation);
}
// Update the new column to its default, if it has a non-null default
if (columnDescriptor.isAutoincrement() || columnDescriptor.hasNonNullDefault()) {
updateNewColumnToDefault(columnDescriptor);
}
//
// Add dependencies. These can arise if a generated column depends
// on a user created function.
//
addColumnDependencies(lcc, dd, td, columnInfo[ix]);
// Update SYSCOLPERMS table which tracks the permissions granted
// at columns level. The sytem table has a bit map of all the columns
// in the user table to help determine which columns have the
// permission granted on them. Since we are adding a new column,
// that bit map needs to be expanded and initialize the bit for it
// to 0 since at the time of ADD COLUMN, no permissions have been
// granted on that new column.
//
dd.updateSYSCOLPERMSforAddColumnToUserTable(td.getUUID(), tc);
}
use of org.apache.derby.iapi.sql.dictionary.ColumnDescriptor in project derby by apache.
the class AlterTableConstantAction method modifyColumnType.
private void modifyColumnType(int ix) throws StandardException {
ColumnDescriptor columnDescriptor = td.getColumnDescriptor(columnInfo[ix].name);
ColumnDescriptor newColumnDescriptor = new ColumnDescriptor(columnInfo[ix].name, columnDescriptor.getPosition(), columnInfo[ix].dataType, columnDescriptor.getDefaultValue(), columnDescriptor.getDefaultInfo(), td, columnDescriptor.getDefaultUUID(), columnInfo[ix].autoincStart, columnInfo[ix].autoincInc, columnInfo[ix].autoincCycle);
// Update the ColumnDescriptor with new default info
dd.dropColumnDescriptor(td.getUUID(), columnInfo[ix].name, tc);
dd.addDescriptor(newColumnDescriptor, td, DataDictionary.SYSCOLUMNS_CATALOG_NUM, false, tc);
}
Aggregations