private void removeSequence(Sequence sequence) {
   if (sequence != null) {
     table.removeSequence(sequence);
     sequence.setBelongsToTable(false);
     Database db = session.getDatabase();
     db.removeSchemaObject(session, sequence);
   }
 }
 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);
     }
   }
 }
  @Override
  public Expression optimize(Session session) {
    if (columnResolver == null) {
      Schema schema =
          session
              .getDatabase()
              .findSchema(tableAlias == null ? session.getCurrentSchemaName() : tableAlias);
      if (schema != null) {
        Constant constant = schema.findConstant(columnName);
        if (constant != null) {
          return (Expression) constant.getValue();
        }
      }

      // 处理在where和having中出现别名的情况,如:
      // SELECT id AS A FROM mytable where A>=0
      // SELECT id/3 AS A, COUNT(*) FROM mytable GROUP BY A HAVING A>=0
      if (select != null) {
        for (Expression e : select.getExpressions()) {
          if (database.equalsIdentifiers(columnName, e.getAlias()))
            return e.getNonAliasExpression().optimize(session);
        }
      }

      String name = columnName;
      if (tableAlias != null) {
        name = tableAlias + "." + name;
        if (schemaName != null) {
          name = schemaName + "." + name;
        }
      }
      throw DbException.get(ErrorCode.COLUMN_NOT_FOUND_1, name);
    }
    return (Expression) columnResolver.optimize(this, column);
  }
 @Override
 public int update() {
   session.commit(true);
   session.getUser().checkAdmin();
   Database db = session.getDatabase();
   if (db.findAggregate(name) != null || schema.findFunction(name) != null) {
     if (!ifNotExists) {
       throw DbException.get(ErrorCode.FUNCTION_ALIAS_ALREADY_EXISTS_1, name);
     }
   } else {
     int id = getObjectId();
     UserAggregate aggregate = new UserAggregate(db, id, name, javaClassName, force);
     db.addDatabaseObject(session, aggregate);
   }
   return 0;
 }
 @Override
 public int update() {
   session.commit(true);
   Database db = session.getDatabase();
   if (getSchema().findSequence(sequenceName) != null) {
     if (ifNotExists) {
       return 0;
     }
     throw DbException.get(ErrorCode.SEQUENCE_ALREADY_EXISTS_1, sequenceName);
   }
   int id = getObjectId();
   Long startValue = getLong(start);
   Long inc = getLong(increment);
   Long cache = getLong(cacheSize);
   Long min = getLong(minValue);
   Long max = getLong(maxValue);
   Sequence sequence =
       new Sequence(
           getSchema(), id, sequenceName, startValue, inc, cache, min, max, cycle, belongsToTable);
   db.addSchemaObject(session, sequence);
   return 0;
 }
Exemple #6
0
 /**
  * Create a new schema object.
  *
  * @param database the database
  * @param id the object id
  * @param schemaName the schema name
  * @param owner the owner of the schema
  * @param system if this is a system schema (such a schema can not be dropped)
  */
 public Schema(Database database, int id, String schemaName, User owner, boolean system) {
   super(database, id, schemaName, Trace.SCHEMA);
   tablesAndViews = database.newStringMap();
   indexes = database.newStringMap();
   sequences = database.newStringMap();
   triggers = database.newStringMap();
   constraints = database.newStringMap();
   constants = database.newStringMap();
   functions = database.newStringMap();
   this.owner = owner;
   this.system = system;
 }
 @Override
 public String getSQL(boolean isDistributed) {
   String sql;
   boolean quote = database.getSettings().databaseToUpper;
   if (column != null) {
     sql = column.getSQL();
   } else {
     sql = quote ? Parser.quoteIdentifier(columnName) : columnName;
   }
   if (tableAlias != null) {
     String a = quote ? Parser.quoteIdentifier(tableAlias) : tableAlias;
     sql = a + "." + sql;
   }
   if (schemaName != null) {
     String s = quote ? Parser.quoteIdentifier(schemaName) : schemaName;
     sql = s + "." + sql;
   }
   return sql;
 }
 @Override
 public boolean isEverything(ExpressionVisitor visitor) {
   switch (visitor.getType()) {
     case ExpressionVisitor.OPTIMIZABLE_MIN_MAX_COUNT_ALL:
       return false;
     case ExpressionVisitor.READONLY:
     case ExpressionVisitor.DETERMINISTIC:
     case ExpressionVisitor.QUERY_COMPARABLE:
       return true;
     case ExpressionVisitor.INDEPENDENT:
       return this.queryLevel < visitor.getQueryLevel();
     case ExpressionVisitor.EVALUATABLE:
       // if the current value is known (evaluatable set)
       // or if this columns belongs to a 'higher level' query and is
       // therefore just a parameter
       if (database.getSettings().nestedJoins) {
         if (visitor.getQueryLevel() < this.queryLevel) {
           return true;
         }
         if (getTableFilter() == null) {
           return false;
         }
         return getTableFilter().isEvaluatable();
       }
       return evaluatable || visitor.getQueryLevel() < this.queryLevel;
     case ExpressionVisitor.SET_MAX_DATA_MODIFICATION_ID:
       visitor.addDataModificationId(column.getTable().getMaxDataModificationId());
       return true;
     case ExpressionVisitor.NOT_FROM_RESOLVER:
       return columnResolver != visitor.getResolver();
     case ExpressionVisitor.GET_DEPENDENCIES:
       if (column != null) {
         visitor.addDependency(column.getTable());
       }
       return true;
     case ExpressionVisitor.GET_COLUMNS:
       visitor.addColumn(column);
       return true;
     default:
       throw DbException.throwInternalError("type=" + visitor.getType());
   }
 }
 /** Check that all views and other dependent objects. */
 private void checkViews(SchemaObject sourceTable, SchemaObject newTable) {
   String sourceTableName = sourceTable.getName();
   String newTableName = newTable.getName();
   Database db = sourceTable.getDatabase();
   // save the real table under a temporary name
   String temp = db.getTempTableName(sourceTableName, session);
   db.renameSchemaObject(session, sourceTable, temp);
   try {
     // have our new table impersonate the target table
     db.renameSchemaObject(session, newTable, sourceTableName);
     checkViewsAreValid(sourceTable);
   } finally {
     // always put the source tables back with their proper names
     try {
       db.renameSchemaObject(session, newTable, newTableName);
     } finally {
       db.renameSchemaObject(session, sourceTable, sourceTableName);
     }
   }
 }
