Unverified 提交 7c9d6bad authored 作者: Noel Grandin's avatar Noel Grandin 提交者: GitHub

Merge pull request #661 from plus33/master

Support drop-columns using brackets (Oracle syntax style) 
...@@ -3486,6 +3486,20 @@ public class Parser { ...@@ -3486,6 +3486,20 @@ public class Parser {
addExpected(token); addExpected(token);
return false; return false;
} }
/*
* Reads passed token in list, in order and returns true on first match.
* If none of the token matches returns false
*/
private boolean readIfOr(String ... tokens) {
for(String token: tokens) {
if (readIf(token)) {
return true;
}
}
return false;
}
/* /*
* Reads every token in list, in order - returns true if all are found. * Reads every token in list, in order - returns true if all are found.
* If any are not found, returns false - AND resets parsing back to state when called. * If any are not found, returns false - AND resets parsing back to state when called.
...@@ -4466,7 +4480,7 @@ public class Parser { ...@@ -4466,7 +4480,7 @@ public class Parser {
} }
original += "(" + p; original += "(" + p;
// Oracle syntax // Oracle syntax
readIf("CHAR"); readIfOr("CHAR", "BYTE");
if (dataType.supportsScale) { if (dataType.supportsScale) {
if (readIf(",")) { if (readIf(",")) {
scale = readInt(); scale = readInt();
...@@ -6073,6 +6087,7 @@ public class Parser { ...@@ -6073,6 +6087,7 @@ public class Parser {
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); Table table = tableIfTableExists(schema, tableName, ifTableExists);
boolean openingBracketDetected = readIf("("); // For Oracle compatibility - open bracket required
do { do {
String columnName = readColumnIdentifier(); String columnName = readColumnIdentifier();
if (table == null) { if (table == null) {
...@@ -6084,6 +6099,9 @@ public class Parser { ...@@ -6084,6 +6099,9 @@ public class Parser {
Column column = table.getColumn(columnName); Column column = table.getColumn(columnName);
columnsToRemove.add(column); columnsToRemove.add(column);
} while (readIf(",")); } while (readIf(","));
if (openingBracketDetected) {
read(")"); // For Oracle compatibility - close bracket
}
command.setTableName(tableName); command.setTableName(tableName);
command.setIfTableExists(ifTableExists); command.setIfTableExists(ifTableExists);
command.setColumnsToRemove(columnsToRemove); command.setColumnsToRemove(columnsToRemove);
......
...@@ -113,10 +113,18 @@ public class TestAlter extends TestBase { ...@@ -113,10 +113,18 @@ public class TestAlter extends TestBase {
} }
private void testAlterTableDropMultipleColumns() throws SQLException { private void testAlterTableDropMultipleColumns() throws SQLException {
stat.execute("create table test(id int, name varchar, name2 varchar)"); stat.execute("create table test(id int, b varchar, c int, d int)");
stat.execute("alter table test drop column name, name2"); stat.execute("alter table test drop column b, c");
stat.execute("alter table test drop d");
stat.execute("drop table test"); stat.execute("drop table test");
// Test-Case: Same as above but using brackets (Oracle style)
stat.execute("create table test(id int, b varchar, c int, d int)");
stat.execute("alter table test drop column (b, c)");
assertThrows(ErrorCode.COLUMN_NOT_FOUND_1, stat).
execute("alter table test drop column b");
stat.execute("alter table test drop (d)");
stat.execute("drop table test");
// Test-Case: Error if dropping all columns
stat.execute("create table test(id int, name varchar, name2 varchar)"); stat.execute("create table test(id int, name varchar, name2 varchar)");
assertThrows(ErrorCode.CANNOT_DROP_LAST_COLUMN, stat). assertThrows(ErrorCode.CANNOT_DROP_LAST_COLUMN, stat).
execute("alter table test drop column id, name, name2"); execute("alter table test drop column id, name, name2");
...@@ -209,6 +217,8 @@ public class TestAlter extends TestBase { ...@@ -209,6 +217,8 @@ public class TestAlter extends TestBase {
stat.execute("drop table t"); stat.execute("drop table t");
} }
// column and field names must be upper-case due to getMetaData sensitivity // column and field names must be upper-case due to getMetaData sensitivity
private void testAlterTableAddMultipleColumnsBefore() throws SQLException { private void testAlterTableAddMultipleColumnsBefore() throws SQLException {
stat.execute("create table T(X varchar)"); stat.execute("create table T(X varchar)");
......
...@@ -40,6 +40,7 @@ public class TestCompatibilityOracle extends TestBase { ...@@ -40,6 +40,7 @@ public class TestCompatibilityOracle extends TestBase {
testPoundSymbolInColumnName(); testPoundSymbolInColumnName();
testToDate(); testToDate();
testForbidEmptyInClause(); testForbidEmptyInClause();
testSpecialTypes();
} }
private void testNotNullSyntax() throws SQLException { private void testNotNullSyntax() throws SQLException {
...@@ -85,13 +86,29 @@ public class TestCompatibilityOracle extends TestBase { ...@@ -85,13 +86,29 @@ public class TestCompatibilityOracle extends TestBase {
conn.close(); conn.close();
} }
private void testSpecialTypes() throws SQLException {
// Test VARCHAR, VARCHAR2 with CHAR and BYTE
deleteDb("oracle");
Connection conn = getConnection("oracle;MODE=Oracle");
Statement stat = conn.createStatement();
stat.execute("create table T (ID NUMBER)");
stat.execute("alter table T add A_1 VARCHAR(1)");
stat.execute("alter table T add A_2 VARCHAR2(1)");
stat.execute("alter table T add B_1 VARCHAR(1 byte)"); // with BYTE
stat.execute("alter table T add B_2 VARCHAR2(1 byte)");
stat.execute("alter table T add C_1 VARCHAR(1 char)"); // with CHAR
stat.execute("alter table T add C_2 VARCHAR2(1 char)");
stat.execute("alter table T add B_255 VARCHAR(255 byte)");
stat.execute("alter table T add C_255 VARCHAR(255 char)");
stat.execute("drop table T");
conn.close();
}
private void testTreatEmptyStringsAsNull() throws SQLException { private void testTreatEmptyStringsAsNull() throws SQLException {
deleteDb("oracle"); deleteDb("oracle");
Connection conn = getConnection("oracle;MODE=Oracle"); Connection conn = getConnection("oracle;MODE=Oracle");
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
stat.execute("CREATE TABLE A (ID NUMBER, X VARCHAR2(1))"); stat.execute("CREATE TABLE A (ID NUMBER, X VARCHAR2(1))");
stat.execute("INSERT INTO A VALUES (1, 'a')"); stat.execute("INSERT INTO A VALUES (1, 'a')");
stat.execute("INSERT INTO A VALUES (2, '')"); stat.execute("INSERT INTO A VALUES (2, '')");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论