示例#1
0
  /**
   * Add a table to the schema.
   *
   * @param data the create table information
   * @return the created {@link Table} object
   */
  public Table createTable(CreateTableData data) {
    synchronized (database) {
      if (!data.temporary || data.globalTemporary) {
        database.lockMeta(data.session);
      }
      data.schema = this;

      if (data.isMemoryTable()) data.storageEngineName = MemoryStorageEngine.NAME;

      // 用默认的数据库参数
      if (data.storageEngineName == null) {
        data.storageEngineName = database.getDefaultStorageEngineName();
      }
      if (data.storageEngineName != null) {
        StorageEngine engine = StorageEngineManager.getInstance().getEngine(data.storageEngineName);
        if (engine == null) {
          try {
            engine = (StorageEngine) Utils.loadUserClass(data.storageEngineName).newInstance();
            StorageEngineManager.getInstance().registerEngine(engine);
          } catch (Exception e) {
            throw DbException.convert(e);
          }
        }

        if (engine instanceof TableFactory) {
          return ((TableFactory) engine).createTable(data);
        }
        return new StandardTable(data, engine);
      }
      throw DbException.convert(new NullPointerException("table engine is null"));
    }
  }
  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) {
      int position = oldColumn.getColumnId();
      newColumns.remove(position);
    } 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;
    data.storageEngineName = table.getStorageEngineName();
    Table newTable = getSchema().createTable(data);
    newTable.setComment(table.getComment());
    StringBuilder buff = new StringBuilder();
    buff.append(newTable.getCreateSQL());

    if (table.supportsAlterColumnWithCopyData()) {
      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 = (Expression) 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;
  }
示例#3
0
 public void setTableName(String tableName) {
   data.tableName = tableName;
 }
示例#4
0
 @Override
 public int update() {
   if (!transactional) {
     session.commit(true);
   }
   Database db = session.getDatabase();
   if (!db.isPersistent()) {
     data.persistIndexes = false;
   }
   if (getSchema().findTableOrView(session, data.tableName) != null) {
     if (ifNotExists) {
       return 0;
     }
     throw DbException.get(ErrorCode.TABLE_OR_VIEW_ALREADY_EXISTS_1, data.tableName);
   }
   if (asQuery != null) {
     asQuery.prepare();
     if (data.columns.isEmpty()) {
       generateColumnsFromQuery();
     } else if (data.columns.size() != asQuery.getColumnCount()) {
       throw DbException.get(ErrorCode.COLUMN_COUNT_DOES_NOT_MATCH);
     }
   }
   if (pkColumns != null) {
     for (Column c : data.columns) {
       for (IndexColumn idxCol : pkColumns) {
         if (c.getName().equals(idxCol.columnName)) {
           c.setNullable(false);
         }
       }
     }
   }
   data.id = getObjectId();
   data.create = create;
   data.session = session;
   boolean isSessionTemporary = data.temporary && !data.globalTemporary;
   if (!isSessionTemporary) {
     db.lockMeta(session);
   }
   Table table = createTable(data);
   ArrayList<Sequence> sequences = New.arrayList();
   for (Column c : data.columns) {
     if (c.isAutoIncrement()) {
       int objId = getObjectId();
       c.convertAutoIncrementToSequence(session, getSchema(), objId, data.temporary);
     }
     Sequence seq = c.getSequence();
     if (seq != null) {
       sequences.add(seq);
     }
   }
   table.setComment(comment);
   if (isSessionTemporary) {
     if (onCommitDrop) {
       table.setOnCommitDrop(true);
     }
     if (onCommitTruncate) {
       table.setOnCommitTruncate(true);
     }
     session.addLocalTempTable(table);
   } else {
     db.lockMeta(session);
     db.addSchemaObject(session, table);
   }
   try {
     for (Column c : data.columns) {
       c.prepareExpression(session);
     }
     for (Sequence sequence : sequences) {
       table.addSequence(sequence);
     }
     for (DefineCommand command : constraintCommands) {
       command.setTransactional(transactional);
       command.update();
     }
     if (asQuery != null) {
       Insert insert = null;
       insert = new Insert(session);
       insert.setSortedInsertMode(sortedInsertMode);
       insert.setQuery(asQuery);
       insert.setTable(table);
       insert.setInsertFromSelect(true);
       insert.prepare();
       insert.update();
     }
   } catch (DbException e) {
     db.checkPowerOff();
     db.removeSchemaObject(session, table);
     if (!transactional) {
       session.commit(true);
     }
     throw e;
   }
   return 0;
 }
示例#5
0
 public CreateTable(Session session, Schema schema) {
   super(session, schema);
   data.persistIndexes = true;
   data.persistData = true;
 }
示例#6
0
 public void setTemporary(boolean temporary) {
   data.temporary = temporary;
 }
示例#7
0
 public void setHidden(boolean isHidden) {
   data.isHidden = isHidden;
 }
示例#8
0
 public void setStorageEngine(String storageEngine) {
   data.storageEngine = storageEngine;
 }
示例#9
0
 public void setPersistData(boolean persistData) {
   data.persistData = persistData;
   if (!persistData) {
     data.persistIndexes = false;
   }
 }
示例#10
0
 public void setGlobalTemporary(boolean globalTemporary) {
   data.globalTemporary = globalTemporary;
 }
示例#11
0
 public void setPersistIndexes(boolean persistIndexes) {
   data.persistIndexes = persistIndexes;
 }