Unverified 提交 a440ce8c authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov 提交者: GitHub

Merge pull request #1680 from katzyn/ddl

Assorted fixes for ALTER TABLE ALTER COLUMN
...@@ -355,11 +355,13 @@ ALTER TABLE [ IF EXISTS ] tableName ALTER COLUMN columnName ...@@ -355,11 +355,13 @@ ALTER TABLE [ IF EXISTS ] tableName ALTER COLUMN columnName
| { RESTART WITH long } | { RESTART WITH long }
| { SELECTIVITY int } | { SELECTIVITY int }
| { SET DEFAULT expression } | { SET DEFAULT expression }
| { DROP DEFAULT }
| { SET ON UPDATE expression } | { SET ON UPDATE expression }
| { SET NULL } | { DROP ON UPDATE }
| { SET NOT NULL } | { SET NOT NULL }
| { SET { VISIBLE | INVISIBLE } } | { DROP NOT NULL } | { SET NULL }
| { DROP { DEFAULT | ON UPDATE } } } | { SET DATA TYPE dataType }
| { SET { VISIBLE | INVISIBLE } } }
"," ","
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.
...@@ -377,19 +379,20 @@ Selectivity 100 means values are unique, 10 means every distinct value appears 1 ...@@ -377,19 +379,20 @@ Selectivity 100 means values are unique, 10 means every distinct value appears 1
SET DEFAULT changes the default value of a column. SET DEFAULT changes the default value of a column.
DROP DEFAULT removes the default value of a column.
SET ON UPDATE changes the value that is set on update if value for this column is not specified in update statement. SET ON UPDATE changes the value that is set on update if value for this column is not specified in update statement.
SET NULL sets a column to allow NULL. The row may not be part of a primary key. DROP ON UPDATE removes the value that is set on update of a column.
Single column indexes on this column are dropped.
SET NOT NULL sets a column to not allow NULL. Rows may not contains NULL in this column. SET NOT NULL sets a column to not allow NULL. Rows may not contains NULL in this column.
SET INVISIBLE makes the column hidden, i.e. it will not appear in SELECT * results. DROP NOT NULL and SET NULL set a column to allow NULL. The row may not be part of a primary key.
SET VISIBLE has the reverse effect.
DROP DEFAULT removes the default value of a column. SET DATA TYPE changes the data type of a column.
DROP ON UPDATE removes the value that is set on update of a column. SET INVISIBLE makes the column hidden, i.e. it will not appear in SELECT * results.
SET VISIBLE has the reverse effect.
This command commits an open transaction in this connection. This command commits an open transaction in this connection.
"," ","
......
...@@ -63,12 +63,13 @@ public interface CommandInterface { ...@@ -63,12 +63,13 @@ public interface CommandInterface {
int ALTER_TABLE_ALTER_COLUMN_NOT_NULL = 8; int ALTER_TABLE_ALTER_COLUMN_NOT_NULL = 8;
/** /**
* The type of a ALTER TABLE ALTER COLUMN SET NULL statement. * The type of a ALTER TABLE ALTER COLUMN DROP NOT NULL statement.
*/ */
int ALTER_TABLE_ALTER_COLUMN_NULL = 9; int ALTER_TABLE_ALTER_COLUMN_DROP_NOT_NULL = 9;
/** /**
* The type of a ALTER TABLE ALTER COLUMN SET DEFAULT statement. * The type of a ALTER TABLE ALTER COLUMN SET DEFAULT and ALTER TABLE ALTER
* COLUMN DROP DEFAULT statements.
*/ */
int ALTER_TABLE_ALTER_COLUMN_DEFAULT = 10; int ALTER_TABLE_ALTER_COLUMN_DEFAULT = 10;
......
...@@ -7216,7 +7216,7 @@ public class Parser { ...@@ -7216,7 +7216,7 @@ public class Parser {
Column column = columnIfTableExists(schema, tableName, columnName, ifTableExists); Column column = columnIfTableExists(schema, tableName, columnName, ifTableExists);
command.setOldColumn(column); command.setOldColumn(column);
if (nullConstraint == NullConstraintType.NULL_IS_ALLOWED) { if (nullConstraint == NullConstraintType.NULL_IS_ALLOWED) {
command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_NULL); command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_DROP_NOT_NULL);
} else { } else {
command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_NOT_NULL); command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_NOT_NULL);
} }
...@@ -7247,10 +7247,8 @@ public class Parser { ...@@ -7247,10 +7247,8 @@ public class Parser {
command.setNewColumnName(newName); command.setNewColumnName(newName);
return command; return command;
} else if (readIf("DROP")) { } else if (readIf("DROP")) {
// PostgreSQL compatibility
if (readIf("DEFAULT")) { if (readIf("DEFAULT")) {
AlterTableAlterColumn command = new AlterTableAlterColumn( AlterTableAlterColumn command = new AlterTableAlterColumn(session, schema);
session, schema);
command.setTableName(tableName); command.setTableName(tableName);
command.setIfTableExists(ifTableExists); command.setIfTableExists(ifTableExists);
command.setOldColumn(column); command.setOldColumn(column);
...@@ -7275,18 +7273,15 @@ public class Parser { ...@@ -7275,18 +7273,15 @@ public class Parser {
command.setTableName(tableName); command.setTableName(tableName);
command.setIfTableExists(ifTableExists); command.setIfTableExists(ifTableExists);
command.setOldColumn(column); command.setOldColumn(column);
command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_NULL); command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_DROP_NOT_NULL);
return command; return command;
} else if (readIf("TYPE")) { } else if (readIf("TYPE")) {
// PostgreSQL compatibility // PostgreSQL compatibility
return parseAlterTableAlterColumnType(schema, tableName, return parseAlterTableAlterColumnDataType(schema, tableName, columnName, ifTableExists);
columnName, ifTableExists);
} else if (readIf("SET")) { } else if (readIf("SET")) {
if (readIf("DATA")) { if (readIf("DATA")) {
// Derby compatibility
read("TYPE"); read("TYPE");
return parseAlterTableAlterColumnType(schema, tableName, columnName, return parseAlterTableAlterColumnDataType(schema, tableName, columnName, ifTableExists);
ifTableExists);
} }
AlterTableAlterColumn command = new AlterTableAlterColumn( AlterTableAlterColumn command = new AlterTableAlterColumn(
session, schema); session, schema);
...@@ -7296,7 +7291,7 @@ public class Parser { ...@@ -7296,7 +7291,7 @@ public class Parser {
NullConstraintType nullConstraint = parseNotNullConstraint(); NullConstraintType nullConstraint = parseNotNullConstraint();
switch (nullConstraint) { switch (nullConstraint) {
case NULL_IS_ALLOWED: case NULL_IS_ALLOWED:
command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_NULL); command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_DROP_NOT_NULL);
break; break;
case NULL_IS_NOT_ALLOWED: case NULL_IS_NOT_ALLOWED:
command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_NOT_NULL); command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_NOT_NULL);
...@@ -7343,8 +7338,7 @@ public class Parser { ...@@ -7343,8 +7338,7 @@ public class Parser {
command.setSelectivity(readExpression()); command.setSelectivity(readExpression());
return command; return command;
} else { } else {
return parseAlterTableAlterColumnType(schema, tableName, return parseAlterTableAlterColumnType(schema, tableName, columnName, ifTableExists);
columnName, ifTableExists);
} }
} }
throw getSyntaxError(); throw getSyntaxError();
...@@ -7376,8 +7370,48 @@ public class Parser { ...@@ -7376,8 +7370,48 @@ public class Parser {
Column oldColumn = columnIfTableExists(schema, tableName, columnName, ifTableExists); Column oldColumn = columnIfTableExists(schema, tableName, columnName, ifTableExists);
Column newColumn = parseColumnForTable(columnName, Column newColumn = parseColumnForTable(columnName,
oldColumn == null ? true : oldColumn.isNullable(), true); oldColumn == null ? true : oldColumn.isNullable(), true);
AlterTableAlterColumn command = new AlterTableAlterColumn(session, if (readIf(CHECK)) {
schema); Expression expr = readExpression();
newColumn.addCheckConstraint(session, expr);
}
AlterTableAlterColumn command = new AlterTableAlterColumn(session, schema);
command.setTableName(tableName);
command.setIfTableExists(ifTableExists);
command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_CHANGE_TYPE);
command.setOldColumn(oldColumn);
command.setNewColumn(newColumn);
return command;
}
private AlterTableAlterColumn parseAlterTableAlterColumnDataType(Schema schema,
String tableName, String columnName, boolean ifTableExists) {
Column oldColumn = columnIfTableExists(schema, tableName, columnName, ifTableExists);
Column newColumn = parseColumnWithType(columnName, true);
if (oldColumn != null) {
if (!oldColumn.isNullable()) {
newColumn.setNullable(false);
}
if (!oldColumn.getVisible()) {
newColumn.setVisible(false);
}
Expression e = oldColumn.getDefaultExpression();
if (e != null) {
newColumn.setDefaultExpression(session, e);
}
e = oldColumn.getOnUpdateExpression();
if (e != null) {
newColumn.setOnUpdateExpression(session, e);
}
e = oldColumn.getCheckConstraint(session, columnName);
if (e != null) {
newColumn.addCheckConstraint(session, e);
}
String c = oldColumn.getComment();
if (c != null) {
newColumn.setComment(c);
}
}
AlterTableAlterColumn command = new AlterTableAlterColumn(session, schema);
command.setTableName(tableName); command.setTableName(tableName);
command.setIfTableExists(ifTableExists); command.setIfTableExists(ifTableExists);
command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_CHANGE_TYPE); command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_CHANGE_TYPE);
......
...@@ -137,7 +137,7 @@ public class AlterTableAlterColumn extends CommandWithColumns { ...@@ -137,7 +137,7 @@ public class AlterTableAlterColumn extends CommandWithColumns {
db.updateMeta(session, table); db.updateMeta(session, table);
break; break;
} }
case CommandInterface.ALTER_TABLE_ALTER_COLUMN_NULL: { case CommandInterface.ALTER_TABLE_ALTER_COLUMN_DROP_NOT_NULL: {
if (oldColumn.isNullable()) { if (oldColumn.isNullable()) {
// no change // no change
break; break;
......
...@@ -152,9 +152,9 @@ public class TestScript extends TestDb { ...@@ -152,9 +152,9 @@ public class TestScript extends TestDb {
"uuid", "varchar", "varchar-ignorecase" }) { "uuid", "varchar", "varchar-ignorecase" }) {
testScript("datatypes/" + s + ".sql"); testScript("datatypes/" + s + ".sql");
} }
for (String s : new String[] { "alterTableAdd", "alterTableDropColumn", "alterTableRename", for (String s : new String[] { "alterTableAdd", "alterTableAlterColumn", "alterTableDropColumn",
"createAlias", "createSequence", "createSynonym", "createTable", "createTrigger", "createView", "alterTableRename", "createAlias", "createSequence", "createSynonym", "createTable", "createTrigger",
"dropDomain", "dropIndex", "dropSchema", "truncateTable" }) { "createView", "dropDomain", "dropIndex", "dropSchema", "truncateTable" }) {
testScript("ddl/" + s + ".sql"); testScript("ddl/" + s + ".sql");
} }
for (String s : new String[] { "delete", "error_reporting", "insert", "insertIgnore", "merge", "mergeUsing", for (String s : new String[] { "delete", "error_reporting", "insert", "insertIgnore", "merge", "mergeUsing",
......
-- Copyright 2004-2019 H2 Group. Multiple-Licensed under the MPL 2.0,
-- and the EPL 1.0 (http://h2database.com/html/license.html).
-- Initial Developer: H2 Group
--
CREATE TABLE TEST(T INT);
> ok
SELECT COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME = 'T';
>> INT
-- SET DEFAULT
ALTER TABLE TEST ALTER COLUMN T SET DEFAULT 1;
> ok
SELECT COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME = 'T';
>> INT DEFAULT 1
-- DROP DEFAULT
ALTER TABLE TEST ALTER COLUMN T DROP DEFAULT;
> ok
SELECT COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME = 'T';
>> INT
-- SET NOT NULL
ALTER TABLE TEST ALTER COLUMN T SET NOT NULL;
> ok
SELECT COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME = 'T';
>> INT NOT NULL
-- DROP NOT NULL
ALTER TABLE TEST ALTER COLUMN T DROP NOT NULL;
> ok
SELECT COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME = 'T';
>> INT
ALTER TABLE TEST ALTER COLUMN T SET NOT NULL;
> ok
-- SET NULL
ALTER TABLE TEST ALTER COLUMN T SET NULL;
> ok
SELECT COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME = 'T';
>> INT
-- SET DATA TYPE
ALTER TABLE TEST ALTER COLUMN T SET DATA TYPE BIGINT;
> ok
SELECT COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME = 'T';
>> BIGINT
ALTER TABLE TEST ALTER COLUMN T INT INVISIBLE DEFAULT 1 ON UPDATE 2 NOT NULL COMMENT 'C' CHECK T < 100;
> ok
SELECT COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME = 'T';
>> INT INVISIBLE DEFAULT 1 ON UPDATE 2 NOT NULL COMMENT 'C' CHECK (T < 100)
ALTER TABLE TEST ALTER COLUMN T SET DATA TYPE BIGINT;
> ok
SELECT COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME = 'T';
>> BIGINT INVISIBLE DEFAULT 1 ON UPDATE 2 NOT NULL COMMENT 'C' CHECK (T < 100)
DROP TABLE TEST;
> ok
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论