Exemple #10
0
  @Override
  public void mapColumns(ColumnResolver resolver, int level) {
    if (select == null) select = (Select) resolver.getSelect();

    if (resolver instanceof TableFilter
        && resolver.getTableFilter().getTable().supportsColumnFamily()) {
      Table t = resolver.getTableFilter().getTable();

      // if (!t.isStatic() && t.getRowKeyName().equalsIgnoreCase(columnName)) {
      // if (columnFamilyName != null) {
      // schemaName = tableAlias;
      // tableAlias = columnFamilyName;
      // columnFamilyName = null;
      // }
      // if (tableAlias != null && !database.equalsIdentifiers(tableAlias,
      // resolver.getTableAlias())) {
      // return;
      // }
      // if (schemaName != null && !database.equalsIdentifiers(schemaName,
      // resolver.getSchemaName())) {
      // return;
      // }
      // mapColumn(resolver, t.getRowKeyColumn(), level);
      // return;
      // }

      if (database.equalsIdentifiers(Column.ROWKEY, columnName)) {
        Column col = t.getRowKeyColumn();
        if (col != null) {
          mapColumn(resolver, col, level);
          return;
        }
      }
      if (resolver.getSelect() == null) {
        Column c = t.getColumn(columnName);
        mapColumn(resolver, c, level);
        return;
      }

      String tableAlias = this.tableAlias;
      boolean useAlias = false;
      // 当columnFamilyName不存在时,有可能是想使用简化的tableAlias.columnName语法
      if (columnFamilyName != null && !t.doesColumnFamilyExist(columnFamilyName)) {
        // 不替换原有的tableAlias,因为有可能在另一个table中存在这样的columnFamilyName
        tableAlias = columnFamilyName;

        if (!t.doesColumnExist(columnName)) return;

        useAlias = true;
      }

      if (tableAlias != null && !database.equalsIdentifiers(tableAlias, resolver.getTableAlias())) {
        return;
      }
      if (schemaName != null && !database.equalsIdentifiers(schemaName, resolver.getSchemaName())) {
        return;
      }

      String fullColumnName;
      if (useAlias || columnFamilyName == null) fullColumnName = columnName;
      else fullColumnName = t.getFullColumnName(columnFamilyName, columnName);

      if (t.doesColumnExist(fullColumnName)) {
        Column c = t.getColumn(fullColumnName);
        mapColumn(resolver, c, level);
        return;
      }
    } else {
      if (columnFamilyName != null) {
        schemaName = tableAlias;
        tableAlias = columnFamilyName;
        columnFamilyName = null;
      }
    }

    if (tableAlias != null && !database.equalsIdentifiers(tableAlias, resolver.getTableAlias())) {
      return;
    }
    if (schemaName != null && !database.equalsIdentifiers(schemaName, resolver.getSchemaName())) {
      return;
    }
    for (Column col : resolver.getColumns()) {
      String n = col.getName();
      if (database.equalsIdentifiers(columnName, n)) {
        mapColumn(resolver, col, level);
        return;
      }
    }
    if (database.equalsIdentifiers(Column.ROWID, columnName)) {
      Column col = resolver.getRowIdColumn();
      if (col != null) {
        mapColumn(resolver, col, level);
        return;
      }
    }
    Column[] columns = resolver.getSystemColumns();
    for (int i = 0; columns != null && i < columns.length; i++) {
      Column col = columns[i];
      if (database.equalsIdentifiers(columnName, col.getName())) {
        mapColumn(resolver, col, level);
        return;
      }
    }
  }
 @Override
 void add(Database database, int dataType, boolean distinct, Value v) {
   if (v == ValueNull.INSTANCE) {
     return;
   }
   count++;
   if (distinct) {
     if (distinctValues == null) {
       distinctValues = ValueHashMap.newInstance();
     }
     distinctValues.put(v, this);
     return;
   }
   switch (aggregateType) {
     case Aggregate.SUM:
       if (value == null) {
         value = v.convertTo(dataType);
       } else {
         v = v.convertTo(value.getType());
         value = value.add(v);
       }
       break;
     case Aggregate.AVG:
       if (value == null) {
         value = v.convertTo(DataType.getAddProofType(dataType));
       } else {
         v = v.convertTo(value.getType());
         value = value.add(v);
       }
       break;
     case Aggregate.MIN:
       if (value == null || database.compare(v, value) < 0) {
         value = v;
       }
       break;
     case Aggregate.MAX:
       if (value == null || database.compare(v, value) > 0) {
         value = v;
       }
       break;
     case Aggregate.STDDEV_POP:
     case Aggregate.STDDEV_SAMP:
     case Aggregate.VAR_POP:
     case Aggregate.VAR_SAMP:
       {
         // Using Welford's method, see also
         // http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
         // http://www.johndcook.com/standard_deviation.html
         double x = v.getDouble();
         if (count == 1) {
           mean = x;
           m2 = 0;
         } else {
           double delta = x - mean;
           mean += delta / count;
           m2 += delta * (x - mean);
         }
         break;
       }
     case Aggregate.BOOL_AND:
       v = v.convertTo(Value.BOOLEAN);
       if (value == null) {
         value = v;
       } else {
         value =
             ValueBoolean.get(value.getBoolean().booleanValue() && v.getBoolean().booleanValue());
       }
       break;
     case Aggregate.BOOL_OR:
       v = v.convertTo(Value.BOOLEAN);
       if (value == null) {
         value = v;
       } else {
         value =
             ValueBoolean.get(value.getBoolean().booleanValue() || v.getBoolean().booleanValue());
       }
       break;
     case Aggregate.BIT_AND:
       if (value == null) {
         value = v.convertTo(dataType);
       } else {
         value = ValueLong.get(value.getLong() & v.getLong()).convertTo(dataType);
       }
       break;
     case Aggregate.BIT_OR:
       if (value == null) {
         value = v.convertTo(dataType);
       } else {
         value = ValueLong.get(value.getLong() | v.getLong()).convertTo(dataType);
       }
       break;
     default:
       DbException.throwInternalError("type=" + aggregateType);
   }
 }
 @Override
 void merge(Database database, int dataType, boolean distinct, Value v) {
   if (v == ValueNull.INSTANCE) {
     return;
   }
   count++;
   if (distinct) {
     if (distinctValues == null) {
       distinctValues = ValueHashMap.newInstance();
     }
     distinctValues.put(v, this);
     return;
   }
   switch (aggregateType) {
     case Aggregate.SUM:
       if (value == null) {
         value = v.convertTo(dataType);
       } else {
         v = v.convertTo(value.getType());
         value = value.add(v);
       }
       break;
     case Aggregate.MIN:
       if (value == null || database.compare(v, value) < 0) {
         value = v;
       }
       break;
     case Aggregate.MAX:
       if (value == null || database.compare(v, value) > 0) {
         value = v;
       }
       break;
     case Aggregate.BOOL_AND:
       v = v.convertTo(Value.BOOLEAN);
       if (value == null) {
         value = v;
       } else {
         value =
             ValueBoolean.get(value.getBoolean().booleanValue() && v.getBoolean().booleanValue());
       }
       break;
     case Aggregate.BOOL_OR:
       v = v.convertTo(Value.BOOLEAN);
       if (value == null) {
         value = v;
       } else {
         value =
             ValueBoolean.get(value.getBoolean().booleanValue() || v.getBoolean().booleanValue());
       }
       break;
     case Aggregate.BIT_AND:
       if (value == null) {
         value = v.convertTo(dataType);
       } else {
         value = ValueLong.get(value.getLong() & v.getLong()).convertTo(dataType);
       }
       break;
     case Aggregate.BIT_OR:
       if (value == null) {
         value = v.convertTo(dataType);
       } else {
         value = ValueLong.get(value.getLong() | v.getLong()).convertTo(dataType);
       }
       break;
       // 这5个在分布式环境下会进行重写,所以合并时是不会出现的
     case Aggregate.AVG:
     case Aggregate.STDDEV_POP:
     case Aggregate.STDDEV_SAMP:
     case Aggregate.VAR_POP:
     case Aggregate.VAR_SAMP:
     default:
       DbException.throwInternalError("type=" + aggregateType);
   }
 }
 @Override
 public int update() {
   session.commit(true);
   Database db = session.getDatabase();
   session.getUser().checkRight(table, Right.ALL);
   table.checkSupportAlter();
   table.lock(session, true, true);
   Sequence sequence = oldColumn == null ? null : oldColumn.getSequence();
   if (newColumn != null) {
     checkDefaultReferencesTable((Expression) newColumn.getDefaultExpression());
   }
   if (columnsToAdd != null) {
     for (Column column : columnsToAdd) {
       checkDefaultReferencesTable((Expression) column.getDefaultExpression());
     }
   }
   switch (type) {
     case CommandInterface.ALTER_TABLE_ALTER_COLUMN_NOT_NULL:
       {
         if (!oldColumn.isNullable()) {
           // no change
           break;
         }
         checkNoNullValues();
         oldColumn.setNullable(false);
         db.updateMeta(session, table);
         break;
       }
     case CommandInterface.ALTER_TABLE_ALTER_COLUMN_NULL:
       {
         if (oldColumn.isNullable()) {
           // no change
           break;
         }
         checkNullable();
         oldColumn.setNullable(true);
         db.updateMeta(session, table);
         break;
       }
     case CommandInterface.ALTER_TABLE_ALTER_COLUMN_DEFAULT:
       {
         checkDefaultReferencesTable(defaultExpression);
         oldColumn.setSequence(null);
         oldColumn.setDefaultExpression(session, defaultExpression);
         removeSequence(sequence);
         db.updateMeta(session, table);
         break;
       }
     case CommandInterface.ALTER_TABLE_ALTER_COLUMN_CHANGE_TYPE:
       {
         // if the change is only increasing the precision, then we don't
         // need to copy the table because the length is only a constraint,
         // and does not affect the storage structure.
         if (oldColumn.isWideningConversion(newColumn)) {
           convertAutoIncrementColumn(newColumn);
           oldColumn.copy(newColumn);
           db.updateMeta(session, table);
         } else {
           oldColumn.setSequence(null);
           oldColumn.setDefaultExpression(session, null);
           oldColumn.setConvertNullToDefault(false);
           if (oldColumn.isNullable() && !newColumn.isNullable()) {
             checkNoNullValues();
           } else if (!oldColumn.isNullable() && newColumn.isNullable()) {
             checkNullable();
           }
           convertAutoIncrementColumn(newColumn);
           copyData();
         }
         break;
       }
     case CommandInterface.ALTER_TABLE_ADD_COLUMN:
       {
         // ifNotExists only supported for single column add
         if (ifNotExists
             && columnsToAdd.size() == 1
             && table.doesColumnExist(columnsToAdd.get(0).getName())) {
           break;
         }
         for (Column column : columnsToAdd) {
           if (column.isAutoIncrement()) {
             int objId = getObjectId();
             column.convertAutoIncrementToSequence(
                 session, getSchema(), objId, table.isTemporary());
           }
         }
         copyData();
         break;
       }
     case CommandInterface.ALTER_TABLE_DROP_COLUMN:
       {
         if (table.getColumns().length == 1) {
           throw DbException.get(ErrorCode.CANNOT_DROP_LAST_COLUMN, oldColumn.getSQL());
         }
         table.dropSingleColumnConstraintsAndIndexes(session, oldColumn);
         copyData();
         break;
       }
     case CommandInterface.ALTER_TABLE_ALTER_COLUMN_SELECTIVITY:
       {
         int value = newSelectivity.optimize(session).getValue(session).getInt();
         oldColumn.setSelectivity(value);
         db.updateMeta(session, table);
         break;
       }
     default:
       DbException.throwInternalError("type=" + type);
   }
   return 0;
 }
  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;
  }
Exemple #15
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;
 }