}
}
break;
case NodeTypes.AT_RENAME_NODE:
TableName newName = DDLHelper.convertName(defaultSchema,
((AlterTableRenameNode)node).newName());
TableName oldName = origTable.getName();
ddl.renameTable(session, oldName, newName);
return ChangeLevel.METADATA;
case NodeTypes.AT_RENAME_COLUMN_NODE:
AlterTableRenameColumnNode alterRenameCol = (AlterTableRenameColumnNode) node;
String oldColName = alterRenameCol.getName();
String newColName = alterRenameCol.newName();
final Column oldCol = origTable.getColumn(oldColName);
if (oldCol == null) {
throw new NoSuchColumnException(oldColName);
}
columnChanges.add(TableChange.createModify(oldColName, newColName));
break;
default:
return null; // Something unsupported
}
}
for (ForeignKey foreignKey : origTable.getForeignKeys()) {
if (foreignKey.getReferencingTable() == origTable) {
checkForeignKeyAlterColumns(columnChanges, foreignKey.getReferencingColumns(),
foreignKey, origTable);
}
if (foreignKey.getReferencedTable() == origTable) {
checkForeignKeyAlterColumns(columnChanges, foreignKey.getReferencedColumns(),
foreignKey, origTable);
}
}
final AkibanInformationSchema origAIS = origTable.getAIS();
final Table tableCopy = copyTable(ddl.getAISCloner(), origTable, columnChanges);
final AkibanInformationSchema aisCopy = tableCopy.getAIS();
TableDDL.cloneReferencedTables(defaultSchema, ddl.getAISCloner(), origAIS, aisCopy, elements);
final TypesTranslator typesTranslator = ddl.getTypesTranslator();
final AISBuilder builder = new AISBuilder(aisCopy);
builder.getNameGenerator().mergeAIS(origAIS);
int pos = tableCopy.getColumnsIncludingInternal().size();
for(ColumnDefinitionNode cdn : columnDefNodes) {
if(cdn instanceof ModifyColumnNode) {
ModifyColumnNode modNode = (ModifyColumnNode) cdn;
handleModifyColumnNode(modNode, builder, tableCopy, typesTranslator);
} else {
TableDDL.addColumn(builder, typesTranslator, cdn, origTable.getName().getSchemaName(), origTable.getName().getTableName(), pos++);
}
}
// Ensure that internal columns stay at the end
// because there's a bunch of places that assume that they are
// (e.g. they assume getColumns() have indexes (1...getColumns().size()))
// If the original table had a primary key, the hidden pk is added a bit farther down
for (Column origColumn : origTable.getColumnsIncludingInternal()) {
if (origColumn.isInternalColumn()) {
String newName = findNewName(columnChanges, origColumn.getName());
if (newName != null) {
Column.create(tableCopy, origColumn, newName, pos++);
}
}
}
copyTableIndexes(origTable, tableCopy, columnChanges, indexChanges);
IndexNameGenerator indexNamer = DefaultIndexNameGenerator.forTable(tableCopy);
TableName newName = tableCopy.getName();
for(ConstraintDefinitionNode cdn : conDefNodes) {
assert cdn.getConstraintType() != ConstraintType.DROP : cdn;
String name = TableDDL.addIndex(indexNamer, builder, cdn, newName.getSchemaName(), newName.getTableName(), context);
indexChanges.add(TableChange.createAdd(name));
// This is required as the addIndex() for a primary key constraint
// *may* alter the NULL->NOT NULL status
// of the columns in the primary key
if (name.equals(Index.PRIMARY)) {
for (IndexColumn col : tableCopy.getIndex(name).getKeyColumns())
{
String columnName = col.getColumn().getName();
// Check if the column was added in the same alter as creating the index:
// ALTER TABLE c ADD COLUMN n SERIAL PRIMARY KEY
// You can't add and modify the column, so assume the add does the correct thing.
boolean columnAdded = false;
for (TableChange change : columnChanges) {
if (change.getChangeType() == ChangeType.ADD && columnName.equals(change.getNewName()))
columnAdded = true;
}
if (!columnAdded)
columnChanges.add(TableChange.createModify(columnName, columnName));
}
}
}
for(IndexDefinitionNode idn : indexDefNodes) {
String name = TableDDL.addIndex(indexNamer, builder, idn, newName.getSchemaName(), newName.getTableName(), context, ddl);
indexChanges.add(TableChange.createAdd(name));
}
// Correctly adds the Hidden PK (including sequence).
if (tableCopy.getPrimaryKeyIncludingInternal() == null) {
if (origTable.getPrimaryKeyIncludingInternal().isAkibanPK()) {
Column origColumn = origTable.getPrimaryKeyIncludingInternal().getColumns().get(0);
Column.create(tableCopy, origColumn, Column.ROW_ID_NAME, tableCopy.getColumns().size());
} else {
tableCopy.addHiddenPrimaryKey(builder.getNameGenerator());
columnChanges.add(TableChange.createAdd(Column.ROW_ID_NAME));
}
}
for(FKConstraintDefinitionNode fk : fkDefNodes) {
if(fk.isGrouping()) {
if(fk.getConstraintType() == ConstraintType.DROP) {
Join parentJoin = tableCopy.getParentJoin();
tableCopy.setGroup(null);
tableCopy.removeCandidateParentJoin(parentJoin);
parentJoin.getParent().removeCandidateChildJoin(parentJoin);
} else {
if(origTable.getParentJoin() != null) {
throw new JoinToMultipleParentsException(origTable.getName());
}
tableCopy.setGroup(null);
TableDDL.addJoin(builder, fk, defaultSchema, newName.getSchemaName(), newName.getTableName());
}
} else {
if(fk.getConstraintType() == ConstraintType.DROP) {
String name = fk.getConstraintName().getTableName();
ForeignKey tableFK = null;
for (ForeignKey tfk : tableCopy.getReferencingForeignKeys()) {
if (name.equals(tfk.getConstraintName().getTableName())) {
tableFK = tfk;
break;
}
}
assert tableFK != null : name;
tableCopy.removeForeignKey(tableFK);
} else {
TableDDL.addForeignKey(builder, origAIS, fk, defaultSchema, newName.getSchemaName(), newName.getTableName());
}
}
}
return ddl.alterTable(session, origTable.getName(), tableCopy, columnChanges, indexChanges, context);
}