提交 507d02d0 authored 作者: Thomas Mueller Graf's avatar Thomas Mueller Graf

Merge branch 'master' of https://github.com/h2database/h2database

......@@ -289,12 +289,13 @@ ALTER TABLE TEST ALTER COLUMN NAME SET NULL;
"
"Commands (DDL)","ALTER TABLE DROP COLUMN","
ALTER TABLE tableName DROP COLUMN [ IF EXISTS ] columnName
ALTER TABLE tableName DROP COLUMN [ IF EXISTS ] ( columnName [,...] )
","
Removes a column from a table.
Removes column(s) from a table.
This command commits an open transaction in this connection.
","
ALTER TABLE TEST DROP COLUMN NAME
ALTER TABLE TEST DROP COLUMN NAME1, NAME2
"
"Commands (DDL)","ALTER TABLE DROP CONSTRAINT","
......
......@@ -28,6 +28,8 @@ Change Log
<h2>Version 1.4.189 Beta (2015-09-13)</h2>
<ul>
<li>Add support for dropping multiple columns in ALTER TABLE DROP COLUMN...
</li>
<li>Fix bug in XA management when doing rollback after prepare. Patch by Stephane Lacoin.
</li>
<li>MVStore CLOB and BLOB: An exception with the message "Block not found" could be thrown
......
......@@ -5415,12 +5415,17 @@ public class Parser {
AlterTableAlterColumn command = new AlterTableAlterColumn(
session, table.getSchema());
command.setType(CommandInterface.ALTER_TABLE_DROP_COLUMN);
ArrayList<Column> columnsToRemove = New.arrayList();
do {
String columnName = readColumnIdentifier();
command.setTable(table);
if (ifExists && !table.doesColumnExist(columnName)) {
return new NoOperation(session);
}
command.setOldColumn(table.getColumn(columnName));
Column column = table.getColumn(columnName);
columnsToRemove.add(column);
} while (readIf(","));
command.setTable(table);
command.setColumnsToRemove(columnsToRemove);
return command;
}
} else if (readIf("CHANGE")) {
......
......@@ -7,7 +7,7 @@ package org.h2.command.ddl;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import org.h2.api.ErrorCode;
import org.h2.command.CommandInterface;
import org.h2.command.Parser;
......@@ -57,6 +57,7 @@ public class AlterTableAlterColumn extends SchemaCommand {
private String addAfter;
private boolean ifNotExists;
private ArrayList<Column> columnsToAdd;
private ArrayList<Column> columnsToRemove;
public AlterTableAlterColumn(Session session, Schema schema) {
super(session, schema);
......@@ -85,7 +86,6 @@ public class AlterTableAlterColumn extends SchemaCommand {
session.getUser().checkRight(table, Right.ALL);
table.checkSupportAlter();
table.lock(session, true, true);
Sequence sequence = oldColumn == null ? null : oldColumn.getSequence();
if (newColumn != null) {
checkDefaultReferencesTable(newColumn.getDefaultExpression());
}
......@@ -116,6 +116,7 @@ public class AlterTableAlterColumn extends SchemaCommand {
break;
}
case CommandInterface.ALTER_TABLE_ALTER_COLUMN_DEFAULT: {
Sequence sequence = oldColumn == null ? null : oldColumn.getSequence();
checkDefaultReferencesTable(defaultExpression);
oldColumn.setSequence(null);
oldColumn.setDefaultExpression(session, defaultExpression);
......@@ -162,11 +163,11 @@ public class AlterTableAlterColumn extends SchemaCommand {
break;
}
case CommandInterface.ALTER_TABLE_DROP_COLUMN: {
if (table.getColumns().length == 1) {
if (table.getColumns().length - columnsToRemove.size() < 1) {
throw DbException.get(ErrorCode.CANNOT_DROP_LAST_COLUMN,
oldColumn.getSQL());
columnsToRemove.get(0).getSQL());
}
table.dropSingleColumnConstraintsAndIndexes(session, oldColumn);
table.dropMultipleColumnsConstraintsAndIndexes(session, columnsToRemove);
copyData();
break;
}
......@@ -282,8 +283,20 @@ public class AlterTableAlterColumn extends SchemaCommand {
newColumns.add(col.getClone());
}
if (type == CommandInterface.ALTER_TABLE_DROP_COLUMN) {
int position = oldColumn.getColumnId();
newColumns.remove(position);
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) {
......@@ -509,4 +522,8 @@ public class AlterTableAlterColumn extends SchemaCommand {
public void setNewColumns(ArrayList<Column> columnsToAdd) {
this.columnsToAdd = columnsToAdd;
}
public void setColumnsToRemove(ArrayList<Column> columnsToRemove) {
this.columnsToRemove = columnsToRemove;
}
}
......@@ -9,7 +9,6 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import org.h2.api.ErrorCode;
import org.h2.command.Prepared;
import org.h2.constraint.Constraint;
......@@ -531,19 +530,20 @@ public abstract class Table extends SchemaObjectBase {
}
/**
* Check that this column is not referenced by a multi-column constraint or
* Check that these columns are not referenced by a multi-column constraint or
* multi-column index. If it is, an exception is thrown. Single-column
* references and indexes are dropped.
*
* @param session the session
* @param col the column
* @param columsToDrop the columns to drop
* @throws DbException if the column is referenced by multi-column
* constraints or indexes
*/
public void dropSingleColumnConstraintsAndIndexes(Session session,
Column col) {
ArrayList<Constraint> constraintsToDrop = New.arrayList();
public void dropMultipleColumnsConstraintsAndIndexes(Session session,
ArrayList<Column> columsToDrop) {
HashSet<Constraint> constraintsToDrop = New.hashSet();
if (constraints != null) {
for (Column col : columsToDrop) {
for (int i = 0, size = constraints.size(); i < size; i++) {
Constraint constraint = constraints.get(i);
HashSet<Column> columns = constraint.getReferencedColumns(this);
......@@ -558,9 +558,11 @@ public abstract class Table extends SchemaObjectBase {
}
}
}
ArrayList<Index> indexesToDrop = New.arrayList();
}
HashSet<Index> indexesToDrop = New.hashSet();
ArrayList<Index> indexes = getIndexes();
if (indexes != null) {
for (Column col : columsToDrop) {
for (int i = 0, size = indexes.size(); i < size; i++) {
Index index = indexes.get(i);
if (index.getCreateSQL() == null) {
......@@ -577,6 +579,7 @@ public abstract class Table extends SchemaObjectBase {
}
}
}
}
for (Constraint c : constraintsToDrop) {
session.getDatabase().removeSchemaObject(session, c);
}
......
......@@ -325,11 +325,6 @@ java org.h2.test.TestAll timer
*/
public boolean splitFileSystem;
/**
* Support nested joins.
*/
public boolean nestedJoins;
/**
* If only fast tests should be run. If enabled, SSL is not tested.
*/
......
......@@ -323,9 +323,6 @@ public abstract class TestBase {
if (config.defrag) {
url = addOption(url, "DEFRAG_ALWAYS", "TRUE");
}
if (config.nestedJoins) {
url = addOption(url, "NESTED_JOINS", "TRUE");
}
return "jdbc:h2:" + url;
}
......
......@@ -10,7 +10,6 @@ import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.h2.api.ErrorCode;
import org.h2.test.TestBase;
......@@ -38,6 +37,7 @@ public class TestAlter extends TestBase {
stat = conn.createStatement();
testAlterTableAlterColumnAsSelfColumn();
testAlterTableDropColumnWithReferences();
testAlterTableDropMultipleColumns();
testAlterTableAlterColumnWithConstraint();
testAlterTableAlterColumn();
testAlterTableAddColumnIdentity();
......@@ -108,6 +108,17 @@ public class TestAlter extends TestBase {
}
private void testAlterTableDropMultipleColumns() throws SQLException {
stat.execute("create table test(id int, name varchar, name2 varchar)");
stat.execute("alter table test drop column name, name2");
stat.execute("drop table test");
stat.execute("create table test(id int, name varchar, name2 varchar)");
assertThrows(ErrorCode.CANNOT_DROP_LAST_COLUMN, stat).
execute("alter table test drop column id, name, name2");
stat.execute("drop table test");
}
/**
* Tests a bug we used to have where altering the name of a column that had
* a check constraint that referenced itself would result in not being able
......
......@@ -25,7 +25,6 @@ public class TestLimit extends TestBase {
public static void main(String... a) throws Exception {
TestBase test = TestBase.createCaller().init();
// test.config.traceTest = true;
test.config.nestedJoins = true;
test.test();
}
......
......@@ -36,15 +36,11 @@ public class TestNestedJoins extends TestBase {
public static void main(String... a) throws Exception {
TestBase test = TestBase.createCaller().init();
// test.config.traceTest = true;
test.config.nestedJoins = true;
test.test();
}
@Override
public void test() throws Exception {
if (!config.nestedJoins) {
return;
}
deleteDb("nestedJoins");
// testCases2();
testCases();
......
......@@ -35,15 +35,11 @@ public class TestOuterJoins extends TestBase {
public static void main(String... a) throws Exception {
TestBase test = TestBase.createCaller().init();
test.config.traceTest = true;
test.config.nestedJoins = true;
test.test();
}
@Override
public void test() throws Exception {
if (!config.nestedJoins) {
return;
}
deleteDb("outerJoins");
testCases();
testRandom();
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论