Unverified 提交 a55fda66 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov 提交者: GitHub

Merge pull request #1329 from katzyn/ddl

Allow creation of delegate index in ALTER TABLE
...@@ -14,6 +14,7 @@ import org.h2.command.Parser; ...@@ -14,6 +14,7 @@ import org.h2.command.Parser;
import org.h2.command.Prepared; import org.h2.command.Prepared;
import org.h2.constraint.Constraint; import org.h2.constraint.Constraint;
import org.h2.constraint.ConstraintReferential; import org.h2.constraint.ConstraintReferential;
import org.h2.constraint.ConstraintUnique;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.engine.Database; import org.h2.engine.Database;
import org.h2.engine.DbObject; import org.h2.engine.DbObject;
...@@ -25,13 +26,16 @@ import org.h2.index.Index; ...@@ -25,13 +26,16 @@ import org.h2.index.Index;
import org.h2.index.IndexType; import org.h2.index.IndexType;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.result.ResultInterface; import org.h2.result.ResultInterface;
import org.h2.result.SearchRow;
import org.h2.schema.Schema; import org.h2.schema.Schema;
import org.h2.schema.SchemaObject; import org.h2.schema.SchemaObject;
import org.h2.schema.Sequence; import org.h2.schema.Sequence;
import org.h2.schema.TriggerObject; import org.h2.schema.TriggerObject;
import org.h2.table.Column; import org.h2.table.Column;
import org.h2.table.Table; import org.h2.table.Table;
import org.h2.table.TableBase;
import org.h2.table.TableView; import org.h2.table.TableView;
import org.h2.util.Utils;
/** /**
* This class represents the statements * This class represents the statements
...@@ -392,8 +396,7 @@ public class AlterTableAlterColumn extends CommandWithColumns { ...@@ -392,8 +396,7 @@ public class AlterTableAlterColumn extends CommandWithColumns {
data.session = session; data.session = session;
Table newTable = getSchema().createTable(data); Table newTable = getSchema().createTable(data);
newTable.setComment(table.getComment()); newTable.setComment(table.getComment());
StringBuilder buff = new StringBuilder(); String newTableSQL = newTable.getCreateSQL();
buff.append(newTable.getCreateSQL());
StringBuilder columnList = new StringBuilder(); StringBuilder columnList = new StringBuilder();
for (Column nc : newColumns) { for (Column nc : newColumns) {
if (columnList.length() > 0) { if (columnList.length() > 0) {
...@@ -407,22 +410,15 @@ public class AlterTableAlterColumn extends CommandWithColumns { ...@@ -407,22 +410,15 @@ public class AlterTableAlterColumn extends CommandWithColumns {
columnList.append(nc.getSQL()); 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(); String newTableName = newTable.getName();
Schema newTableSchema = newTable.getSchema(); Schema newTableSchema = newTable.getSchema();
newTable.removeChildrenAndResources(session); newTable.removeChildrenAndResources(session);
execute(newTableSQL, true); execute(newTableSQL, true);
newTable = newTableSchema.getTableOrView(session, newTableName); newTable = newTableSchema.getTableOrView(session, newTableName);
ArrayList<String> triggers = new ArrayList<>(); ArrayList<String> children = Utils.newSmallArrayList();
ArrayList<String> triggers = Utils.newSmallArrayList();
boolean hasDelegateIndex = false;
for (DbObject child : table.getChildren()) { for (DbObject child : table.getChildren()) {
if (child instanceof Sequence) { if (child instanceof Sequence) {
continue; continue;
...@@ -456,10 +452,49 @@ public class AlterTableAlterColumn extends CommandWithColumns { ...@@ -456,10 +452,49 @@ public class AlterTableAlterColumn extends CommandWithColumns {
if (child instanceof TriggerObject) { if (child instanceof TriggerObject) {
triggers.add(sql); triggers.add(sql);
} else { } else {
if (!hasDelegateIndex) {
Index index = null;
if (child instanceof ConstraintUnique) {
ConstraintUnique constraint = (ConstraintUnique) child;
if (constraint.getConstraintType() == Constraint.Type.PRIMARY_KEY) {
index = constraint.getUniqueIndex();
}
} else if (child instanceof Index) {
index = (Index) child;
}
if (index != null
&& TableBase.getMainIndexColumn(index.getIndexType(), index.getIndexColumns())
!= SearchRow.ROWID_INDEX) {
execute(sql, true); execute(sql, true);
hasDelegateIndex = true;
continue;
}
} }
children.add(sql);
} }
} }
}
StringBuilder buff = new StringBuilder();
buff.append("INSERT INTO ").append(newTable.getSQL());
buff.append(" SELECT ");
if (columnList.length() == 0) {
// special case: insert into test select * from
buff.append('*');
} else {
buff.append(columnList);
}
buff.append(" FROM ").append(table.getSQL());
try {
execute(buff.toString(), true);
} catch (Throwable t) {
// data was not inserted due to data conversion error or some
// unexpected reason
execute("DROP TABLE " + newTable.getSQL(), true);
throw t;
}
for (String sql : children) {
execute(sql, true);
}
table.setModified(); table.setModified();
// remove the sequences from the columns (except dropped columns) // remove the sequences from the columns (except dropped columns)
// otherwise the sequence is dropped if the table is dropped // otherwise the sequence is dropped if the table is dropped
......
...@@ -35,7 +35,6 @@ import org.h2.mvstore.tx.Transaction; ...@@ -35,7 +35,6 @@ import org.h2.mvstore.tx.Transaction;
import org.h2.mvstore.tx.TransactionStore; import org.h2.mvstore.tx.TransactionStore;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.result.SearchRow; import org.h2.result.SearchRow;
import org.h2.result.SortOrder;
import org.h2.schema.SchemaObject; import org.h2.schema.SchemaObject;
import org.h2.table.Column; import org.h2.table.Column;
import org.h2.table.IndexColumn; import org.h2.table.IndexColumn;
...@@ -504,8 +503,8 @@ public class MVTable extends TableBase { ...@@ -504,8 +503,8 @@ public class MVTable extends TableBase {
database.lockMeta(session); database.lockMeta(session);
} }
MVIndex index; MVIndex index;
int mainIndexColumn; int mainIndexColumn = primaryIndex.getMainIndexColumn() != SearchRow.ROWID_INDEX
mainIndexColumn = getMainIndexColumn(indexType, cols); ? SearchRow.ROWID_INDEX : getMainIndexColumn(indexType, cols);
if (database.isStarting()) { if (database.isStarting()) {
if (transactionStore.hasMap("index." + indexId)) { if (transactionStore.hasMap("index." + indexId)) {
mainIndexColumn = SearchRow.ROWID_INDEX; mainIndexColumn = SearchRow.ROWID_INDEX;
...@@ -646,29 +645,6 @@ public class MVTable extends TableBase { ...@@ -646,29 +645,6 @@ public class MVTable extends TableBase {
} }
} }
private int getMainIndexColumn(IndexType indexType, IndexColumn[] cols) {
if (primaryIndex.getMainIndexColumn() != SearchRow.ROWID_INDEX) {
return SearchRow.ROWID_INDEX;
}
if (!indexType.isPrimaryKey() || cols.length != 1) {
return SearchRow.ROWID_INDEX;
}
IndexColumn first = cols[0];
if (first.sortType != SortOrder.ASCENDING) {
return SearchRow.ROWID_INDEX;
}
switch (first.column.getType()) {
case Value.BYTE:
case Value.SHORT:
case Value.INT:
case Value.LONG:
break;
default:
return SearchRow.ROWID_INDEX;
}
return first.column.getColumnId();
}
private static void addRowsToIndex(Session session, ArrayList<Row> list, private static void addRowsToIndex(Session session, ArrayList<Row> list,
Index index) { Index index) {
sortRows(list, index); sortRows(list, index);
......
...@@ -36,7 +36,6 @@ import org.h2.index.TreeIndex; ...@@ -36,7 +36,6 @@ import org.h2.index.TreeIndex;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.message.Trace; import org.h2.message.Trace;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.result.SortOrder;
import org.h2.schema.SchemaObject; import org.h2.schema.SchemaObject;
import org.h2.util.MathUtils; import org.h2.util.MathUtils;
import org.h2.util.Utils; import org.h2.util.Utils;
...@@ -199,7 +198,8 @@ public class RegularTable extends TableBase { ...@@ -199,7 +198,8 @@ public class RegularTable extends TableBase {
if (database.isStarting() && if (database.isStarting() &&
database.getPageStore().getRootPageId(indexId) != 0) { database.getPageStore().getRootPageId(indexId) != 0) {
mainIndexColumn = -1; mainIndexColumn = -1;
} else if (!database.isStarting() && mainIndex.getRowCount(session) != 0) { } else if (!database.isStarting() && mainIndex.getRowCount(session) != 0
|| mainIndex.getMainIndexColumn() != -1) {
mainIndexColumn = -1; mainIndexColumn = -1;
} else { } else {
mainIndexColumn = getMainIndexColumn(indexType, cols); mainIndexColumn = getMainIndexColumn(indexType, cols);
...@@ -289,29 +289,6 @@ public class RegularTable extends TableBase { ...@@ -289,29 +289,6 @@ public class RegularTable extends TableBase {
return index; return index;
} }
private int getMainIndexColumn(IndexType indexType, IndexColumn[] cols) {
if (mainIndex.getMainIndexColumn() != -1) {
return -1;
}
if (!indexType.isPrimaryKey() || cols.length != 1) {
return -1;
}
IndexColumn first = cols[0];
if (first.sortType != SortOrder.ASCENDING) {
return -1;
}
switch (first.column.getType()) {
case Value.BYTE:
case Value.SHORT:
case Value.INT:
case Value.LONG:
break;
default:
return -1;
}
return first.column.getColumnId();
}
@Override @Override
public boolean canGetRowCount() { public boolean canGetRowCount() {
return true; return true;
......
...@@ -10,9 +10,13 @@ import java.util.List; ...@@ -10,9 +10,13 @@ import java.util.List;
import org.h2.command.ddl.CreateTableData; import org.h2.command.ddl.CreateTableData;
import org.h2.engine.Database; import org.h2.engine.Database;
import org.h2.engine.DbSettings; import org.h2.engine.DbSettings;
import org.h2.index.IndexType;
import org.h2.mvstore.db.MVTableEngine; import org.h2.mvstore.db.MVTableEngine;
import org.h2.result.SearchRow;
import org.h2.result.SortOrder;
import org.h2.util.StatementBuilder; import org.h2.util.StatementBuilder;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
import org.h2.value.Value;
/** /**
* The base class of a regular table, or a user defined table. * The base class of a regular table, or a user defined table.
...@@ -31,6 +35,33 @@ public abstract class TableBase extends Table { ...@@ -31,6 +35,33 @@ public abstract class TableBase extends Table {
private final boolean globalTemporary; private final boolean globalTemporary;
/**
* Returns main index column if index is an primary key index and has only
* one column with _ROWID_ compatible data type.
*
* @param indexType type of an index
* @param cols columns of the index
* @return main index column or {@link SearchRow#ROWID_INDEX}
*/
public static int getMainIndexColumn(IndexType indexType, IndexColumn[] cols) {
if (!indexType.isPrimaryKey() || cols.length != 1) {
return SearchRow.ROWID_INDEX;
}
IndexColumn first = cols[0];
if (first.sortType != SortOrder.ASCENDING) {
return SearchRow.ROWID_INDEX;
}
switch (first.column.getType()) {
case Value.BYTE:
case Value.SHORT:
case Value.INT:
case Value.LONG:
return first.column.getColumnId();
default:
return SearchRow.ROWID_INDEX;
}
}
public TableBase(CreateTableData data) { public TableBase(CreateTableData data) {
super(data.schema, data.id, data.tableName, super(data.schema, data.id, data.tableName,
data.persistIndexes, data.persistData); data.persistIndexes, data.persistData);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论