private void copyData() {
   if (table.isTemporary()) {
     throw DbException.getUnsupportedException("TEMP TABLE");
   }
   Database db = session.getDatabase();
   String baseName = table.getName();
   String tempName = db.getTempTableName(baseName, session);
   Column[] columns = table.getColumns();
   ArrayList<Column> newColumns = New.arrayList();
   Table newTable = cloneTableStructure(columns, db, tempName, newColumns);
   try {
     // check if a view would become invalid
     // (because the column to drop is referenced or so)
     checkViews(table, newTable);
   } catch (DbException e) {
     execute("DROP TABLE " + newTable.getName(), true);
     throw DbException.get(ErrorCode.VIEW_IS_INVALID_2, e, getSQL(), e.getMessage());
   }
   String tableName = table.getName();
   ArrayList<TableView> views = table.getViews();
   if (views != null) {
     views = New.arrayList(views);
     for (TableView view : views) {
       table.removeView(view);
     }
   }
   execute("DROP TABLE " + table.getSQL() + " IGNORE", true);
   db.renameSchemaObject(session, newTable, tableName);
   for (DbObject child : newTable.getChildren()) {
     if (child instanceof Sequence) {
       continue;
     }
     String name = child.getName();
     if (name == null || child.getCreateSQL() == null) {
       continue;
     }
     if (name.startsWith(tempName + "_")) {
       name = name.substring(tempName.length() + 1);
       SchemaObject so = (SchemaObject) child;
       if (so instanceof Constraint) {
         if (so.getSchema().findConstraint(session, name) != null) {
           name = so.getSchema().getUniqueConstraintName(session, newTable);
         }
       } else if (so instanceof Index) {
         if (so.getSchema().findIndex(session, name) != null) {
           name = so.getSchema().getUniqueIndexName(session, newTable, name);
         }
       }
       db.renameSchemaObject(session, so, name);
     }
   }
   if (views != null) {
     for (TableView view : views) {
       String sql = view.getCreateSQL(true, true);
       execute(sql, true);
     }
   }
 }
  private Table cloneTableStructure(
      Column[] columns, Database db, String tempName, ArrayList<Column> newColumns) {
    for (Column col : columns) {
      newColumns.add(col.getClone());
    }
    if (type == CommandInterface.ALTER_TABLE_DROP_COLUMN) {
      for (Column removeCol : columnsToRemove) {
        Column foundCol = null;
        for (Iterator<Column> iter = newColumns.iterator(); iter.hasNext(); ) {
          Column newCol = iter.next();
          if (newCol.getName() == removeCol.getName()) {
            foundCol = newCol;
            break;
          }
        }
        if (foundCol == null) {
          throw DbException.throwInternalError(removeCol.getCreateSQL());
        }
        newColumns.remove(foundCol);
      }
    } else if (type == CommandInterface.ALTER_TABLE_ADD_COLUMN) {
      int position;
      if (addBefore != null) {
        position = table.getColumn(addBefore).getColumnId();
      } else if (addAfter != null) {
        position = table.getColumn(addAfter).getColumnId() + 1;
      } else {
        position = columns.length;
      }
      for (Column column : columnsToAdd) {
        newColumns.add(position++, column);
      }
    } else if (type == CommandInterface.ALTER_TABLE_ALTER_COLUMN_CHANGE_TYPE) {
      int position = oldColumn.getColumnId();
      newColumns.remove(position);
      newColumns.add(position, newColumn);
    }

    // create a table object in order to get the SQL statement
    // can't just use this table, because most column objects are 'shared'
    // with the old table
    // still need a new id because using 0 would mean: the new table tries
    // to use the rows of the table 0 (the meta table)
    int id = db.allocateObjectId();
    CreateTableData data = new CreateTableData();
    data.tableName = tempName;
    data.id = id;
    data.columns = newColumns;
    data.temporary = table.isTemporary();
    data.persistData = table.isPersistData();
    data.persistIndexes = table.isPersistIndexes();
    data.isHidden = table.isHidden();
    data.create = true;
    data.session = session;
    Table newTable = getSchema().createTable(data);
    newTable.setComment(table.getComment());
    StringBuilder buff = new StringBuilder();
    buff.append(newTable.getCreateSQL());
    StringBuilder columnList = new StringBuilder();
    for (Column nc : newColumns) {
      if (columnList.length() > 0) {
        columnList.append(", ");
      }
      if (type == CommandInterface.ALTER_TABLE_ADD_COLUMN && columnsToAdd.contains(nc)) {
        Expression def = nc.getDefaultExpression();
        columnList.append(def == null ? "NULL" : def.getSQL());
      } else {
        columnList.append(nc.getSQL());
      }
    }
    buff.append(" AS SELECT ");
    if (columnList.length() == 0) {
      // special case: insert into test select * from
      buff.append('*');
    } else {
      buff.append(columnList);
    }
    buff.append(" FROM ").append(table.getSQL());
    String newTableSQL = buff.toString();
    String newTableName = newTable.getName();
    Schema newTableSchema = newTable.getSchema();
    newTable.removeChildrenAndResources(session);

    execute(newTableSQL, true);
    newTable = newTableSchema.getTableOrView(session, newTableName);
    ArrayList<String> triggers = New.arrayList();
    for (DbObject child : table.getChildren()) {
      if (child instanceof Sequence) {
        continue;
      } else if (child instanceof Index) {
        Index idx = (Index) child;
        if (idx.getIndexType().getBelongsToConstraint()) {
          continue;
        }
      }
      String createSQL = child.getCreateSQL();
      if (createSQL == null) {
        continue;
      }
      if (child instanceof TableView) {
        continue;
      } else if (child.getType() == DbObject.TABLE_OR_VIEW) {
        DbException.throwInternalError();
      }
      String quotedName = Parser.quoteIdentifier(tempName + "_" + child.getName());
      String sql = null;
      if (child instanceof ConstraintReferential) {
        ConstraintReferential r = (ConstraintReferential) child;
        if (r.getTable() != table) {
          sql = r.getCreateSQLForCopy(r.getTable(), newTable, quotedName, false);
        }
      }
      if (sql == null) {
        sql = child.getCreateSQLForCopy(newTable, quotedName);
      }
      if (sql != null) {
        if (child instanceof TriggerObject) {
          triggers.add(sql);
        } else {
          execute(sql, true);
        }
      }
    }
    table.setModified();
    // remove the sequences from the columns (except dropped columns)
    // otherwise the sequence is dropped if the table is dropped
    for (Column col : newColumns) {
      Sequence seq = col.getSequence();
      if (seq != null) {
        table.removeSequence(seq);
        col.setSequence(null);
      }
    }
    for (String sql : triggers) {
      execute(sql, true);
    }
    return newTable;
  }