提交 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 ...@@ -208,7 +208,7 @@ ALTER SEQUENCE SEQ_ID RESTART WITH 1000
" "
"Commands (DDL)","ALTER TABLE ADD"," "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 ] [ [ NOT ] NULL ] [ AUTO_INCREMENT | IDENTITY ] [ BEFORE columnName ]
"," ","
Adds a new column to a table. Adds a new column to a table.
......
...@@ -34,6 +34,7 @@ Change Log ...@@ -34,6 +34,7 @@ Change Log
</li><li>Linked tables: the index conditions was sometimes not used when querying the remote database. </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>Issue 294: OSGi: the versions were missing in manifest package exports.
</li><li>The option -baseDir didn't work with symbolic links. </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, </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). but not using the Properties parameter of DriverManager.getConnection(String url, Properties info).
</li></ul> </li></ul>
......
...@@ -505,7 +505,6 @@ See also <a href="build.html#providing_patches">Providing Patches</a>. ...@@ -505,7 +505,6 @@ See also <a href="build.html#providing_patches">Providing Patches</a>.
disable autocommit for all connections. disable autocommit for all connections.
</li><li>Compatibility with MS Access: support "&amp;" to concatenate text. </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>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>Document the database file format.
</li><li>Support reading LOBs. </li><li>Support reading LOBs.
</li><li>Require appending DANGEROUS=TRUE when using certain dangerous settings such as </li><li>Require appending DANGEROUS=TRUE when using certain dangerous settings such as
......
...@@ -447,6 +447,11 @@ public interface CommandInterface { ...@@ -447,6 +447,11 @@ public interface CommandInterface {
*/ */
int SHUTDOWN_DEFRAG = 84; 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. * Get command type.
* *
......
...@@ -4778,9 +4778,10 @@ public class Parser { ...@@ -4778,9 +4778,10 @@ 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.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); command.setTable(table);
String columnName = readColumnIdentifier(); String columnName = readColumnIdentifier();
Column column = parseColumnForTable(columnName, true); Column column = parseColumnForTable(columnName, true);
......
...@@ -35,6 +35,7 @@ import org.h2.util.New; ...@@ -35,6 +35,7 @@ import org.h2.util.New;
/** /**
* This class represents the statements * This class represents the statements
* ALTER TABLE ADD, * ALTER TABLE ADD,
* ALTER TABLE ADD IF NOT EXISTS,
* ALTER TABLE ALTER COLUMN, * ALTER TABLE ALTER COLUMN,
* ALTER TABLE ALTER COLUMN RESTART, * ALTER TABLE ALTER COLUMN RESTART,
* ALTER TABLE ALTER COLUMN SELECTIVITY, * ALTER TABLE ALTER COLUMN SELECTIVITY,
...@@ -122,6 +123,13 @@ public class AlterTableAlterColumn extends SchemaCommand { ...@@ -122,6 +123,13 @@ public class AlterTableAlterColumn extends SchemaCommand {
copyData(); copyData();
break; 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: { case CommandInterface.ALTER_TABLE_DROP_COLUMN: {
if (table.getColumns().length == 1) { if (table.getColumns().length == 1) {
throw DbException.get(ErrorCode.CANNOT_DROP_LAST_COLUMN, oldColumn.getSQL()); throw DbException.get(ErrorCode.CANNOT_DROP_LAST_COLUMN, oldColumn.getSQL());
...@@ -216,7 +224,8 @@ public class AlterTableAlterColumn extends SchemaCommand { ...@@ -216,7 +224,8 @@ public class AlterTableAlterColumn extends SchemaCommand {
if (type == CommandInterface.ALTER_TABLE_DROP_COLUMN) { if (type == CommandInterface.ALTER_TABLE_DROP_COLUMN) {
int position = oldColumn.getColumnId(); int position = oldColumn.getColumnId();
newColumns.remove(position); 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; int position;
if (addBefore == null) { if (addBefore == null) {
position = columns.length; position = columns.length;
...@@ -254,7 +263,8 @@ public class AlterTableAlterColumn extends SchemaCommand { ...@@ -254,7 +263,8 @@ 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
|| type == CommandInterface.ALTER_TABLE_ADD_COLUMN_IF_NOT_EXISTS) && nc == newColumn) {
Expression def = nc.getDefaultExpression(); Expression def = nc.getDefaultExpression();
columnList.append(def == null ? "NULL" : def.getSQL()); columnList.append(def == null ? "NULL" : def.getSQL());
} else { } else {
......
...@@ -76,7 +76,7 @@ ALTER SEQUENCE sequenceName [ RESTART WITH long ] [ INCREMENT BY long ] ...@@ -76,7 +76,7 @@ ALTER SEQUENCE sequenceName [ RESTART WITH long ] [ INCREMENT BY long ]
"," ","
Changes the next value and the increment of a sequence." Changes the next value and the increment of a sequence."
"Commands (DDL)","ALTER TABLE ADD"," "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 ] [ [ NOT ] NULL ] [ AUTO_INCREMENT | IDENTITY ] [ BEFORE columnName ]
"," ","
Adds a new column to a table." Adds a new column to a table."
......
...@@ -589,6 +589,16 @@ public abstract class Table extends SchemaObjectBase { ...@@ -589,6 +589,16 @@ public abstract class Table extends SchemaObjectBase {
return column; 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. * Get the best plan for the given search mask.
* *
......
...@@ -38,6 +38,7 @@ public class TestAlter extends TestBase { ...@@ -38,6 +38,7 @@ public class TestAlter extends TestBase {
testAlterTableDropColumnWithReferences(); testAlterTableDropColumnWithReferences();
testAlterTableAlterColumn(); testAlterTableAlterColumn();
testAlterTableDropIdentityColumn(); testAlterTableDropIdentityColumn();
testAlterTableAddColumnIfNotExists();
conn.close(); conn.close();
deleteDb("alter"); deleteDb("alter");
} }
...@@ -123,4 +124,14 @@ public class TestAlter extends TestBase { ...@@ -123,4 +124,14 @@ public class TestAlter extends TestBase {
stat.execute("drop table t"); 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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论