提交 03ef250f authored 作者: noelgrandin's avatar noelgrandin

Contribution from Steve McLeod steve.mcleod@gmail.com

Modify ALTER TABLE ADD to support adding multiple columns in one command.
上级 51fef277
...@@ -211,8 +211,9 @@ ALTER SEQUENCE SEQ_ID RESTART WITH 1000 ...@@ -211,8 +211,9 @@ ALTER SEQUENCE SEQ_ID RESTART WITH 1000
" "
"Commands (DDL)","ALTER TABLE ADD"," "Commands (DDL)","ALTER TABLE ADD","
ALTER TABLE tableName ADD [ IF NOT EXISTS ] name dataType [ DEFAULT expression ] ALTER TABLE tableName ADD [ COLUMN ]
[ [ NOT ] NULL ] [ AUTO_INCREMENT | IDENTITY ] [ BEFORE columnName ] { [ IF NOT EXISTS ] columnDefinition [ BEFORE columnName ]
| ( { columnDefinition } [,...] ) }
"," ","
Adds a new column to a table. Adds a new column to a table.
This command commits an open transaction. This command commits an open transaction.
......
...@@ -18,7 +18,8 @@ Change Log ...@@ -18,7 +18,8 @@ Change Log
<h1>Change Log</h1> <h1>Change Log</h1>
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul><li>Issue 380: ALTER TABLE ADD FOREIGN KEY with an explicit index didn't verify <ul><li>ALTER TABLE ADD can now add more than one column at a time.
</li><li>Issue 380: ALTER TABLE ADD FOREIGN KEY with an explicit index didn't verify
the index can be used, which would lead to a NullPointerException later on. the index can be used, which would lead to a NullPointerException later on.
</li><li>The wrong kind of exception (NullPointerException) was thrown in a UNION query </li><li>The wrong kind of exception (NullPointerException) was thrown in a UNION query
with an incorrect ORDER BY expression. with an incorrect ORDER BY expression.
......
...@@ -4948,19 +4948,37 @@ public class Parser { ...@@ -4948,19 +4948,37 @@ public class Parser {
private AlterTableAlterColumn parseAlterTableAddColumn(Table table) { private AlterTableAlterColumn parseAlterTableAddColumn(Table table) {
readIf("COLUMN"); readIf("COLUMN");
boolean ifNotExists = readIfNoExists();
Schema schema = table.getSchema(); Schema schema = table.getSchema();
AlterTableAlterColumn command = new AlterTableAlterColumn(session, schema); AlterTableAlterColumn command = new AlterTableAlterColumn(session, schema);
command.setIfNotExists(ifNotExists);
command.setType(CommandInterface.ALTER_TABLE_ADD_COLUMN); command.setType(CommandInterface.ALTER_TABLE_ADD_COLUMN);
command.setTable(table); command.setTable(table);
ArrayList<Column> columnsToAdd = New.arrayList();
boolean b = readIf("(");
if (b) {
command.setIfNotExists(false);
do{
String columnName = readColumnIdentifier();
Column column = parseColumnForTable(columnName, true);
columnsToAdd.add(column);
} while (readIf(","));
read(")");
command.setNewColumns(columnsToAdd);
} else {
boolean ifNotExists = readIfNoExists();
command.setIfNotExists(ifNotExists);
String columnName = readColumnIdentifier(); String columnName = readColumnIdentifier();
Column column = parseColumnForTable(columnName, true); Column column = parseColumnForTable(columnName, true);
command.setNewColumn(column); columnsToAdd.add(column);
if (readIf("BEFORE")) { if (readIf("BEFORE")) {
command.setAddBefore(readColumnIdentifier()); command.setAddBefore(readColumnIdentifier());
} }
}
command.setNewColumns(columnsToAdd);
return command; return command;
} }
private int parseAction() { private int parseAction() {
......
...@@ -55,6 +55,7 @@ public class AlterTableAlterColumn extends SchemaCommand { ...@@ -55,6 +55,7 @@ public class AlterTableAlterColumn extends SchemaCommand {
private Expression newSelectivity; private Expression newSelectivity;
private String addBefore; private String addBefore;
private boolean ifNotExists; private boolean ifNotExists;
private ArrayList<Column> columnsToAdd;
public AlterTableAlterColumn(Session session, Schema schema) { public AlterTableAlterColumn(Session session, Schema schema) {
super(session, schema); super(session, schema);
...@@ -82,6 +83,11 @@ public class AlterTableAlterColumn extends SchemaCommand { ...@@ -82,6 +83,11 @@ public class AlterTableAlterColumn extends SchemaCommand {
if (newColumn != null) { if (newColumn != null) {
checkDefaultReferencesTable(newColumn.getDefaultExpression()); checkDefaultReferencesTable(newColumn.getDefaultExpression());
} }
if (columnsToAdd != null) {
for (Column column : columnsToAdd) {
checkDefaultReferencesTable(column.getDefaultExpression());
}
}
switch (type) { switch (type) {
case CommandInterface.ALTER_TABLE_ALTER_COLUMN_NOT_NULL: { case CommandInterface.ALTER_TABLE_ALTER_COLUMN_NOT_NULL: {
if (!oldColumn.isNullable()) { if (!oldColumn.isNullable()) {
...@@ -134,10 +140,13 @@ public class AlterTableAlterColumn extends SchemaCommand { ...@@ -134,10 +140,13 @@ public class AlterTableAlterColumn extends SchemaCommand {
break; break;
} }
case CommandInterface.ALTER_TABLE_ADD_COLUMN: { case CommandInterface.ALTER_TABLE_ADD_COLUMN: {
if (ifNotExists && table.doesColumnExist(newColumn.getName())) { // ifNotExists only supported for single column add
if (ifNotExists && columnsToAdd.size() == 1 && table.doesColumnExist(columnsToAdd.get(0).getName())) {
break; break;
} }
convertAutoIncrementColumn(newColumn); for (Column column : columnsToAdd) {
convertAutoIncrementColumn(column);
}
copyData(); copyData();
break; break;
} }
...@@ -266,7 +275,9 @@ public class AlterTableAlterColumn extends SchemaCommand { ...@@ -266,7 +275,9 @@ public class AlterTableAlterColumn extends SchemaCommand {
} else { } else {
position = table.getColumn(addBefore).getColumnId(); position = table.getColumn(addBefore).getColumnId();
} }
newColumns.add(position, newColumn); for (Column column : columnsToAdd) {
newColumns.add(position++, column);
}
} else if (type == CommandInterface.ALTER_TABLE_ALTER_COLUMN_CHANGE_TYPE) { } else if (type == CommandInterface.ALTER_TABLE_ALTER_COLUMN_CHANGE_TYPE) {
int position = oldColumn.getColumnId(); int position = oldColumn.getColumnId();
newColumns.remove(position); newColumns.remove(position);
...@@ -298,7 +309,7 @@ public class AlterTableAlterColumn extends SchemaCommand { ...@@ -298,7 +309,7 @@ public class AlterTableAlterColumn extends SchemaCommand {
if (columnList.length() > 0) { if (columnList.length() > 0) {
columnList.append(", "); columnList.append(", ");
} }
if (type == CommandInterface.ALTER_TABLE_ADD_COLUMN && nc == newColumn) { if (type == CommandInterface.ALTER_TABLE_ADD_COLUMN && columnsToAdd.contains(nc)) {
Expression def = nc.getDefaultExpression(); Expression def = nc.getDefaultExpression();
columnList.append(def == null ? "NULL" : def.getSQL()); columnList.append(def == null ? "NULL" : def.getSQL());
} else { } else {
...@@ -470,4 +481,7 @@ public class AlterTableAlterColumn extends SchemaCommand { ...@@ -470,4 +481,7 @@ public class AlterTableAlterColumn extends SchemaCommand {
this.ifNotExists = ifNotExists; this.ifNotExists = ifNotExists;
} }
public void setNewColumns(ArrayList<Column> columnsToAdd) {
this.columnsToAdd = columnsToAdd;
}
} }
...@@ -40,6 +40,7 @@ public class TestAlter extends TestBase { ...@@ -40,6 +40,7 @@ public class TestAlter extends TestBase {
testAlterTableAlterColumn(); testAlterTableAlterColumn();
testAlterTableDropIdentityColumn(); testAlterTableDropIdentityColumn();
testAlterTableAddColumnIfNotExists(); testAlterTableAddColumnIfNotExists();
testAlterTableAddMultipleColumns();
testAlterTableAlterColumn2(); testAlterTableAlterColumn2();
conn.close(); conn.close();
deleteDb("alter"); deleteDb("alter");
...@@ -136,6 +137,15 @@ public class TestAlter extends TestBase { ...@@ -136,6 +137,15 @@ public class TestAlter extends TestBase {
stat.execute("drop table t"); stat.execute("drop table t");
} }
private void testAlterTableAddMultipleColumns() throws SQLException {
stat.execute("create table t(x varchar) as select 'x'");
stat.execute("alter table t add (y int, z varchar)");
stat.execute("drop table t");
stat.execute("create table t(x varchar) as select 'x'");
stat.execute("alter table t add (y int)");
stat.execute("drop table t");
}
private void testAlterTableAlterColumn2() throws SQLException { private void testAlterTableAlterColumn2() throws SQLException {
// ensure that increasing a VARCHAR columns length takes effect because // ensure that increasing a VARCHAR columns length takes effect because
// we optimize this case // we optimize this case
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论