提交 a6ec7f8f authored 作者: Noel Grandin's avatar Noel Grandin

Merge pull request #287 from lukaseder/master

Add support for ALTER [ object ] IF EXISTS
...@@ -192,7 +192,7 @@ SHOW TABLES ...@@ -192,7 +192,7 @@ SHOW TABLES
" "
"Commands (DDL)","ALTER INDEX RENAME"," "Commands (DDL)","ALTER INDEX RENAME","
ALTER INDEX indexName RENAME TO newIndexName ALTER INDEX [ IF EXISTS ] indexName RENAME TO newIndexName
"," ","
Renames an index. Renames an index.
This command commits an open transaction in this connection. This command commits an open transaction in this connection.
...@@ -201,7 +201,7 @@ ALTER INDEX IDXNAME RENAME TO IDX_TEST_NAME ...@@ -201,7 +201,7 @@ ALTER INDEX IDXNAME RENAME TO IDX_TEST_NAME
" "
"Commands (DDL)","ALTER SCHEMA RENAME"," "Commands (DDL)","ALTER SCHEMA RENAME","
ALTER SCHEMA schema RENAME TO newSchemaName ALTER SCHEMA [ IF EXISTS ] schema RENAME TO newSchemaName
"," ","
Renames a schema. Renames a schema.
This command commits an open transaction in this connection. This command commits an open transaction in this connection.
...@@ -210,7 +210,7 @@ ALTER SCHEMA TEST RENAME TO PRODUCTION ...@@ -210,7 +210,7 @@ ALTER SCHEMA TEST RENAME TO PRODUCTION
" "
"Commands (DDL)","ALTER SEQUENCE"," "Commands (DDL)","ALTER SEQUENCE","
ALTER SEQUENCE sequenceName [ RESTART WITH long ] [ INCREMENT BY long ] ALTER SEQUENCE [ IF EXISTS ] sequenceName [ RESTART WITH long ] [ INCREMENT BY long ]
[ MINVALUE long | NOMINVALUE | NO MINVALUE ] [ MINVALUE long | NOMINVALUE | NO MINVALUE ]
[ MAXVALUE long | NOMAXVALUE | NO MAXVALUE ] [ MAXVALUE long | NOMAXVALUE | NO MAXVALUE ]
[ CYCLE long | NOCYCLE | NO CYCLE ] [ CYCLE long | NOCYCLE | NO CYCLE ]
...@@ -224,7 +224,7 @@ ALTER SEQUENCE SEQ_ID RESTART WITH 1000 ...@@ -224,7 +224,7 @@ ALTER SEQUENCE SEQ_ID RESTART WITH 1000
" "
"Commands (DDL)","ALTER TABLE ADD"," "Commands (DDL)","ALTER TABLE ADD","
ALTER TABLE tableName ADD [ COLUMN ] ALTER TABLE [ IF EXISTS ] tableName ADD [ COLUMN ]
{ [ IF NOT EXISTS ] columnDefinition [ { BEFORE | AFTER } columnName ] { [ IF NOT EXISTS ] columnDefinition [ { BEFORE | AFTER } columnName ]
| ( { columnDefinition } [,...] ) } | ( { columnDefinition } [,...] ) }
"," ","
...@@ -235,7 +235,7 @@ ALTER TABLE TEST ADD CREATEDATE TIMESTAMP ...@@ -235,7 +235,7 @@ ALTER TABLE TEST ADD CREATEDATE TIMESTAMP
" "
"Commands (DDL)","ALTER TABLE ADD CONSTRAINT"," "Commands (DDL)","ALTER TABLE ADD CONSTRAINT","
ALTER TABLE tableName ADD constraint [ CHECK | NOCHECK ] ALTER TABLE [ IF EXISTS ] tableName ADD constraint [ CHECK | NOCHECK ]
"," ","
Adds a constraint to a table. If NOCHECK is specified, existing rows are not Adds a constraint to a table. If NOCHECK is specified, existing rows are not
checked for consistency (the default is to check consistency for existing rows). checked for consistency (the default is to check consistency for existing rows).
...@@ -247,7 +247,7 @@ ALTER TABLE TEST ADD CONSTRAINT NAME_UNIQUE UNIQUE(NAME) ...@@ -247,7 +247,7 @@ ALTER TABLE TEST ADD CONSTRAINT NAME_UNIQUE UNIQUE(NAME)
" "
"Commands (DDL)","ALTER TABLE RENAME CONSTRAINT"," "Commands (DDL)","ALTER TABLE RENAME CONSTRAINT","
ALTER TABLE tableName RENAME oldConstraintName TO newConstraintName ALTER TABLE [ IF EXISTS ] tableName RENAME oldConstraintName TO newConstraintName
"," ","
Renames a constraint. Renames a constraint.
This command commits an open transaction in this connection. This command commits an open transaction in this connection.
...@@ -256,7 +256,7 @@ ALTER TABLE TEST RENAME CONSTRAINT FOO TO BAR ...@@ -256,7 +256,7 @@ ALTER TABLE TEST RENAME CONSTRAINT FOO TO BAR
" "
"Commands (DDL)","ALTER TABLE ALTER COLUMN"," "Commands (DDL)","ALTER TABLE ALTER COLUMN","
ALTER TABLE tableName ALTER COLUMN columnName ALTER TABLE [ IF EXISTS ] tableName ALTER COLUMN columnName
{ { dataType [ DEFAULT expression ] [ [ NOT ] NULL ] [ AUTO_INCREMENT | IDENTITY ] } { { dataType [ DEFAULT expression ] [ [ NOT ] NULL ] [ AUTO_INCREMENT | IDENTITY ] }
| { RENAME TO name } | { RENAME TO name }
| { RESTART WITH long } | { RESTART WITH long }
...@@ -298,7 +298,7 @@ ALTER TABLE TEST ALTER COLUMN NAME SET NULL; ...@@ -298,7 +298,7 @@ ALTER TABLE TEST ALTER COLUMN NAME SET NULL;
" "
"Commands (DDL)","ALTER TABLE DROP COLUMN"," "Commands (DDL)","ALTER TABLE DROP COLUMN","
ALTER TABLE tableName DROP COLUMN [ IF EXISTS ] ( columnName [,...] ) ALTER TABLE [ IF EXISTS ] tableName DROP COLUMN [ IF EXISTS ] ( columnName [,...] )
"," ","
Removes column(s) from a table. Removes column(s) from a table.
This command commits an open transaction in this connection. This command commits an open transaction in this connection.
...@@ -308,7 +308,7 @@ ALTER TABLE TEST DROP COLUMN NAME1, NAME2 ...@@ -308,7 +308,7 @@ ALTER TABLE TEST DROP COLUMN NAME1, NAME2
" "
"Commands (DDL)","ALTER TABLE DROP CONSTRAINT"," "Commands (DDL)","ALTER TABLE DROP CONSTRAINT","
ALTER TABLE tableName DROP { CONSTRAINT [ IF EXISTS ] constraintName | PRIMARY KEY } ALTER TABLE [ IF EXISTS ] tableName DROP { CONSTRAINT [ IF EXISTS ] constraintName | PRIMARY KEY }
"," ","
Removes a constraint or a primary key from a table. Removes a constraint or a primary key from a table.
This command commits an open transaction in this connection. This command commits an open transaction in this connection.
...@@ -317,7 +317,7 @@ ALTER TABLE TEST DROP CONSTRAINT UNIQUE_NAME ...@@ -317,7 +317,7 @@ ALTER TABLE TEST DROP CONSTRAINT UNIQUE_NAME
" "
"Commands (DDL)","ALTER TABLE SET"," "Commands (DDL)","ALTER TABLE SET","
ALTER TABLE tableName SET REFERENTIAL_INTEGRITY ALTER TABLE [ IF EXISTS ] tableName SET REFERENTIAL_INTEGRITY
{ FALSE | TRUE [ CHECK | NOCHECK ] } { FALSE | TRUE [ CHECK | NOCHECK ] }
"," ","
Disables or enables referential integrity checking for a table. This command can Disables or enables referential integrity checking for a table. This command can
...@@ -332,7 +332,7 @@ ALTER TABLE TEST SET REFERENTIAL_INTEGRITY FALSE ...@@ -332,7 +332,7 @@ ALTER TABLE TEST SET REFERENTIAL_INTEGRITY FALSE
" "
"Commands (DDL)","ALTER TABLE RENAME"," "Commands (DDL)","ALTER TABLE RENAME","
ALTER TABLE tableName RENAME TO newName ALTER TABLE [ IF EXISTS ] tableName RENAME TO newName
"," ","
Renames a table. Renames a table.
This command commits an open transaction in this connection. This command commits an open transaction in this connection.
...@@ -380,7 +380,7 @@ ALTER USER SA SET PASSWORD 'rioyxlgt' ...@@ -380,7 +380,7 @@ ALTER USER SA SET PASSWORD 'rioyxlgt'
" "
"Commands (DDL)","ALTER VIEW"," "Commands (DDL)","ALTER VIEW","
ALTER VIEW viewName RECOMPILE ALTER VIEW [ IF EXISTS ] viewName RECOMPILE
"," ","
Recompiles a view after the underlying tables have been changed or created. Recompiles a view after the underlying tables have been changed or created.
This command is used for views created using CREATE FORCE VIEW. This command is used for views created using CREATE FORCE VIEW.
......
...@@ -48,6 +48,16 @@ table with an LOB column. ...@@ -48,6 +48,16 @@ table with an LOB column.
</li> </li>
<li>Add support for PostgreSQL ALTER TABLE ... RENAME COLUMN .. TO ... <li>Add support for PostgreSQL ALTER TABLE ... RENAME COLUMN .. TO ...
</li> </li>
<li>Add support for ALTER SCHEMA [ IF EXISTS ]
</li>
<li>Add support for ALTER TABLE [ IF EXISTS ]
</li>
<li>Add support for ALTER VIEW [ IF EXISTS ]
</li>
<li>Add support for ALTER INDE [ IF EXISTS ]
</li>
<li>Add support for ALTER SEQUENCE [ IF EXISTS ]
</li>
<li>Improve performance of cleaning up temp tables - patch from Eric Faulhaber. <li>Improve performance of cleaning up temp tables - patch from Eric Faulhaber.
</li> </li>
<li>Fix bug where table locks were not dropped when the connection closed <li>Fix bug where table locks were not dropped when the connection closed
......
...@@ -16,6 +16,7 @@ import java.util.ArrayList; ...@@ -16,6 +16,7 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashSet; import java.util.HashSet;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.api.Trigger; import org.h2.api.Trigger;
import org.h2.command.ddl.AlterIndexRename; import org.h2.command.ddl.AlterIndexRename;
...@@ -652,7 +653,7 @@ public class Parser { ...@@ -652,7 +653,7 @@ public class Parser {
return command; return command;
} }
private Schema getSchema(String schemaName) { private Schema findSchema(String schemaName) {
if (schemaName == null) { if (schemaName == null) {
return null; return null;
} }
...@@ -664,13 +665,22 @@ public class Parser { ...@@ -664,13 +665,22 @@ public class Parser {
} else if (database.getMode().sysDummy1 && } else if (database.getMode().sysDummy1 &&
"SYSIBM".equals(schemaName)) { "SYSIBM".equals(schemaName)) {
// IBM DB2 and Apache Derby compatibility: SYSIBM.SYSDUMMY1 // IBM DB2 and Apache Derby compatibility: SYSIBM.SYSDUMMY1
} else {
throw DbException.get(ErrorCode.SCHEMA_NOT_FOUND_1, schemaName);
} }
} }
return schema; return schema;
} }
private Schema getSchema(String schemaName) {
if (schemaName == null) {
return null;
}
Schema schema = findSchema(schemaName);
if (schema == null) {
throw DbException.get(ErrorCode.SCHEMA_NOT_FOUND_1, schemaName);
}
return schema;
}
private Schema getSchema() { private Schema getSchema() {
return getSchema(schemaName); return getSchema(schemaName);
} }
...@@ -4852,10 +4862,13 @@ public class Parser { ...@@ -4852,10 +4862,13 @@ public class Parser {
} }
private AlterIndexRename parseAlterIndex() { private AlterIndexRename parseAlterIndex() {
boolean ifExists = readIfExists(false);
String indexName = readIdentifierWithSchema(); String indexName = readIdentifierWithSchema();
Schema old = getSchema(); Schema old = getSchema();
AlterIndexRename command = new AlterIndexRename(session); AlterIndexRename command = new AlterIndexRename(session);
command.setOldIndex(getSchema().getIndex(indexName)); command.setOldSchema(old);
command.setOldName(indexName);
command.setIfExists(ifExists);
read("RENAME"); read("RENAME");
read("TO"); read("TO");
String newName = readIdentifierWithSchema(old.getName()); String newName = readIdentifierWithSchema(old.getName());
...@@ -4866,9 +4879,11 @@ public class Parser { ...@@ -4866,9 +4879,11 @@ public class Parser {
private AlterView parseAlterView() { private AlterView parseAlterView() {
AlterView command = new AlterView(session); AlterView command = new AlterView(session);
boolean ifExists = readIfExists(false);
command.setIfExists(ifExists);
String viewName = readIdentifierWithSchema(); String viewName = readIdentifierWithSchema();
Table tableView = getSchema().findTableOrView(session, viewName); Table tableView = getSchema().findTableOrView(session, viewName);
if (!(tableView instanceof TableView)) { if (!(tableView instanceof TableView) && !ifExists) {
throw DbException.get(ErrorCode.VIEW_NOT_FOUND_1, viewName); throw DbException.get(ErrorCode.VIEW_NOT_FOUND_1, viewName);
} }
TableView view = (TableView) tableView; TableView view = (TableView) tableView;
...@@ -4877,24 +4892,35 @@ public class Parser { ...@@ -4877,24 +4892,35 @@ public class Parser {
return command; return command;
} }
private AlterSchemaRename parseAlterSchema() { private Prepared parseAlterSchema() {
boolean ifExists = readIfExists(false);
String schemaName = readIdentifierWithSchema(); String schemaName = readIdentifierWithSchema();
Schema old = getSchema(); Schema old = getSchema();
AlterSchemaRename command = new AlterSchemaRename(session);
command.setOldSchema(getSchema(schemaName));
read("RENAME"); read("RENAME");
read("TO"); read("TO");
String newName = readIdentifierWithSchema(old.getName()); String newName = readIdentifierWithSchema(old.getName());
checkSchema(old); Schema schema = findSchema(schemaName);
command.setNewName(newName); if (schema == null) {
return command; if (ifExists) {
return new NoOperation(session);
} else {
throw DbException.get(ErrorCode.SCHEMA_NOT_FOUND_1, schemaName);
}
} else {
AlterSchemaRename command = new AlterSchemaRename(session);
command.setOldSchema(schema);
checkSchema(old);
command.setNewName(newName);
return command;
}
} }
private AlterSequence parseAlterSequence() { private AlterSequence parseAlterSequence() {
boolean ifExists = readIfExists(false);
String sequenceName = readIdentifierWithSchema(); String sequenceName = readIdentifierWithSchema();
Sequence sequence = getSchema().getSequence(sequenceName); AlterSequence command = new AlterSequence(session, getSchema());
AlterSequence command = new AlterSequence(session, sequence.getSchema()); command.setSequenceName(sequenceName);
command.setSequence(sequence); command.setIfExists(ifExists);
while (true) { while (true) {
if (readIf("RESTART")) { if (readIf("RESTART")) {
read("WITH"); read("WITH");
...@@ -5415,21 +5441,24 @@ public class Parser { ...@@ -5415,21 +5441,24 @@ public class Parser {
} }
private Prepared parseAlterTable() { private Prepared parseAlterTable() {
Table table = readTableOrView(); boolean ifTableExists = readIfExists(false);
String tableName = readIdentifierWithSchema();
Schema schema = getSchema();
if (readIf("ADD")) { if (readIf("ADD")) {
Prepared command = parseAlterTableAddConstraintIf(table.getName(), Prepared command = parseAlterTableAddConstraintIf(tableName,
table.getSchema()); schema, ifTableExists);
if (command != null) { if (command != null) {
return command; return command;
} }
return parseAlterTableAddColumn(table); return parseAlterTableAddColumn(tableName, schema, ifTableExists);
} else if (readIf("SET")) { } else if (readIf("SET")) {
read("REFERENTIAL_INTEGRITY"); read("REFERENTIAL_INTEGRITY");
int type = CommandInterface.ALTER_TABLE_SET_REFERENTIAL_INTEGRITY; int type = CommandInterface.ALTER_TABLE_SET_REFERENTIAL_INTEGRITY;
boolean value = readBooleanSetting(); boolean value = readBooleanSetting();
AlterTableSet command = new AlterTableSet(session, AlterTableSet command = new AlterTableSet(session,
table.getSchema(), type, value); schema, type, value);
command.setTableName(table.getName()); command.setTableName(tableName);
command.setIfTableExists(ifTableExists);
if (readIf("CHECK")) { if (readIf("CHECK")) {
command.setCheckExisting(true); command.setCheckExisting(true);
} else if (readIf("NOCHECK")) { } else if (readIf("NOCHECK")) {
...@@ -5440,87 +5469,93 @@ public class Parser { ...@@ -5440,87 +5469,93 @@ public class Parser {
if (readIf("COLUMN")) { if (readIf("COLUMN")) {
// PostgreSQL syntax // PostgreSQL syntax
String columnName = readColumnIdentifier(); String columnName = readColumnIdentifier();
Column column = table.getColumn(columnName);
read("TO"); read("TO");
AlterTableRenameColumn command = new AlterTableRenameColumn( AlterTableRenameColumn command = new AlterTableRenameColumn(
session); session, schema);
command.setTable(table); command.setTableName(tableName);
command.setColumn(column); command.setIfTableExists(ifTableExists);
command.setOldColumnName(columnName);
String newName = readColumnIdentifier(); String newName = readColumnIdentifier();
command.setNewColumnName(newName); command.setNewColumnName(newName);
return command; return command;
} else if (readIf("CONSTRAINT")) { } else if (readIf("CONSTRAINT")) {
String constraintName = readIdentifierWithSchema(table String constraintName = readIdentifierWithSchema(schema.getName());
.getSchema().getName()); checkSchema(schema);
checkSchema(table.getSchema());
read("TO"); read("TO");
AlterTableRenameConstraint command = new AlterTableRenameConstraint( AlterTableRenameConstraint command = new AlterTableRenameConstraint(
session, table.getSchema()); session, schema);
command.setConstraintName(constraintName); command.setConstraintName(constraintName);
String newName = readColumnIdentifier(); String newName = readColumnIdentifier();
command.setNewConstraintName(newName); command.setNewConstraintName(newName);
return command; return commandIfTableExists(schema, tableName, ifTableExists, command);
} else { } else {
read("TO"); read("TO");
String newName = readIdentifierWithSchema(table.getSchema() String newName = readIdentifierWithSchema(schema.getName());
.getName()); checkSchema(schema);
checkSchema(table.getSchema());
AlterTableRename command = new AlterTableRename(session, AlterTableRename command = new AlterTableRename(session,
getSchema()); getSchema());
command.setOldTable(table); command.setOldTableName(tableName);
command.setNewTableName(newName); command.setNewTableName(newName);
command.setIfTableExists(ifTableExists);
command.setHidden(readIf("HIDDEN")); command.setHidden(readIf("HIDDEN"));
return command; return command;
} }
} else if (readIf("DROP")) { } else if (readIf("DROP")) {
if (readIf("CONSTRAINT")) { if (readIf("CONSTRAINT")) {
boolean ifExists = readIfExists(false); boolean ifExists = readIfExists(false);
String constraintName = readIdentifierWithSchema(table String constraintName = readIdentifierWithSchema(schema.getName());
.getSchema().getName());
ifExists = readIfExists(ifExists); ifExists = readIfExists(ifExists);
checkSchema(table.getSchema()); checkSchema(schema);
AlterTableDropConstraint command = new AlterTableDropConstraint( AlterTableDropConstraint command = new AlterTableDropConstraint(
session, getSchema(), ifExists); session, getSchema(), ifExists);
command.setConstraintName(constraintName); command.setConstraintName(constraintName);
return command; return commandIfTableExists(schema, tableName, ifTableExists, command);
} else if (readIf("FOREIGN")) { } else if (readIf("FOREIGN")) {
// MySQL compatibility // MySQL compatibility
read("KEY"); read("KEY");
String constraintName = readIdentifierWithSchema(table String constraintName = readIdentifierWithSchema(schema.getName());
.getSchema().getName()); checkSchema(schema);
checkSchema(table.getSchema());
AlterTableDropConstraint command = new AlterTableDropConstraint( AlterTableDropConstraint command = new AlterTableDropConstraint(
session, getSchema(), false); session, getSchema(), false);
command.setConstraintName(constraintName); command.setConstraintName(constraintName);
return command; return commandIfTableExists(schema, tableName, ifTableExists, command);
} else if (readIf("INDEX")) { } else if (readIf("INDEX")) {
// MySQL compatibility // MySQL compatibility
String indexName = readIdentifierWithSchema(); String indexName = readIdentifierWithSchema();
DropIndex command = new DropIndex(session, getSchema()); DropIndex command = new DropIndex(session, getSchema());
command.setIndexName(indexName); command.setIndexName(indexName);
return command; return commandIfTableExists(schema, tableName, ifTableExists, command);
} else if (readIf("PRIMARY")) { } else if (readIf("PRIMARY")) {
read("KEY"); read("KEY");
Table table = tableIfTableExists(schema, tableName, ifTableExists);
if (table == null) {
return new NoOperation(session);
}
Index idx = table.getPrimaryKey(); Index idx = table.getPrimaryKey();
DropIndex command = new DropIndex(session, table.getSchema()); DropIndex command = new DropIndex(session, schema);
command.setIndexName(idx.getName()); command.setIndexName(idx.getName());
return command; return command;
} else { } else {
readIf("COLUMN"); readIf("COLUMN");
boolean ifExists = readIfExists(false); boolean ifExists = readIfExists(false);
AlterTableAlterColumn command = new AlterTableAlterColumn( AlterTableAlterColumn command = new AlterTableAlterColumn(
session, table.getSchema()); session, schema);
command.setType(CommandInterface.ALTER_TABLE_DROP_COLUMN); command.setType(CommandInterface.ALTER_TABLE_DROP_COLUMN);
ArrayList<Column> columnsToRemove = New.arrayList(); ArrayList<Column> columnsToRemove = New.arrayList();
Table table = tableIfTableExists(schema, tableName, ifTableExists);
do { do {
String columnName = readColumnIdentifier(); String columnName = readColumnIdentifier();
if (table == null) {
return new NoOperation(session);
}
if (ifExists && !table.doesColumnExist(columnName)) { if (ifExists && !table.doesColumnExist(columnName)) {
return new NoOperation(session); return new NoOperation(session);
} }
Column column = table.getColumn(columnName); Column column = table.getColumn(columnName);
columnsToRemove.add(column); columnsToRemove.add(column);
} while (readIf(",")); } while (readIf(","));
command.setTable(table); command.setTableName(tableName);
command.setIfTableExists(ifTableExists);
command.setColumnsToRemove(columnsToRemove); command.setColumnsToRemove(columnsToRemove);
return command; return command;
} }
...@@ -5528,32 +5563,34 @@ public class Parser { ...@@ -5528,32 +5563,34 @@ public class Parser {
// MySQL compatibility // MySQL compatibility
readIf("COLUMN"); readIf("COLUMN");
String columnName = readColumnIdentifier(); String columnName = readColumnIdentifier();
Column column = table.getColumn(columnName);
String newColumnName = readColumnIdentifier(); String newColumnName = readColumnIdentifier();
Column column = columnIfTableExists(schema, tableName, columnName, ifTableExists);
boolean nullable = column == null ? true : column.isNullable();
// new column type ignored. RENAME and MODIFY are // new column type ignored. RENAME and MODIFY are
// a single command in MySQL but two different commands in H2. // a single command in MySQL but two different commands in H2.
parseColumnForTable(newColumnName, column.isNullable()); parseColumnForTable(newColumnName, nullable);
AlterTableRenameColumn command = new AlterTableRenameColumn(session); AlterTableRenameColumn command = new AlterTableRenameColumn(session, schema);
command.setTable(table); command.setTableName(tableName);
command.setColumn(column); command.setIfTableExists(ifTableExists);
command.setOldColumnName(columnName);
command.setNewColumnName(newColumnName); command.setNewColumnName(newColumnName);
return command; return command;
} else if (readIf("MODIFY")) { } else if (readIf("MODIFY")) {
// MySQL compatibility // MySQL compatibility
readIf("COLUMN"); readIf("COLUMN");
String columnName = readColumnIdentifier(); String columnName = readColumnIdentifier();
Column column = table.getColumn(columnName); return parseAlterTableAlterColumnType(schema, tableName, columnName, ifTableExists);
return parseAlterTableAlterColumnType(table, columnName, column);
} else if (readIf("ALTER")) { } else if (readIf("ALTER")) {
readIf("COLUMN"); readIf("COLUMN");
String columnName = readColumnIdentifier(); String columnName = readColumnIdentifier();
Column column = table.getColumn(columnName); Column column = columnIfTableExists(schema, tableName, columnName, ifTableExists);
if (readIf("RENAME")) { if (readIf("RENAME")) {
read("TO"); read("TO");
AlterTableRenameColumn command = new AlterTableRenameColumn( AlterTableRenameColumn command = new AlterTableRenameColumn(
session); session, schema);
command.setTable(table); command.setTableName(tableName);
command.setColumn(column); command.setIfTableExists(ifTableExists);
command.setOldColumnName(columnName);
String newName = readColumnIdentifier(); String newName = readColumnIdentifier();
command.setNewColumnName(newName); command.setNewColumnName(newName);
return command; return command;
...@@ -5561,8 +5598,9 @@ public class Parser { ...@@ -5561,8 +5598,9 @@ public class Parser {
// PostgreSQL compatibility // PostgreSQL compatibility
if (readIf("DEFAULT")) { if (readIf("DEFAULT")) {
AlterTableAlterColumn command = new AlterTableAlterColumn( AlterTableAlterColumn command = new AlterTableAlterColumn(
session, table.getSchema()); session, schema);
command.setTable(table); command.setTableName(tableName);
command.setIfTableExists(ifTableExists);
command.setOldColumn(column); command.setOldColumn(column);
command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_DEFAULT); command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_DEFAULT);
command.setDefaultExpression(null); command.setDefaultExpression(null);
...@@ -5571,24 +5609,26 @@ public class Parser { ...@@ -5571,24 +5609,26 @@ public class Parser {
read("NOT"); read("NOT");
read("NULL"); read("NULL");
AlterTableAlterColumn command = new AlterTableAlterColumn( AlterTableAlterColumn command = new AlterTableAlterColumn(
session, table.getSchema()); session, schema);
command.setTable(table); command.setTableName(tableName);
command.setIfTableExists(ifTableExists);
command.setOldColumn(column); command.setOldColumn(column);
command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_NULL); command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_NULL);
return command; return command;
} else if (readIf("TYPE")) { } else if (readIf("TYPE")) {
// PostgreSQL compatibility // PostgreSQL compatibility
return parseAlterTableAlterColumnType(table, columnName, column); return parseAlterTableAlterColumnType(schema, tableName, columnName, ifTableExists);
} else if (readIf("SET")) { } else if (readIf("SET")) {
if (readIf("DATA")) { if (readIf("DATA")) {
// Derby compatibility // Derby compatibility
read("TYPE"); read("TYPE");
return parseAlterTableAlterColumnType(table, columnName, return parseAlterTableAlterColumnType(schema, tableName, columnName,
column); ifTableExists);
} }
AlterTableAlterColumn command = new AlterTableAlterColumn( AlterTableAlterColumn command = new AlterTableAlterColumn(
session, table.getSchema()); session, schema);
command.setTable(table); command.setTableName(tableName);
command.setIfTableExists(ifTableExists);
command.setOldColumn(column); command.setOldColumn(column);
if (readIf("NULL")) { if (readIf("NULL")) {
command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_NULL); command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_NULL);
...@@ -5606,45 +5646,66 @@ public class Parser { ...@@ -5606,45 +5646,66 @@ public class Parser {
} else if (readIf("RESTART")) { } else if (readIf("RESTART")) {
readIf("WITH"); readIf("WITH");
Expression start = readExpression(); Expression start = readExpression();
AlterSequence command = new AlterSequence(session, AlterSequence command = new AlterSequence(session, schema);
table.getSchema());
command.setColumn(column); command.setColumn(column);
command.setStartWith(start); command.setStartWith(start);
return command; return commandIfTableExists(schema, tableName, ifTableExists, command);
} else if (readIf("SELECTIVITY")) { } else if (readIf("SELECTIVITY")) {
AlterTableAlterColumn command = new AlterTableAlterColumn( AlterTableAlterColumn command = new AlterTableAlterColumn(
session, table.getSchema()); session, schema);
command.setTable(table); command.setTableName(tableName);
command.setIfTableExists(ifTableExists);
command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_SELECTIVITY); command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_SELECTIVITY);
command.setOldColumn(column); command.setOldColumn(column);
command.setSelectivity(readExpression()); command.setSelectivity(readExpression());
return command; return command;
} else { } else {
return parseAlterTableAlterColumnType(table, columnName, column); return parseAlterTableAlterColumnType(schema, tableName, columnName, ifTableExists);
} }
} }
throw getSyntaxError(); throw getSyntaxError();
} }
private AlterTableAlterColumn parseAlterTableAlterColumnType(Table table, private Table tableIfTableExists(Schema schema, String tableName, boolean ifTableExists) {
String columnName, Column column) { Table table = schema.findTableOrView(session, tableName);
Column newColumn = parseColumnForTable(columnName, column.isNullable()); if (table == null && !ifTableExists) {
throw DbException.get(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, tableName);
}
return table;
}
private Column columnIfTableExists(Schema schema, String tableName, String columnName, boolean ifTableExists) {
Table table = tableIfTableExists(schema, tableName, ifTableExists);
return table == null ? null : table.getColumn(columnName);
}
private Prepared commandIfTableExists(Schema schema, String tableName, boolean ifTableExists, Prepared commandIfTableExists) {
return tableIfTableExists(schema, tableName, ifTableExists) == null
? new NoOperation(session)
: commandIfTableExists;
}
private AlterTableAlterColumn parseAlterTableAlterColumnType(Schema schema, String tableName,
String columnName, boolean ifTableExists) {
Column oldColumn = columnIfTableExists(schema, tableName, columnName, ifTableExists);
Column newColumn = parseColumnForTable(columnName, oldColumn == null ? true : oldColumn.isNullable());
AlterTableAlterColumn command = new AlterTableAlterColumn(session, AlterTableAlterColumn command = new AlterTableAlterColumn(session,
table.getSchema()); schema);
command.setTable(table); command.setTableName(tableName);
command.setIfTableExists(ifTableExists);
command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_CHANGE_TYPE); command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_CHANGE_TYPE);
command.setOldColumn(column); command.setOldColumn(oldColumn);
command.setNewColumn(newColumn); command.setNewColumn(newColumn);
return command; return command;
} }
private AlterTableAlterColumn parseAlterTableAddColumn(Table table) { private AlterTableAlterColumn parseAlterTableAddColumn(String tableName, Schema schema, boolean ifTableExists) {
readIf("COLUMN"); readIf("COLUMN");
Schema schema = table.getSchema();
AlterTableAlterColumn command = new AlterTableAlterColumn(session, AlterTableAlterColumn command = new AlterTableAlterColumn(session,
schema); schema);
command.setType(CommandInterface.ALTER_TABLE_ADD_COLUMN); command.setType(CommandInterface.ALTER_TABLE_ADD_COLUMN);
command.setTable(table); command.setTableName(tableName);
command.setIfTableExists(ifTableExists);
ArrayList<Column> columnsToAdd = New.arrayList(); ArrayList<Column> columnsToAdd = New.arrayList();
if (readIf("(")) { if (readIf("(")) {
command.setIfNotExists(false); command.setIfNotExists(false);
...@@ -5699,7 +5760,7 @@ public class Parser { ...@@ -5699,7 +5760,7 @@ public class Parser {
} }
private DefineCommand parseAlterTableAddConstraintIf(String tableName, private DefineCommand parseAlterTableAddConstraintIf(String tableName,
Schema schema) { Schema schema, boolean ifTableExists) {
String constraintName = null, comment = null; String constraintName = null, comment = null;
boolean ifNotExists = false; boolean ifNotExists = false;
boolean allowIndexDefinition = database.getMode().indexDefinitionInCreateTable; boolean allowIndexDefinition = database.getMode().indexDefinitionInCreateTable;
...@@ -5718,6 +5779,7 @@ public class Parser { ...@@ -5718,6 +5779,7 @@ public class Parser {
command.setComment(comment); command.setComment(comment);
command.setConstraintName(constraintName); command.setConstraintName(constraintName);
command.setTableName(tableName); command.setTableName(tableName);
command.setIfTableExists(ifTableExists);
if (readIf("HASH")) { if (readIf("HASH")) {
command.setPrimaryKeyHash(true); command.setPrimaryKeyHash(true);
} }
...@@ -5742,6 +5804,7 @@ public class Parser { ...@@ -5742,6 +5804,7 @@ public class Parser {
CreateIndex command = new CreateIndex(session, schema); CreateIndex command = new CreateIndex(session, schema);
command.setComment(comment); command.setComment(comment);
command.setTableName(tableName); command.setTableName(tableName);
command.setIfTableExists(ifTableExists);
if (!readIf("(")) { if (!readIf("(")) {
command.setIndexName(readUniqueIdentifier()); command.setIndexName(readUniqueIdentifier());
read("("); read("(");
...@@ -5801,6 +5864,7 @@ public class Parser { ...@@ -5801,6 +5864,7 @@ public class Parser {
command.setCheckExisting(true); command.setCheckExisting(true);
} }
command.setTableName(tableName); command.setTableName(tableName);
command.setIfTableExists(ifTableExists);
command.setConstraintName(constraintName); command.setConstraintName(constraintName);
command.setComment(comment); command.setComment(comment);
return command; return command;
...@@ -5896,7 +5960,7 @@ public class Parser { ...@@ -5896,7 +5960,7 @@ public class Parser {
if (!readIf(")")) { if (!readIf(")")) {
do { do {
DefineCommand c = parseAlterTableAddConstraintIf(tableName, DefineCommand c = parseAlterTableAddConstraintIf(tableName,
schema); schema, false);
if (c != null) { if (c != null) {
command.addConstraintCommand(c); command.addConstraintCommand(c);
} else { } else {
......
...@@ -20,6 +20,9 @@ import org.h2.schema.Schema; ...@@ -20,6 +20,9 @@ import org.h2.schema.Schema;
*/ */
public class AlterIndexRename extends DefineCommand { public class AlterIndexRename extends DefineCommand {
private boolean ifExists;
private Schema oldSchema;
private String oldIndexName;
private Index oldIndex; private Index oldIndex;
private String newIndexName; private String newIndexName;
...@@ -27,8 +30,16 @@ public class AlterIndexRename extends DefineCommand { ...@@ -27,8 +30,16 @@ public class AlterIndexRename extends DefineCommand {
super(session); super(session);
} }
public void setOldIndex(Index index) { public void setIfExists(boolean b) {
oldIndex = index; ifExists = b;
}
public void setOldSchema(Schema old) {
oldSchema = old;
}
public void setOldName(String name) {
oldIndexName = name;
} }
public void setNewName(String name) { public void setNewName(String name) {
...@@ -39,9 +50,17 @@ public class AlterIndexRename extends DefineCommand { ...@@ -39,9 +50,17 @@ public class AlterIndexRename extends DefineCommand {
public int update() { public int update() {
session.commit(true); session.commit(true);
Database db = session.getDatabase(); Database db = session.getDatabase();
Schema schema = oldIndex.getSchema(); oldIndex = oldSchema.findIndex(session, oldIndexName);
if (schema.findIndex(session, newIndexName) != null || if (oldIndex == null) {
newIndexName.equals(oldIndex.getName())) { if (!ifExists) {
throw DbException.get(ErrorCode.INDEX_NOT_FOUND_1,
newIndexName);
} else {
return 0;
}
}
if (oldSchema.findIndex(session, newIndexName) != null ||
newIndexName.equals(oldIndexName)) {
throw DbException.get(ErrorCode.INDEX_ALREADY_EXISTS_1, throw DbException.get(ErrorCode.INDEX_ALREADY_EXISTS_1,
newIndexName); newIndexName);
} }
......
...@@ -49,6 +49,7 @@ public class AlterTableAddConstraint extends SchemaCommand { ...@@ -49,6 +49,7 @@ public class AlterTableAddConstraint extends SchemaCommand {
private String comment; private String comment;
private boolean checkExisting; private boolean checkExisting;
private boolean primaryKeyHash; private boolean primaryKeyHash;
private boolean ifTableExists;
private final boolean ifNotExists; private final boolean ifNotExists;
private ArrayList<Index> createdIndexes = New.arrayList(); private ArrayList<Index> createdIndexes = New.arrayList();
...@@ -58,6 +59,10 @@ public class AlterTableAddConstraint extends SchemaCommand { ...@@ -58,6 +59,10 @@ public class AlterTableAddConstraint extends SchemaCommand {
this.ifNotExists = ifNotExists; this.ifNotExists = ifNotExists;
} }
public void setIfTableExists(boolean b) {
ifTableExists = b;
}
private String generateConstraintName(Table table) { private String generateConstraintName(Table table) {
if (constraintName == null) { if (constraintName == null) {
constraintName = getSchema().getUniqueConstraintName( constraintName = getSchema().getUniqueConstraintName(
...@@ -90,7 +95,13 @@ public class AlterTableAddConstraint extends SchemaCommand { ...@@ -90,7 +95,13 @@ public class AlterTableAddConstraint extends SchemaCommand {
session.commit(true); session.commit(true);
} }
Database db = session.getDatabase(); 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 (getSchema().findConstraint(session, constraintName) != null) {
if (ifNotExists) { if (ifNotExists) {
return 0; return 0;
......
...@@ -48,7 +48,7 @@ import org.h2.util.New; ...@@ -48,7 +48,7 @@ import org.h2.util.New;
*/ */
public class AlterTableAlterColumn extends SchemaCommand { public class AlterTableAlterColumn extends SchemaCommand {
private Table table; private String tableName;
private Column oldColumn; private Column oldColumn;
private Column newColumn; private Column newColumn;
private int type; private int type;
...@@ -56,6 +56,7 @@ public class AlterTableAlterColumn extends SchemaCommand { ...@@ -56,6 +56,7 @@ public class AlterTableAlterColumn extends SchemaCommand {
private Expression newSelectivity; private Expression newSelectivity;
private String addBefore; private String addBefore;
private String addAfter; private String addAfter;
private boolean ifTableExists;
private boolean ifNotExists; private boolean ifNotExists;
private ArrayList<Column> columnsToAdd; private ArrayList<Column> columnsToAdd;
private ArrayList<Column> columnsToRemove; private ArrayList<Column> columnsToRemove;
...@@ -64,8 +65,12 @@ public class AlterTableAlterColumn extends SchemaCommand { ...@@ -64,8 +65,12 @@ public class AlterTableAlterColumn extends SchemaCommand {
super(session, schema); super(session, schema);
} }
public void setTable(Table table) { public void setIfTableExists(boolean b) {
this.table = table; ifTableExists = b;
}
public void setTableName(String tableName) {
this.tableName = tableName;
} }
public void setOldColumn(Column oldColumn) { public void setOldColumn(Column oldColumn) {
...@@ -84,16 +89,23 @@ public class AlterTableAlterColumn extends SchemaCommand { ...@@ -84,16 +89,23 @@ public class AlterTableAlterColumn extends SchemaCommand {
public int update() { public int update() {
session.commit(true); session.commit(true);
Database db = session.getDatabase(); 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); session.getUser().checkRight(table, Right.ALL);
table.checkSupportAlter(); table.checkSupportAlter();
table.lock(session, true, true); table.lock(session, true, true);
if (newColumn != null) { if (newColumn != null) {
checkDefaultReferencesTable(newColumn.getDefaultExpression()); checkDefaultReferencesTable(table, newColumn.getDefaultExpression());
checkClustering(newColumn); checkClustering(newColumn);
} }
if (columnsToAdd != null) { if (columnsToAdd != null) {
for (Column column : columnsToAdd) { for (Column column : columnsToAdd) {
checkDefaultReferencesTable(column.getDefaultExpression()); checkDefaultReferencesTable(table, column.getDefaultExpression());
checkClustering(column); checkClustering(column);
} }
} }
...@@ -103,7 +115,7 @@ public class AlterTableAlterColumn extends SchemaCommand { ...@@ -103,7 +115,7 @@ public class AlterTableAlterColumn extends SchemaCommand {
// no change // no change
break; break;
} }
checkNoNullValues(); checkNoNullValues(table);
oldColumn.setNullable(false); oldColumn.setNullable(false);
db.updateMeta(session, table); db.updateMeta(session, table);
break; break;
...@@ -113,17 +125,17 @@ public class AlterTableAlterColumn extends SchemaCommand { ...@@ -113,17 +125,17 @@ public class AlterTableAlterColumn extends SchemaCommand {
// no change // no change
break; break;
} }
checkNullable(); checkNullable(table);
oldColumn.setNullable(true); oldColumn.setNullable(true);
db.updateMeta(session, table); db.updateMeta(session, table);
break; break;
} }
case CommandInterface.ALTER_TABLE_ALTER_COLUMN_DEFAULT: { case CommandInterface.ALTER_TABLE_ALTER_COLUMN_DEFAULT: {
Sequence sequence = oldColumn == null ? null : oldColumn.getSequence(); Sequence sequence = oldColumn == null ? null : oldColumn.getSequence();
checkDefaultReferencesTable(defaultExpression); checkDefaultReferencesTable(table, defaultExpression);
oldColumn.setSequence(null); oldColumn.setSequence(null);
oldColumn.setDefaultExpression(session, defaultExpression); oldColumn.setDefaultExpression(session, defaultExpression);
removeSequence(sequence); removeSequence(table, sequence);
db.updateMeta(session, table); db.updateMeta(session, table);
break; break;
} }
...@@ -132,7 +144,7 @@ public class AlterTableAlterColumn extends SchemaCommand { ...@@ -132,7 +144,7 @@ public class AlterTableAlterColumn extends SchemaCommand {
// need to copy the table because the length is only a constraint, // need to copy the table because the length is only a constraint,
// and does not affect the storage structure. // and does not affect the storage structure.
if (oldColumn.isWideningConversion(newColumn)) { if (oldColumn.isWideningConversion(newColumn)) {
convertAutoIncrementColumn(newColumn); convertAutoIncrementColumn(table, newColumn);
oldColumn.copy(newColumn); oldColumn.copy(newColumn);
db.updateMeta(session, table); db.updateMeta(session, table);
} else { } else {
...@@ -140,12 +152,12 @@ public class AlterTableAlterColumn extends SchemaCommand { ...@@ -140,12 +152,12 @@ public class AlterTableAlterColumn extends SchemaCommand {
oldColumn.setDefaultExpression(session, null); oldColumn.setDefaultExpression(session, null);
oldColumn.setConvertNullToDefault(false); oldColumn.setConvertNullToDefault(false);
if (oldColumn.isNullable() && !newColumn.isNullable()) { if (oldColumn.isNullable() && !newColumn.isNullable()) {
checkNoNullValues(); checkNoNullValues(table);
} else if (!oldColumn.isNullable() && newColumn.isNullable()) { } else if (!oldColumn.isNullable() && newColumn.isNullable()) {
checkNullable(); checkNullable(table);
} }
convertAutoIncrementColumn(newColumn); convertAutoIncrementColumn(table, newColumn);
copyData(); copyData(table);
} }
break; break;
} }
...@@ -162,7 +174,7 @@ public class AlterTableAlterColumn extends SchemaCommand { ...@@ -162,7 +174,7 @@ public class AlterTableAlterColumn extends SchemaCommand {
table.isTemporary()); table.isTemporary());
} }
} }
copyData(); copyData(table);
break; break;
} }
case CommandInterface.ALTER_TABLE_DROP_COLUMN: { case CommandInterface.ALTER_TABLE_DROP_COLUMN: {
...@@ -171,7 +183,7 @@ public class AlterTableAlterColumn extends SchemaCommand { ...@@ -171,7 +183,7 @@ public class AlterTableAlterColumn extends SchemaCommand {
columnsToRemove.get(0).getSQL()); columnsToRemove.get(0).getSQL());
} }
table.dropMultipleColumnsConstraintsAndIndexes(session, columnsToRemove); table.dropMultipleColumnsConstraintsAndIndexes(session, columnsToRemove);
copyData(); copyData(table);
break; break;
} }
case CommandInterface.ALTER_TABLE_ALTER_COLUMN_SELECTIVITY: { case CommandInterface.ALTER_TABLE_ALTER_COLUMN_SELECTIVITY: {
...@@ -186,7 +198,7 @@ public class AlterTableAlterColumn extends SchemaCommand { ...@@ -186,7 +198,7 @@ public class AlterTableAlterColumn extends SchemaCommand {
return 0; return 0;
} }
private void checkDefaultReferencesTable(Expression defaultExpression) { private void checkDefaultReferencesTable(Table table, Expression defaultExpression) {
if (defaultExpression == null) { if (defaultExpression == null) {
return; return;
} }
...@@ -209,7 +221,7 @@ public class AlterTableAlterColumn extends SchemaCommand { ...@@ -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.isAutoIncrement()) {
if (c.isPrimaryKey()) { if (c.isPrimaryKey()) {
c.setOriginalSQL("IDENTITY"); c.setOriginalSQL("IDENTITY");
...@@ -221,7 +233,7 @@ public class AlterTableAlterColumn extends SchemaCommand { ...@@ -221,7 +233,7 @@ public class AlterTableAlterColumn extends SchemaCommand {
} }
} }
private void removeSequence(Sequence sequence) { private void removeSequence(Table table, Sequence sequence) {
if (sequence != null) { if (sequence != null) {
table.removeSequence(sequence); table.removeSequence(sequence);
sequence.setBelongsToTable(false); sequence.setBelongsToTable(false);
...@@ -230,7 +242,7 @@ public class AlterTableAlterColumn extends SchemaCommand { ...@@ -230,7 +242,7 @@ public class AlterTableAlterColumn extends SchemaCommand {
} }
} }
private void copyData() { private void copyData(Table table) {
if (table.isTemporary()) { if (table.isTemporary()) {
throw DbException.getUnsupportedException("TEMP TABLE"); throw DbException.getUnsupportedException("TEMP TABLE");
} }
...@@ -239,7 +251,7 @@ public class AlterTableAlterColumn extends SchemaCommand { ...@@ -239,7 +251,7 @@ public class AlterTableAlterColumn extends SchemaCommand {
String tempName = db.getTempTableName(baseName, session); String tempName = db.getTempTableName(baseName, session);
Column[] columns = table.getColumns(); Column[] columns = table.getColumns();
ArrayList<Column> newColumns = New.arrayList(); ArrayList<Column> newColumns = New.arrayList();
Table newTable = cloneTableStructure(columns, db, tempName, newColumns); Table newTable = cloneTableStructure(table, columns, db, tempName, newColumns);
try { try {
// check if a view would become invalid // check if a view would become invalid
// (because the column to drop is referenced or so) // (because the column to drop is referenced or so)
...@@ -289,7 +301,7 @@ public class AlterTableAlterColumn extends SchemaCommand { ...@@ -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) { String tempName, ArrayList<Column> newColumns) {
for (Column col : columns) { for (Column col : columns) {
newColumns.add(col.getClone()); newColumns.add(col.getClone());
...@@ -479,7 +491,7 @@ public class AlterTableAlterColumn extends SchemaCommand { ...@@ -479,7 +491,7 @@ public class AlterTableAlterColumn extends SchemaCommand {
} }
} }
private void checkNullable() { private void checkNullable(Table table) {
for (Index index : table.getIndexes()) { for (Index index : table.getIndexes()) {
if (index.getColumnIndex(oldColumn) < 0) { if (index.getColumnIndex(oldColumn) < 0) {
continue; continue;
...@@ -492,7 +504,7 @@ public class AlterTableAlterColumn extends SchemaCommand { ...@@ -492,7 +504,7 @@ public class AlterTableAlterColumn extends SchemaCommand {
} }
} }
private void checkNoNullValues() { private void checkNoNullValues(Table table) {
String sql = "SELECT COUNT(*) FROM " + String sql = "SELECT COUNT(*) FROM " +
table.getSQL() + " WHERE " + table.getSQL() + " WHERE " +
oldColumn.getSQL() + " IS NULL"; oldColumn.getSQL() + " IS NULL";
......
...@@ -20,7 +20,8 @@ import org.h2.table.Table; ...@@ -20,7 +20,8 @@ import org.h2.table.Table;
*/ */
public class AlterTableRename extends SchemaCommand { public class AlterTableRename extends SchemaCommand {
private Table oldTable; private boolean ifTableExists;
private String oldTableName;
private String newTableName; private String newTableName;
private boolean hidden; private boolean hidden;
...@@ -28,8 +29,12 @@ public class AlterTableRename extends SchemaCommand { ...@@ -28,8 +29,12 @@ public class AlterTableRename extends SchemaCommand {
super(session, schema); super(session, schema);
} }
public void setOldTable(Table table) { public void setIfTableExists(boolean b) {
oldTable = table; ifTableExists = b;
}
public void setOldTableName(String name) {
oldTableName = name;
} }
public void setNewTableName(String name) { public void setNewTableName(String name) {
...@@ -40,6 +45,13 @@ public class AlterTableRename extends SchemaCommand { ...@@ -40,6 +45,13 @@ public class AlterTableRename extends SchemaCommand {
public int update() { public int update() {
session.commit(true); session.commit(true);
Database db = session.getDatabase(); 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); session.getUser().checkRight(oldTable, Right.ALL);
Table t = getSchema().findTableOrView(session, newTableName); Table t = getSchema().findTableOrView(session, newTableName);
if (t != null && hidden && newTableName.equals(oldTable.getName())) { if (t != null && hidden && newTableName.equals(oldTable.getName())) {
......
...@@ -5,12 +5,15 @@ ...@@ -5,12 +5,15 @@
*/ */
package org.h2.command.ddl; package org.h2.command.ddl;
import org.h2.api.ErrorCode;
import org.h2.command.CommandInterface; import org.h2.command.CommandInterface;
import org.h2.engine.Database; import org.h2.engine.Database;
import org.h2.engine.DbObject; import org.h2.engine.DbObject;
import org.h2.engine.Right; import org.h2.engine.Right;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.expression.Expression; import org.h2.expression.Expression;
import org.h2.message.DbException;
import org.h2.schema.Schema;
import org.h2.table.Column; import org.h2.table.Column;
import org.h2.table.Table; import org.h2.table.Table;
...@@ -18,22 +21,27 @@ import org.h2.table.Table; ...@@ -18,22 +21,27 @@ import org.h2.table.Table;
* This class represents the statement * This class represents the statement
* ALTER TABLE ALTER COLUMN RENAME * ALTER TABLE ALTER COLUMN RENAME
*/ */
public class AlterTableRenameColumn extends DefineCommand { public class AlterTableRenameColumn extends SchemaCommand {
private Table table; private boolean ifTableExists;
private Column column; private String tableName;
private String oldName;
private String newName; private String newName;
public AlterTableRenameColumn(Session session) { public AlterTableRenameColumn(Session session, Schema schema) {
super(session); super(session, schema);
} }
public void setTable(Table table) { public void setIfTableExists(boolean b) {
this.table = table; this.ifTableExists = b;
} }
public void setColumn(Column column) { public void setTableName(String tableName) {
this.column = column; this.tableName = tableName;
}
public void setOldColumnName(String oldName) {
this.oldName = oldName;
} }
public void setNewColumnName(String newName) { public void setNewColumnName(String newName) {
...@@ -44,6 +52,14 @@ public class AlterTableRenameColumn extends DefineCommand { ...@@ -44,6 +52,14 @@ public class AlterTableRenameColumn extends DefineCommand {
public int update() { public int update() {
session.commit(true); session.commit(true);
Database db = session.getDatabase(); 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); session.getUser().checkRight(table, Right.ALL);
table.checkSupportAlter(); table.checkSupportAlter();
// we need to update CHECK constraint // we need to update CHECK constraint
......
...@@ -17,12 +17,17 @@ import org.h2.table.TableView; ...@@ -17,12 +17,17 @@ import org.h2.table.TableView;
*/ */
public class AlterView extends DefineCommand { public class AlterView extends DefineCommand {
private boolean ifExists;
private TableView view; private TableView view;
public AlterView(Session session) { public AlterView(Session session) {
super(session); super(session);
} }
public void setIfExists(boolean b) {
ifExists = b;
}
public void setView(TableView view) { public void setView(TableView view) {
this.view = view; this.view = view;
} }
...@@ -30,6 +35,9 @@ public class AlterView extends DefineCommand { ...@@ -30,6 +35,9 @@ public class AlterView extends DefineCommand {
@Override @Override
public int update() { public int update() {
session.commit(true); session.commit(true);
if (view == null && ifExists) {
return 0;
}
session.getUser().checkRight(view, Right.ALL); session.getUser().checkRight(view, Right.ALL);
DbException e = view.recompile(session, false, true); DbException e = view.recompile(session, false, true);
if (e != null) { if (e != null) {
......
...@@ -27,6 +27,7 @@ public class CreateIndex extends SchemaCommand { ...@@ -27,6 +27,7 @@ public class CreateIndex extends SchemaCommand {
private String indexName; private String indexName;
private IndexColumn[] indexColumns; private IndexColumn[] indexColumns;
private boolean primaryKey, unique, hash, spatial; private boolean primaryKey, unique, hash, spatial;
private boolean ifTableExists;
private boolean ifNotExists; private boolean ifNotExists;
private String comment; private String comment;
...@@ -34,6 +35,10 @@ public class CreateIndex extends SchemaCommand { ...@@ -34,6 +35,10 @@ public class CreateIndex extends SchemaCommand {
super(session, schema); super(session, schema);
} }
public void setIfTableExists(boolean b) {
this.ifTableExists = b;
}
public void setIfNotExists(boolean ifNotExists) { public void setIfNotExists(boolean ifNotExists) {
this.ifNotExists = ifNotExists; this.ifNotExists = ifNotExists;
} }
...@@ -57,7 +62,13 @@ public class CreateIndex extends SchemaCommand { ...@@ -57,7 +62,13 @@ public class CreateIndex extends SchemaCommand {
} }
Database db = session.getDatabase(); Database db = session.getDatabase();
boolean persistent = db.isPersistent(); 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 (getSchema().findIndex(session, indexName) != null) {
if (ifNotExists) { if (ifNotExists) {
return 0; return 0;
......
...@@ -24,7 +24,9 @@ import org.h2.table.Table; ...@@ -24,7 +24,9 @@ import org.h2.table.Table;
*/ */
public class AlterSequence extends SchemaCommand { public class AlterSequence extends SchemaCommand {
private boolean ifExists;
private Table table; private Table table;
private String sequenceName;
private Sequence sequence; private Sequence sequence;
private Expression start; private Expression start;
private Expression increment; private Expression increment;
...@@ -37,8 +39,12 @@ public class AlterSequence extends SchemaCommand { ...@@ -37,8 +39,12 @@ public class AlterSequence extends SchemaCommand {
super(session, schema); super(session, schema);
} }
public void setSequence(Sequence sequence) { public void setIfExists(boolean b) {
this.sequence = sequence; ifExists = b;
}
public void setSequenceName(String sequenceName) {
this.sequenceName = sequenceName;
} }
@Override @Override
...@@ -49,7 +55,7 @@ public class AlterSequence extends SchemaCommand { ...@@ -49,7 +55,7 @@ public class AlterSequence extends SchemaCommand {
public void setColumn(Column column) { public void setColumn(Column column) {
table = column.getTable(); table = column.getTable();
sequence = column.getSequence(); sequence = column.getSequence();
if (sequence == null) { if (sequence == null && !ifExists) {
throw DbException.get(ErrorCode.SEQUENCE_NOT_FOUND_1, column.getSQL()); throw DbException.get(ErrorCode.SEQUENCE_NOT_FOUND_1, column.getSQL());
} }
} }
...@@ -81,6 +87,16 @@ public class AlterSequence extends SchemaCommand { ...@@ -81,6 +87,16 @@ public class AlterSequence extends SchemaCommand {
@Override @Override
public int update() { public int update() {
Database db = session.getDatabase(); Database db = session.getDatabase();
if (sequence == null) {
sequence = getSchema().findSequence(sequenceName);
if (sequence == null) {
if (!ifExists) {
throw DbException.get(ErrorCode.SEQUENCE_NOT_FOUND_1, sequenceName);
} else {
return 0;
}
}
}
if (table != null) { if (table != null) {
session.getUser().checkRight(table, Right.ALL); session.getUser().checkRight(table, Right.ALL);
} }
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
*/ */
package org.h2.command.dml; package org.h2.command.dml;
import org.h2.api.ErrorCode;
import org.h2.command.CommandInterface; import org.h2.command.CommandInterface;
import org.h2.command.ddl.SchemaCommand; import org.h2.command.ddl.SchemaCommand;
import org.h2.engine.Right; import org.h2.engine.Right;
...@@ -19,6 +20,7 @@ import org.h2.table.Table; ...@@ -19,6 +20,7 @@ import org.h2.table.Table;
*/ */
public class AlterTableSet extends SchemaCommand { public class AlterTableSet extends SchemaCommand {
private boolean ifTableExists;
private String tableName; private String tableName;
private final int type; private final int type;
...@@ -40,13 +42,23 @@ public class AlterTableSet extends SchemaCommand { ...@@ -40,13 +42,23 @@ public class AlterTableSet extends SchemaCommand {
return true; return true;
} }
public void setIfTableExists(boolean b) {
this.ifTableExists = b;
}
public void setTableName(String tableName) { public void setTableName(String tableName) {
this.tableName = tableName; this.tableName = tableName;
} }
@Override @Override
public int update() { 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); session.getUser().checkRight(table, Right.ALL);
table.lock(session, true, true); table.lock(session, true, true);
switch (type) { switch (type) {
......
...@@ -401,7 +401,7 @@ public class IndexCondition { ...@@ -401,7 +401,7 @@ public class IndexCondition {
return "column=" + column + return "column=" + column +
", compareType=" + compareTypeToString(compareType) + ", compareType=" + compareTypeToString(compareType) +
", expression=" + expression + ", expression=" + expression +
", expressionList=" + expressionList + ", expressionList=" + expressionList.toString() +
", expressionQuery=" + expressionQuery; ", expressionQuery=" + expressionQuery;
} }
......
...@@ -67,15 +67,15 @@ SHOW { SCHEMAS | TABLES [ FROM schemaName ] | ...@@ -67,15 +67,15 @@ SHOW { SCHEMAS | TABLES [ FROM schemaName ] |
"," ","
Lists the schemas, tables, or the columns of a table." Lists the schemas, tables, or the columns of a table."
"Commands (DDL)","ALTER INDEX RENAME"," "Commands (DDL)","ALTER INDEX RENAME","
ALTER INDEX indexName RENAME TO newIndexName ALTER INDEX [ IF EXISTS ] indexName RENAME TO newIndexName
"," ","
Renames an index." Renames an index."
"Commands (DDL)","ALTER SCHEMA RENAME"," "Commands (DDL)","ALTER SCHEMA RENAME","
ALTER SCHEMA schema RENAME TO newSchemaName ALTER SCHEMA [ IF EXISTS ] schema RENAME TO newSchemaName
"," ","
Renames a schema." Renames a schema."
"Commands (DDL)","ALTER SEQUENCE"," "Commands (DDL)","ALTER SEQUENCE","
ALTER SEQUENCE sequenceName [ RESTART WITH long ] [ INCREMENT BY long ] ALTER SEQUENCE [ IF EXISTS ] sequenceName [ RESTART WITH long ] [ INCREMENT BY long ]
[ MINVALUE long | NOMINVALUE | NO MINVALUE ] [ MINVALUE long | NOMINVALUE | NO MINVALUE ]
[ MAXVALUE long | NOMAXVALUE | NO MAXVALUE ] [ MAXVALUE long | NOMAXVALUE | NO MAXVALUE ]
[ CYCLE long | NOCYCLE | NO CYCLE ] [ CYCLE long | NOCYCLE | NO CYCLE ]
...@@ -83,21 +83,21 @@ ALTER SEQUENCE sequenceName [ RESTART WITH long ] [ INCREMENT BY long ] ...@@ -83,21 +83,21 @@ ALTER SEQUENCE sequenceName [ RESTART WITH long ] [ INCREMENT BY long ]
"," ","
Changes the parameters of a sequence." Changes the parameters of a sequence."
"Commands (DDL)","ALTER TABLE ADD"," "Commands (DDL)","ALTER TABLE ADD","
ALTER TABLE tableName ADD [ COLUMN ] ALTER TABLE [ IF EXISTS ] tableName ADD [ COLUMN ]
{ [ IF NOT EXISTS ] columnDefinition [ { BEFORE | AFTER } columnName ] { [ IF NOT EXISTS ] columnDefinition [ { BEFORE | AFTER } columnName ]
| ( { columnDefinition } [,...] ) } | ( { columnDefinition } [,...] ) }
"," ","
Adds a new column to a table." Adds a new column to a table."
"Commands (DDL)","ALTER TABLE ADD CONSTRAINT"," "Commands (DDL)","ALTER TABLE ADD CONSTRAINT","
ALTER TABLE tableName ADD constraint [ CHECK | NOCHECK ] ALTER TABLE [ IF EXISTS ] tableName ADD constraint [ CHECK | NOCHECK ]
"," ","
Adds a constraint to a table." Adds a constraint to a table."
"Commands (DDL)","ALTER TABLE RENAME CONSTRAINT"," "Commands (DDL)","ALTER TABLE RENAME CONSTRAINT","
ALTER TABLE tableName RENAME oldConstraintName TO newConstraintName ALTER TABLE [ IF EXISTS ] tableName RENAME oldConstraintName TO newConstraintName
"," ","
Renames a constraint." Renames a constraint."
"Commands (DDL)","ALTER TABLE ALTER COLUMN"," "Commands (DDL)","ALTER TABLE ALTER COLUMN","
ALTER TABLE tableName ALTER COLUMN columnName ALTER TABLE [ IF EXISTS ] tableName ALTER COLUMN columnName
{ { dataType [ DEFAULT expression ] [ [ NOT ] NULL ] [ AUTO_INCREMENT | IDENTITY ] } { { dataType [ DEFAULT expression ] [ [ NOT ] NULL ] [ AUTO_INCREMENT | IDENTITY ] }
| { RENAME TO name } | { RENAME TO name }
| { RESTART WITH long } | { RESTART WITH long }
...@@ -109,20 +109,20 @@ ALTER TABLE tableName ALTER COLUMN columnName ...@@ -109,20 +109,20 @@ ALTER TABLE tableName ALTER COLUMN columnName
Changes the data type of a column, rename a column, Changes the data type of a column, rename a column,
change the identity value, or change the selectivity." change the identity value, or change the selectivity."
"Commands (DDL)","ALTER TABLE DROP COLUMN"," "Commands (DDL)","ALTER TABLE DROP COLUMN","
ALTER TABLE tableName DROP COLUMN [ IF EXISTS ] ( columnName [,...] ) ALTER TABLE [ IF EXISTS ] tableName DROP COLUMN [ IF EXISTS ] ( columnName [,...] )
"," ","
Removes column(s) from a table." Removes column(s) from a table."
"Commands (DDL)","ALTER TABLE DROP CONSTRAINT"," "Commands (DDL)","ALTER TABLE DROP CONSTRAINT","
ALTER TABLE tableName DROP { CONSTRAINT [ IF EXISTS ] constraintName | PRIMARY KEY } ALTER TABLE [ IF EXISTS ] tableName DROP { CONSTRAINT [ IF EXISTS ] constraintName | PRIMARY KEY }
"," ","
Removes a constraint or a primary key from a table." Removes a constraint or a primary key from a table."
"Commands (DDL)","ALTER TABLE SET"," "Commands (DDL)","ALTER TABLE SET","
ALTER TABLE tableName SET REFERENTIAL_INTEGRITY ALTER TABLE [ IF EXISTS ] tableName SET REFERENTIAL_INTEGRITY
{ FALSE | TRUE [ CHECK | NOCHECK ] } { FALSE | TRUE [ CHECK | NOCHECK ] }
"," ","
Disables or enables referential integrity checking for a table." Disables or enables referential integrity checking for a table."
"Commands (DDL)","ALTER TABLE RENAME"," "Commands (DDL)","ALTER TABLE RENAME","
ALTER TABLE tableName RENAME TO newName ALTER TABLE [ IF EXISTS ] tableName RENAME TO newName
"," ","
Renames a table." Renames a table."
"Commands (DDL)","ALTER USER ADMIN"," "Commands (DDL)","ALTER USER ADMIN","
...@@ -138,7 +138,7 @@ ALTER USER userName SET { PASSWORD string | SALT bytes HASH bytes } ...@@ -138,7 +138,7 @@ ALTER USER userName SET { PASSWORD string | SALT bytes HASH bytes }
"," ","
Changes the password of a user." Changes the password of a user."
"Commands (DDL)","ALTER VIEW"," "Commands (DDL)","ALTER VIEW","
ALTER VIEW viewName RECOMPILE ALTER VIEW [ IF EXISTS ] viewName RECOMPILE
"," ","
Recompiles a view after the underlying tables have been changed or created." Recompiles a view after the underlying tables have been changed or created."
"Commands (DDL)","ANALYZE"," "Commands (DDL)","ANALYZE","
......
...@@ -2991,6 +2991,12 @@ CREATE memory TABLE ADDRESS(ID INT); ...@@ -2991,6 +2991,12 @@ CREATE memory TABLE ADDRESS(ID INT);
alter view address_view recompile; alter view address_view recompile;
> ok > ok
alter view if exists address_view recompile;
> ok
alter view if exists doesnt_exist recompile;
> ok
select * from ADDRESS_VIEW; select * from ADDRESS_VIEW;
> ID > ID
> -- > --
...@@ -4452,7 +4458,31 @@ create index if not exists idx_id on s.test(id); ...@@ -4452,7 +4458,31 @@ create index if not exists idx_id on s.test(id);
create index if not exists idx_id on s.test(id); create index if not exists idx_id on s.test(id);
> ok > ok
alter index s.idx_id rename to s.index_id; alter index s.idx_id rename to s.x;
> ok
alter index if exists s.idx_id rename to s.x;
> ok
alter index if exists s.x rename to s.index_id;
> ok
alter sequence if exists s.seq restart with 10;
> ok
create sequence s.seq cache 0;
> ok
alter sequence if exists s.seq restart with 3;
> ok
select s.seq.nextval as x;
> X
> -
> 3
> rows: 1
drop sequence s.seq;
> ok > ok
create sequence s.seq cache 0; create sequence s.seq cache 0;
...@@ -10197,3 +10227,225 @@ select 0 from (( ...@@ -10197,3 +10227,225 @@ select 0 from ((
> rows: 0 > rows: 0
}; };
> update count: 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
create schema x;
> ok
alter schema if exists y rename to z;
> ok
alter schema if exists x rename to z;
> ok
alter schema if exists x rename to z;
> ok
create table z.z (id int);
> ok
drop schema z;
> ok
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论