提交 70ef2e60 authored 作者: noelgrandin@gmail.com's avatar noelgrandin@gmail.com

add support for IF NOT EXISTS in ALTER TABLE

上级 e9571b3c
......@@ -208,7 +208,7 @@ ALTER SEQUENCE SEQ_ID RESTART WITH 1000
"
"Commands (DDL)","ALTER TABLE ADD","
ALTER TABLE tableName ADD name dataType [ DEFAULT expression ]
ALTER TABLE tableName ADD [ IF NOT EXISTS ] name dataType [ DEFAULT expression ]
[ [ NOT ] NULL ] [ AUTO_INCREMENT | IDENTITY ] [ BEFORE columnName ]
","
Adds a new column to a table.
......
......@@ -34,6 +34,7 @@ Change Log
</li><li>Linked tables: the index conditions was sometimes not used when querying the remote database.
</li><li>Issue 294: OSGi: the versions were missing in manifest package exports.
</li><li>The option -baseDir didn't work with symbolic links.
</li><li>Support for ALTER TABLE ADD COLUMN IF NOT EXISTS.
</li><li>Database-level connection settings could only be set in the database URL,
but not using the Properties parameter of DriverManager.getConnection(String url, Properties info).
</li></ul>
......
......@@ -505,7 +505,6 @@ See also <a href="build.html#providing_patches">Providing Patches</a>.
disable autocommit for all connections.
</li><li>Compatibility with MS Access: support "&amp;" to concatenate text.
</li><li>The BACKUP statement should not synchronize on the database, and therefore should not block other users.
</li><li>Support ALTER TABLE ADD COLUMN IF NOT EXISTS.
</li><li>Document the database file format.
</li><li>Support reading LOBs.
</li><li>Require appending DANGEROUS=TRUE when using certain dangerous settings such as
......
......@@ -447,6 +447,11 @@ public interface CommandInterface {
*/
int SHUTDOWN_DEFRAG = 84;
/**
* The type of a ALTER TABLE ADD IF NOT EXISTS statement.
*/
int ALTER_TABLE_ADD_COLUMN_IF_NOT_EXISTS = 85;
/**
* Get command type.
*
......
......@@ -4778,9 +4778,10 @@ public class Parser {
private AlterTableAlterColumn parseAlterTableAddColumn(Table table) {
readIf("COLUMN");
boolean ifNotExists = readIfNoExists();
Schema schema = table.getSchema();
AlterTableAlterColumn command = new AlterTableAlterColumn(session, schema);
command.setType(CommandInterface.ALTER_TABLE_ADD_COLUMN);
command.setType(ifNotExists ? CommandInterface.ALTER_TABLE_ADD_COLUMN_IF_NOT_EXISTS : CommandInterface.ALTER_TABLE_ADD_COLUMN);
command.setTable(table);
String columnName = readColumnIdentifier();
Column column = parseColumnForTable(columnName, true);
......
......@@ -35,6 +35,7 @@ import org.h2.util.New;
/**
* This class represents the statements
* ALTER TABLE ADD,
* ALTER TABLE ADD IF NOT EXISTS,
* ALTER TABLE ALTER COLUMN,
* ALTER TABLE ALTER COLUMN RESTART,
* ALTER TABLE ALTER COLUMN SELECTIVITY,
......@@ -122,6 +123,13 @@ public class AlterTableAlterColumn extends SchemaCommand {
copyData();
break;
}
case CommandInterface.ALTER_TABLE_ADD_COLUMN_IF_NOT_EXISTS: {
if (!table.doesColumnExist(newColumn.getName())) {
convertAutoIncrementColumn(newColumn);
copyData();
}
break;
}
case CommandInterface.ALTER_TABLE_DROP_COLUMN: {
if (table.getColumns().length == 1) {
throw DbException.get(ErrorCode.CANNOT_DROP_LAST_COLUMN, oldColumn.getSQL());
......@@ -216,7 +224,8 @@ public class AlterTableAlterColumn extends SchemaCommand {
if (type == CommandInterface.ALTER_TABLE_DROP_COLUMN) {
int position = oldColumn.getColumnId();
newColumns.remove(position);
} else if (type == CommandInterface.ALTER_TABLE_ADD_COLUMN) {
} else if (type == CommandInterface.ALTER_TABLE_ADD_COLUMN
|| type == CommandInterface.ALTER_TABLE_ADD_COLUMN_IF_NOT_EXISTS) {
int position;
if (addBefore == null) {
position = columns.length;
......@@ -254,7 +263,8 @@ public class AlterTableAlterColumn extends SchemaCommand {
if (columnList.length() > 0) {
columnList.append(", ");
}
if (type == CommandInterface.ALTER_TABLE_ADD_COLUMN && nc == newColumn) {
if ((type == CommandInterface.ALTER_TABLE_ADD_COLUMN
|| type == CommandInterface.ALTER_TABLE_ADD_COLUMN_IF_NOT_EXISTS) && nc == newColumn) {
Expression def = nc.getDefaultExpression();
columnList.append(def == null ? "NULL" : def.getSQL());
} else {
......
......@@ -76,7 +76,7 @@ ALTER SEQUENCE sequenceName [ RESTART WITH long ] [ INCREMENT BY long ]
","
Changes the next value and the increment of a sequence."
"Commands (DDL)","ALTER TABLE ADD","
ALTER TABLE tableName ADD name dataType [ DEFAULT expression ]
ALTER TABLE tableName ADD [ IF NOT EXISTS ] name dataType [ DEFAULT expression ]
[ [ NOT ] NULL ] [ AUTO_INCREMENT | IDENTITY ] [ BEFORE columnName ]
","
Adds a new column to a table."
......
......@@ -589,6 +589,16 @@ public abstract class Table extends SchemaObjectBase {
return column;
}
/**
* Does the column with the given name exist?
*
* @param columnName the column name
* @return true if the column exists
*/
public boolean doesColumnExist(String columnName) {
return columnMap.containsKey(columnName);
}
/**
* Get the best plan for the given search mask.
*
......
......@@ -38,6 +38,7 @@ public class TestAlter extends TestBase {
testAlterTableDropColumnWithReferences();
testAlterTableAlterColumn();
testAlterTableDropIdentityColumn();
testAlterTableAddColumnIfNotExists();
conn.close();
deleteDb("alter");
}
......@@ -123,4 +124,14 @@ public class TestAlter extends TestBase {
stat.execute("drop table t");
}
private void testAlterTableAddColumnIfNotExists() throws SQLException {
stat.execute("create table t(x varchar) as select 'x'");
stat.execute("alter table t add if not exists x int");
stat.execute("drop table t");
stat.execute("create table t(x varchar) as select 'x'");
stat.execute("alter table t add if not exists y int");
stat.execute("select x, y from t");
stat.execute("drop table t");
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论