提交 1dd4130d authored 作者: lukaseder's avatar lukaseder

[#285] Add support for ALTER TABLE IF EXISTS

上级 5e7df467
......@@ -49,6 +49,7 @@ public class AlterTableAddConstraint extends SchemaCommand {
private String comment;
private boolean checkExisting;
private boolean primaryKeyHash;
private boolean ifTableExists;
private final boolean ifNotExists;
private ArrayList<Index> createdIndexes = New.arrayList();
......@@ -58,6 +59,10 @@ public class AlterTableAddConstraint extends SchemaCommand {
this.ifNotExists = ifNotExists;
}
public void setIfTableExists(boolean b) {
ifTableExists = b;
}
private String generateConstraintName(Table table) {
if (constraintName == null) {
constraintName = getSchema().getUniqueConstraintName(
......@@ -90,7 +95,13 @@ public class AlterTableAddConstraint extends SchemaCommand {
session.commit(true);
}
Database db = session.getDatabase();
Table table = getSchema().getTableOrView(session, tableName);
Table table = getSchema().findTableOrView(session, tableName);
if (table == null) {
if (ifTableExists) {
return 0;
}
throw DbException.get(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, tableName);
}
if (getSchema().findConstraint(session, constraintName) != null) {
if (ifNotExists) {
return 0;
......
......@@ -48,7 +48,7 @@ import org.h2.util.New;
*/
public class AlterTableAlterColumn extends SchemaCommand {
private Table table;
private String tableName;
private Column oldColumn;
private Column newColumn;
private int type;
......@@ -56,6 +56,7 @@ public class AlterTableAlterColumn extends SchemaCommand {
private Expression newSelectivity;
private String addBefore;
private String addAfter;
private boolean ifTableExists;
private boolean ifNotExists;
private ArrayList<Column> columnsToAdd;
private ArrayList<Column> columnsToRemove;
......@@ -64,8 +65,12 @@ public class AlterTableAlterColumn extends SchemaCommand {
super(session, schema);
}
public void setTable(Table table) {
this.table = table;
public void setIfTableExists(boolean b) {
ifTableExists = b;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
public void setOldColumn(Column oldColumn) {
......@@ -84,16 +89,23 @@ public class AlterTableAlterColumn extends SchemaCommand {
public int update() {
session.commit(true);
Database db = session.getDatabase();
Table table = getSchema().findTableOrView(session, tableName);
if (table == null) {
if (ifTableExists) {
return 0;
}
throw DbException.get(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, tableName);
}
session.getUser().checkRight(table, Right.ALL);
table.checkSupportAlter();
table.lock(session, true, true);
if (newColumn != null) {
checkDefaultReferencesTable(newColumn.getDefaultExpression());
checkDefaultReferencesTable(table, newColumn.getDefaultExpression());
checkClustering(newColumn);
}
if (columnsToAdd != null) {
for (Column column : columnsToAdd) {
checkDefaultReferencesTable(column.getDefaultExpression());
checkDefaultReferencesTable(table, column.getDefaultExpression());
checkClustering(column);
}
}
......@@ -103,7 +115,7 @@ public class AlterTableAlterColumn extends SchemaCommand {
// no change
break;
}
checkNoNullValues();
checkNoNullValues(table);
oldColumn.setNullable(false);
db.updateMeta(session, table);
break;
......@@ -113,17 +125,17 @@ public class AlterTableAlterColumn extends SchemaCommand {
// no change
break;
}
checkNullable();
checkNullable(table);
oldColumn.setNullable(true);
db.updateMeta(session, table);
break;
}
case CommandInterface.ALTER_TABLE_ALTER_COLUMN_DEFAULT: {
Sequence sequence = oldColumn == null ? null : oldColumn.getSequence();
checkDefaultReferencesTable(defaultExpression);
checkDefaultReferencesTable(table, defaultExpression);
oldColumn.setSequence(null);
oldColumn.setDefaultExpression(session, defaultExpression);
removeSequence(sequence);
removeSequence(table, sequence);
db.updateMeta(session, table);
break;
}
......@@ -132,7 +144,7 @@ public class AlterTableAlterColumn extends SchemaCommand {
// need to copy the table because the length is only a constraint,
// and does not affect the storage structure.
if (oldColumn.isWideningConversion(newColumn)) {
convertAutoIncrementColumn(newColumn);
convertAutoIncrementColumn(table, newColumn);
oldColumn.copy(newColumn);
db.updateMeta(session, table);
} else {
......@@ -140,12 +152,12 @@ public class AlterTableAlterColumn extends SchemaCommand {
oldColumn.setDefaultExpression(session, null);
oldColumn.setConvertNullToDefault(false);
if (oldColumn.isNullable() && !newColumn.isNullable()) {
checkNoNullValues();
checkNoNullValues(table);
} else if (!oldColumn.isNullable() && newColumn.isNullable()) {
checkNullable();
checkNullable(table);
}
convertAutoIncrementColumn(newColumn);
copyData();
convertAutoIncrementColumn(table, newColumn);
copyData(table);
}
break;
}
......@@ -162,7 +174,7 @@ public class AlterTableAlterColumn extends SchemaCommand {
table.isTemporary());
}
}
copyData();
copyData(table);
break;
}
case CommandInterface.ALTER_TABLE_DROP_COLUMN: {
......@@ -171,7 +183,7 @@ public class AlterTableAlterColumn extends SchemaCommand {
columnsToRemove.get(0).getSQL());
}
table.dropMultipleColumnsConstraintsAndIndexes(session, columnsToRemove);
copyData();
copyData(table);
break;
}
case CommandInterface.ALTER_TABLE_ALTER_COLUMN_SELECTIVITY: {
......@@ -186,7 +198,7 @@ public class AlterTableAlterColumn extends SchemaCommand {
return 0;
}
private void checkDefaultReferencesTable(Expression defaultExpression) {
private void checkDefaultReferencesTable(Table table, Expression defaultExpression) {
if (defaultExpression == null) {
return;
}
......@@ -209,7 +221,7 @@ public class AlterTableAlterColumn extends SchemaCommand {
}
}
private void convertAutoIncrementColumn(Column c) {
private void convertAutoIncrementColumn(Table table, Column c) {
if (c.isAutoIncrement()) {
if (c.isPrimaryKey()) {
c.setOriginalSQL("IDENTITY");
......@@ -221,7 +233,7 @@ public class AlterTableAlterColumn extends SchemaCommand {
}
}
private void removeSequence(Sequence sequence) {
private void removeSequence(Table table, Sequence sequence) {
if (sequence != null) {
table.removeSequence(sequence);
sequence.setBelongsToTable(false);
......@@ -230,7 +242,7 @@ public class AlterTableAlterColumn extends SchemaCommand {
}
}
private void copyData() {
private void copyData(Table table) {
if (table.isTemporary()) {
throw DbException.getUnsupportedException("TEMP TABLE");
}
......@@ -239,7 +251,7 @@ public class AlterTableAlterColumn extends SchemaCommand {
String tempName = db.getTempTableName(baseName, session);
Column[] columns = table.getColumns();
ArrayList<Column> newColumns = New.arrayList();
Table newTable = cloneTableStructure(columns, db, tempName, newColumns);
Table newTable = cloneTableStructure(table, columns, db, tempName, newColumns);
try {
// check if a view would become invalid
// (because the column to drop is referenced or so)
......@@ -289,7 +301,7 @@ public class AlterTableAlterColumn extends SchemaCommand {
}
}
private Table cloneTableStructure(Column[] columns, Database db,
private Table cloneTableStructure(Table table, Column[] columns, Database db,
String tempName, ArrayList<Column> newColumns) {
for (Column col : columns) {
newColumns.add(col.getClone());
......@@ -479,7 +491,7 @@ public class AlterTableAlterColumn extends SchemaCommand {
}
}
private void checkNullable() {
private void checkNullable(Table table) {
for (Index index : table.getIndexes()) {
if (index.getColumnIndex(oldColumn) < 0) {
continue;
......@@ -492,7 +504,7 @@ public class AlterTableAlterColumn extends SchemaCommand {
}
}
private void checkNoNullValues() {
private void checkNoNullValues(Table table) {
String sql = "SELECT COUNT(*) FROM " +
table.getSQL() + " WHERE " +
oldColumn.getSQL() + " IS NULL";
......
......@@ -20,7 +20,8 @@ import org.h2.table.Table;
*/
public class AlterTableRename extends SchemaCommand {
private Table oldTable;
private boolean ifTableExists;
private String oldTableName;
private String newTableName;
private boolean hidden;
......@@ -28,8 +29,12 @@ public class AlterTableRename extends SchemaCommand {
super(session, schema);
}
public void setOldTable(Table table) {
oldTable = table;
public void setIfTableExists(boolean b) {
ifTableExists = b;
}
public void setOldTableName(String name) {
oldTableName = name;
}
public void setNewTableName(String name) {
......@@ -40,6 +45,13 @@ public class AlterTableRename extends SchemaCommand {
public int update() {
session.commit(true);
Database db = session.getDatabase();
Table oldTable = getSchema().findTableOrView(session, oldTableName);
if (oldTable == null) {
if (ifTableExists) {
return 0;
}
throw DbException.get(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, oldTableName);
}
session.getUser().checkRight(oldTable, Right.ALL);
Table t = getSchema().findTableOrView(session, newTableName);
if (t != null && hidden && newTableName.equals(oldTable.getName())) {
......
......@@ -5,12 +5,15 @@
*/
package org.h2.command.ddl;
import org.h2.api.ErrorCode;
import org.h2.command.CommandInterface;
import org.h2.engine.Database;
import org.h2.engine.DbObject;
import org.h2.engine.Right;
import org.h2.engine.Session;
import org.h2.expression.Expression;
import org.h2.message.DbException;
import org.h2.schema.Schema;
import org.h2.table.Column;
import org.h2.table.Table;
......@@ -18,22 +21,27 @@ import org.h2.table.Table;
* This class represents the statement
* ALTER TABLE ALTER COLUMN RENAME
*/
public class AlterTableRenameColumn extends DefineCommand {
public class AlterTableRenameColumn extends SchemaCommand {
private Table table;
private Column column;
private boolean ifTableExists;
private String tableName;
private String oldName;
private String newName;
public AlterTableRenameColumn(Session session) {
super(session);
public AlterTableRenameColumn(Session session, Schema schema) {
super(session, schema);
}
public void setTable(Table table) {
this.table = table;
public void setIfTableExists(boolean b) {
this.ifTableExists = b;
}
public void setColumn(Column column) {
this.column = column;
public void setTableName(String tableName) {
this.tableName = tableName;
}
public void setOldColumnName(String oldName) {
this.oldName = oldName;
}
public void setNewColumnName(String newName) {
......@@ -44,6 +52,14 @@ public class AlterTableRenameColumn extends DefineCommand {
public int update() {
session.commit(true);
Database db = session.getDatabase();
Table table = getSchema().findTableOrView(session, tableName);
if (table == null) {
if (ifTableExists) {
return 0;
}
throw DbException.get(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, tableName);
}
Column column = table.getColumn(oldName);
session.getUser().checkRight(table, Right.ALL);
table.checkSupportAlter();
// we need to update CHECK constraint
......
......@@ -27,6 +27,7 @@ public class CreateIndex extends SchemaCommand {
private String indexName;
private IndexColumn[] indexColumns;
private boolean primaryKey, unique, hash, spatial;
private boolean ifTableExists;
private boolean ifNotExists;
private String comment;
......@@ -34,6 +35,10 @@ public class CreateIndex extends SchemaCommand {
super(session, schema);
}
public void setIfTableExists(boolean b) {
this.ifTableExists = b;
}
public void setIfNotExists(boolean ifNotExists) {
this.ifNotExists = ifNotExists;
}
......@@ -57,7 +62,13 @@ public class CreateIndex extends SchemaCommand {
}
Database db = session.getDatabase();
boolean persistent = db.isPersistent();
Table table = getSchema().getTableOrView(session, tableName);
Table table = getSchema().findTableOrView(session, tableName);
if (table == null) {
if (ifTableExists) {
return 0;
}
throw DbException.get(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, tableName);
}
if (getSchema().findIndex(session, indexName) != null) {
if (ifNotExists) {
return 0;
......
......@@ -5,6 +5,7 @@
*/
package org.h2.command.dml;
import org.h2.api.ErrorCode;
import org.h2.command.CommandInterface;
import org.h2.command.ddl.SchemaCommand;
import org.h2.engine.Right;
......@@ -19,6 +20,7 @@ import org.h2.table.Table;
*/
public class AlterTableSet extends SchemaCommand {
private boolean ifTableExists;
private String tableName;
private final int type;
......@@ -40,13 +42,23 @@ public class AlterTableSet extends SchemaCommand {
return true;
}
public void setIfTableExists(boolean b) {
this.ifTableExists = b;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
@Override
public int update() {
Table table = getSchema().getTableOrView(session, tableName);
Table table = getSchema().findTableOrView(session, tableName);
if (table == null) {
if (ifTableExists) {
return 0;
}
throw DbException.get(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, tableName);
}
session.getUser().checkRight(table, Right.ALL);
table.lock(session, true, true);
switch (type) {
......
......@@ -10227,3 +10227,207 @@ select 0 from ((
> rows: 0
};
> update count: 0
create table x(id int not null);
> ok
alter table if exists y add column a varchar;
> ok
alter table if exists x add column a varchar;
> ok
alter table if exists x add column a varchar;
> exception
alter table if exists y alter column a rename to b;
> ok
alter table if exists x alter column a rename to b;
> ok
alter table if exists x alter column a rename to b;
> exception
alter table if exists y alter column b set default 'a';
> ok
alter table if exists x alter column b set default 'a';
> ok
insert into x(id) values(1);
> update count: 1
select b from x;
> B
> -
> a
> rows: 1
delete from x;
> update count: 1
alter table if exists y alter column b drop default;
> ok
alter table if exists x alter column b drop default;
> ok
alter table if exists y alter column b set not null;
> ok
alter table if exists x alter column b set not null;
> ok
insert into x(id) values(1);
> exception
alter table if exists y alter column b drop not null;
> ok
alter table if exists x alter column b drop not null;
> ok
insert into x(id) values(1);
> update count: 1
select b from x;
> B
> ----
> null
> rows: 1
delete from x;
> update count: 1
alter table if exists y add constraint x_pk primary key (id);
> ok
alter table if exists x add constraint x_pk primary key (id);
> ok
alter table if exists x add constraint x_pk primary key (id);
> exception
insert into x(id) values(1);
> update count: 1
insert into x(id) values(1);
> exception
delete from x;
> update count: 1
alter table if exists y add constraint x_chk check (b = 'a');
> ok
alter table if exists x add constraint x_chk check (b = 'a');
> ok
alter table if exists x add constraint x_chk check (b = 'a');
> exception
insert into x(id, b) values(1, 'b');
> exception
alter table if exists y rename constraint x_chk to x_chk1;
> ok
alter table if exists x rename constraint x_chk to x_chk1;
> ok
alter table if exists x rename constraint x_chk to x_chk1;
> exception
alter table if exists y drop constraint x_chk1;
> ok
alter table if exists x drop constraint x_chk1;
> ok
alter table if exists y rename to z;
> ok
alter table if exists x rename to z;
> ok
alter table if exists x rename to z;
> ok
insert into z(id, b) values(1, 'b');
> update count: 1
delete from z;
> update count: 1
alter table if exists y add constraint z_uk unique (b);
> ok
alter table if exists z add constraint z_uk unique (b);
> ok
alter table if exists z add constraint z_uk unique (b);
> exception
insert into z(id, b) values(1, 'b');
> update count: 1
insert into z(id, b) values(1, 'b');
> exception
delete from z;
> update count: 1
alter table if exists y drop column b;
> ok
alter table if exists z drop column b;
> ok
alter table if exists z drop column b;
> exception
alter table if exists y drop primary key;
> ok
alter table if exists z drop primary key;
> ok
alter table if exists z drop primary key;
> exception
create table x (id int not null primary key);
> ok
alter table if exists y add constraint z_fk foreign key (id) references x (id);
> ok
alter table if exists z add constraint z_fk foreign key (id) references x (id);
> ok
alter table if exists z add constraint z_fk foreign key (id) references x (id);
> exception
insert into z (id) values (1);
> exception
alter table if exists y drop foreign key z_fk;
> ok
alter table if exists z drop foreign key z_fk;
> ok
alter table if exists z drop foreign key z_fk;
> exception
insert into z (id) values (1);
> update count: 1
delete from z;
> update count: 1
drop table x;
> ok
drop table z;
> ok
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论