From 744b27767541b60af89a1726b8d66ad82c0884e4 Mon Sep 17 00:00:00 2001 From: XudongXie Date: Fri, 13 Sep 2024 15:35:12 +0800 Subject: [PATCH] add alter --- sqlTranslate/.idea/workspace.xml | 31 ++++++++++++------- .../main/java/Document/Alter table in Oracle | 13 +++++++- .../java/Generator/OpenGaussGenerator.java | 27 +++++++++++++++- .../src/main/java/Interface/ColumnType.java | 9 ++++++ .../src/main/java/Lexer/OracleLexer.java | 2 +- sqlTranslate/src/main/java/Main.java | 19 ++++++------ .../AST/AlterTable/AlterAddColumnNode.java | 7 ++++- .../AST/AlterTable/AlterModifyColumnNode.java | 31 ++++++++++--------- .../Parser/AST/CreateTable/ColumnNode.java | 6 +++- .../src/main/java/Parser/OracleParser.java | 9 +++--- 10 files changed, 109 insertions(+), 45 deletions(-) create mode 100644 sqlTranslate/src/main/java/Interface/ColumnType.java diff --git a/sqlTranslate/.idea/workspace.xml b/sqlTranslate/.idea/workspace.xml index 76fb709cc..5750f8088 100644 --- a/sqlTranslate/.idea/workspace.xml +++ b/sqlTranslate/.idea/workspace.xml @@ -4,9 +4,16 @@ - @@ -488,7 +494,8 @@ - diff --git a/sqlTranslate/src/main/java/Document/Alter table in Oracle b/sqlTranslate/src/main/java/Document/Alter table in Oracle index 486187262..9098a6647 100644 --- a/sqlTranslate/src/main/java/Document/Alter table in Oracle +++ b/sqlTranslate/src/main/java/Document/Alter table in Oracle @@ -5,4 +5,15 @@ action = ADD column_name data_type [constraint] | RENAME COLUMN old_column_name TO new_column_name | ADD CONSTRAINT constraint_name constraint_definition | DROP CONSTRAINT constraint_name -| RENAME old_table_name TO new_table_name \ No newline at end of file +| RENAME old_table_name TO new_table_name + +Example: +ALTER TABLE employees ADD email VARCHAR2(100); +| ALTER TABLE employees ADD email LONG RAW; +| ALTER TABLE employees DROP COLUMN middle_name; +| ALTER TABLE employees MODIFY salary NUMBER(10,2); +| ALTER TABLE employees MODIFY salary ROWID; +| ALTER TABLE employees RENAME COLUMN first_name TO given_name; +| ALTER TABLE employees ADD CONSTRAINT emp_pk PRIMARY KEY (employee_id); +| ALTER TABLE employees DROP CONSTRAINT emp_pk; +| ALTER TABLE employees RENAME TO staff; \ No newline at end of file diff --git a/sqlTranslate/src/main/java/Generator/OpenGaussGenerator.java b/sqlTranslate/src/main/java/Generator/OpenGaussGenerator.java index f54da8736..6a1de0aea 100644 --- a/sqlTranslate/src/main/java/Generator/OpenGaussGenerator.java +++ b/sqlTranslate/src/main/java/Generator/OpenGaussGenerator.java @@ -1,7 +1,11 @@ package Generator; +import Interface.ColumnType; import Lexer.Token; import Parser.AST.ASTNode; +import Parser.AST.AlterTable.AlterAddColumnNode; +import Parser.AST.AlterTable.AlterModifyColumnNode; +import Parser.AST.AlterTable.AlterNode; import Parser.AST.CreateTable.ColumnNode; import Parser.AST.CreateTable.CreateTabNode; import Exception.GenerateFailedException; @@ -52,6 +56,9 @@ public class OpenGaussGenerator { else if (node instanceof DeleteNode) { return GenDeleteSQL(node); } + else if (node instanceof AlterNode) { + return GenAlterSQL(node); + } else { try { throw new GenerateFailedException("Root node:" + node.getClass() + "(Unsupported node type!)"); @@ -101,6 +108,12 @@ public class OpenGaussGenerator { return node.toQueryString(); } + private String GenAlterSQL(ASTNode node) { + visitAlter(node); +// System.out.println(node.getASTString()); + return node.toQueryString(); + } + private void visitCrt(ASTNode node) { if (node instanceof ColumnNode) { ColumnTypeConvert((ColumnNode) node); @@ -176,7 +189,19 @@ public class OpenGaussGenerator { } } - private void ColumnTypeConvert(ColumnNode node) { + private void visitAlter(ASTNode node) { + if (node instanceof AlterAddColumnNode) { + ColumnTypeConvert((AlterAddColumnNode) node); + } + else if (node instanceof AlterModifyColumnNode) { + ColumnTypeConvert((AlterModifyColumnNode) node); + } + for (ASTNode child : node.getChildren()) { + visitAlter(child); + } + } + + private void ColumnTypeConvert(ColumnType node) { // type convert if (node.getType().getValue().equalsIgnoreCase("NUMBER")) { node.setType(new Token(Token.TokenType.KEYWORD, "NUMERIC")); diff --git a/sqlTranslate/src/main/java/Interface/ColumnType.java b/sqlTranslate/src/main/java/Interface/ColumnType.java new file mode 100644 index 000000000..1e82d1016 --- /dev/null +++ b/sqlTranslate/src/main/java/Interface/ColumnType.java @@ -0,0 +1,9 @@ +package Interface; + +import Lexer.Token; + +public interface ColumnType { + Token getType(); + void setType(Token type); + void ResetTokensbyNameTypeConstraint(); +} diff --git a/sqlTranslate/src/main/java/Lexer/OracleLexer.java b/sqlTranslate/src/main/java/Lexer/OracleLexer.java index c45153568..0d18fb8b0 100644 --- a/sqlTranslate/src/main/java/Lexer/OracleLexer.java +++ b/sqlTranslate/src/main/java/Lexer/OracleLexer.java @@ -24,7 +24,7 @@ public class OracleLexer { // keywords of update , "SET" // keywords of alter table - , "ALTER", "ADD", "DROP", "MODIFY", "RENAME", "TO" + , "ALTER", "ADD", "DROP", "MODIFY", "RENAME", "TO", "COLUMN" }; private static final Pattern TOKEN_PATTERN = Pattern.compile( "(NUMBER\\(.*?\\))|" + // NUMBER() function diff --git a/sqlTranslate/src/main/java/Main.java b/sqlTranslate/src/main/java/Main.java index 3c26a5029..14c1b2af8 100644 --- a/sqlTranslate/src/main/java/Main.java +++ b/sqlTranslate/src/main/java/Main.java @@ -7,14 +7,14 @@ import Parser.OracleParser; public class Main { public static void main(String[] args) { -// String sql = "CREATE TABLE employees (\n" + -// " employee_id NUMBER PRIMARY KEY,\n" + -// " first_name VARCHAR2(20) Check(first_name > '221'),\n" + -// " last_name VARCHAR2(25),\n" + -// " email VARCHAR2(25),\n" + -// " hire_date DATE,\n" + -// " CONSTRAINT chk_example CHECK (employee_id > 0)" + -// ");"; + String sql = "CREATE TABLE employees (\n" + + " employee_id NUMBER PRIMARY KEY,\n" + + " first_name VARCHAR2(20) Check(first_name > '221'),\n" + + " last_name VARCHAR2(25) Check (last_name != '12813@163.com'),\n" + + " email VARCHAR2(25),\n" + + " hire_date DATE,\n" + + " CONSTRAINT chk_example CHECK (employee_id > 0)" + + ");"; // String sql = "INSERT INTO employees (first_name, last_name, email) VALUES ('Jane', 'Smith', 'janesm@example.com');"; // String sql = "DROP TABLE employees CASCADE CONSTRAINTS;"; // String sql = "SELECT e.first_name, d.department_name FROM employees e JOIN departments d Using e.department_id = d.department_id;"; @@ -30,8 +30,7 @@ public class Main { // " FROM departments d\n" + // " WHERE d.department_name = 'Sales'\n" + // ");"; - String sql = "ALTER TABLE employees ADD email VARCHAR2(100) Check (email != '12813@163.com');"; -// String sql = "ALTER TABLE employees ADD CONSTRAINT emp_pk PRIMARY KEY (employee_id);"; +// String sql = "ALTER TABLE employees ADD email VARCHAR2(100) Check (email != '12813@163.com');"; OracleLexer lexer = new OracleLexer(sql); lexer.printTokens(); OracleParser parser = new OracleParser(lexer); diff --git a/sqlTranslate/src/main/java/Parser/AST/AlterTable/AlterAddColumnNode.java b/sqlTranslate/src/main/java/Parser/AST/AlterTable/AlterAddColumnNode.java index 0451f2586..0eb23739e 100644 --- a/sqlTranslate/src/main/java/Parser/AST/AlterTable/AlterAddColumnNode.java +++ b/sqlTranslate/src/main/java/Parser/AST/AlterTable/AlterAddColumnNode.java @@ -1,12 +1,13 @@ package Parser.AST.AlterTable; +import Interface.ColumnType; import Lexer.Token; import Parser.AST.ASTNode; import java.util.ArrayList; import java.util.List; -public class AlterAddColumnNode extends ASTNode { +public class AlterAddColumnNode extends ASTNode implements ColumnType { private Token name; private Token type; private List constraint; @@ -41,10 +42,12 @@ public class AlterAddColumnNode extends ASTNode { this.name = name; } + @Override public Token getType() { return type; } + @Override public void setType(Token type) { this.type = type; } @@ -57,8 +60,10 @@ public class AlterAddColumnNode extends ASTNode { this.constraint = constraint; } + @Override public void ResetTokensbyNameTypeConstraint() { List tokens = new ArrayList<>(); + tokens.add(new Token(Token.TokenType.KEYWORD, "ADD")); tokens.add(name); tokens.add(type); for (Token token : constraint) { diff --git a/sqlTranslate/src/main/java/Parser/AST/AlterTable/AlterModifyColumnNode.java b/sqlTranslate/src/main/java/Parser/AST/AlterTable/AlterModifyColumnNode.java index 14a70e03c..495b174d9 100644 --- a/sqlTranslate/src/main/java/Parser/AST/AlterTable/AlterModifyColumnNode.java +++ b/sqlTranslate/src/main/java/Parser/AST/AlterTable/AlterModifyColumnNode.java @@ -1,14 +1,15 @@ package Parser.AST.AlterTable; +import Interface.ColumnType; import Lexer.Token; import Parser.AST.ASTNode; import java.util.ArrayList; import java.util.List; -public class AlterModifyColumnNode extends ASTNode { - private Token columnName; - private Token columnType; +public class AlterModifyColumnNode extends ASTNode implements ColumnType { + private Token name; + private Token type; public AlterModifyColumnNode() { super(); @@ -22,20 +23,22 @@ public class AlterModifyColumnNode extends ASTNode { super(tokens); } - public void setColumnType(Token columnType) { - this.columnType = columnType; + @Override + public void setType(Token columnType) { + this.type = columnType; } - public Token getColumnType() { - return columnType; + @Override + public Token getType() { + return type; } - public void setColumnName(Token columnName) { - this.columnName = columnName; + public void setName(Token columnName) { + this.name = columnName; } - public Token getColumnName() { - return columnName; + public Token getName() { + return name; } @Override @@ -46,12 +49,12 @@ public class AlterModifyColumnNode extends ASTNode { } } + @Override public void ResetTokensbyNameTypeConstraint() { List tokens = new ArrayList<>(); tokens.add(new Token(Token.TokenType.KEYWORD, "MODIFY")); - tokens.add(columnName); - tokens.add(columnType); - tokens.add(new Token(Token.TokenType.SYMBOL, ";")); + tokens.add(name); + tokens.add(type); setTokens(tokens); } } diff --git a/sqlTranslate/src/main/java/Parser/AST/CreateTable/ColumnNode.java b/sqlTranslate/src/main/java/Parser/AST/CreateTable/ColumnNode.java index bd0155ef8..c470ffff3 100644 --- a/sqlTranslate/src/main/java/Parser/AST/CreateTable/ColumnNode.java +++ b/sqlTranslate/src/main/java/Parser/AST/CreateTable/ColumnNode.java @@ -1,12 +1,13 @@ package Parser.AST.CreateTable; +import Interface.ColumnType; import Lexer.Token; import Parser.AST.ASTNode; import java.util.ArrayList; import java.util.List; -public class ColumnNode extends ASTNode { +public class ColumnNode extends ASTNode implements ColumnType { private Token name; private Token type; private List constraint; @@ -42,10 +43,12 @@ public class ColumnNode extends ASTNode { this.name = name; } + @Override public Token getType() { return type; } + @Override public void setType(Token type) { this.type = type; } @@ -58,6 +61,7 @@ public class ColumnNode extends ASTNode { this.constraint = constraint; } + @Override public void ResetTokensbyNameTypeConstraint() { List tokens = new ArrayList<>(); tokens.add(name); diff --git a/sqlTranslate/src/main/java/Parser/OracleParser.java b/sqlTranslate/src/main/java/Parser/OracleParser.java index fd0e360bc..690527f69 100644 --- a/sqlTranslate/src/main/java/Parser/OracleParser.java +++ b/sqlTranslate/src/main/java/Parser/OracleParser.java @@ -970,6 +970,7 @@ public class OracleParser { (parseTokens.get(j).getValue().equalsIgnoreCase("REFERENCES") || parseTokens.get(j).getValue().equalsIgnoreCase("CHECK"))) { tokens.add(parseTokens.get(j)); + constraint.add(parseTokens.get(j)); Stack stack = new Stack<>(); for (int k = j + 1; k < parseTokens.size(); k++) { tokens.add(parseTokens.get(k)); @@ -1001,7 +1002,7 @@ public class OracleParser { } if (!state) tokens.add(parseTokens.get(j)); - if (j != i + 1) { + if (!state && j != i + 1) { constraint.add(parseTokens.get(j)); } } @@ -1119,10 +1120,10 @@ public class OracleParser { AlterModifyColumnNode childNode = new AlterModifyColumnNode(); for (int j = i + 1; j < parseTokens.size(); j++) { if (j == i + 1) { - childNode.setColumnName(parseTokens.get(j)); + childNode.setName(parseTokens.get(j)); } if (j == i + 2) { - childNode.setColumnType(parseTokens.get(j)); + childNode.setType(parseTokens.get(j)); } if (j > i + 3) { try { @@ -1158,7 +1159,7 @@ public class OracleParser { currentNode.addChild(childNode); currentNode = childNode; } - else if (i + 1 < parseTokens.size() && parseTokens.get(i + 1).hasType(Token.TokenType.IDENTIFIER)) { + else if (i + 1 < parseTokens.size() && parseTokens.get(i + 1).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i + 1).getValue().equalsIgnoreCase("TO")) { tokens = new ArrayList<>(); tokens.add(parseTokens.get(i)); for (int j = i + 1; j < parseTokens.size(); j++) {