diff --git a/sqlTranslate/.idea/compiler.xml b/sqlTranslate/.idea/compiler.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8e6776c3e87f79e02c1bdc519cdca402eae3ce0b
--- /dev/null
+++ b/sqlTranslate/.idea/compiler.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sqlTranslate/.idea/encodings.xml b/sqlTranslate/.idea/encodings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..aa00ffab7828f4818589659c804ec2cfd99baed3
--- /dev/null
+++ b/sqlTranslate/.idea/encodings.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sqlTranslate/.idea/jarRepositories.xml b/sqlTranslate/.idea/jarRepositories.xml
new file mode 100644
index 0000000000000000000000000000000000000000..712ab9d985c20018a0c97b93d2148ac1ffe588a5
--- /dev/null
+++ b/sqlTranslate/.idea/jarRepositories.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sqlTranslate/.idea/misc.xml b/sqlTranslate/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e5d62959271289a9b1b3570311149ea6f3a7c12b
--- /dev/null
+++ b/sqlTranslate/.idea/misc.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sqlTranslate/.idea/uiDesigner.xml b/sqlTranslate/.idea/uiDesigner.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2b63946d5b31084bbb7dda418ceb3d75eb686373
--- /dev/null
+++ b/sqlTranslate/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/sqlTranslate/.idea/vcs.xml b/sqlTranslate/.idea/vcs.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6c0b8635858dc7ad44b93df54b762707ce49eefc
--- /dev/null
+++ b/sqlTranslate/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sqlTranslate/.idea/workspace.xml b/sqlTranslate/.idea/workspace.xml
new file mode 100644
index 0000000000000000000000000000000000000000..13d755352282250b830c5f5e9de4d24b58602d71
--- /dev/null
+++ b/sqlTranslate/.idea/workspace.xml
@@ -0,0 +1,559 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {
+ "customColor": "",
+ "associatedIndex": 4
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1723106789329
+
+
+ 1723106789329
+
+
+ 1726151534112
+
+
+
+ 1726151534112
+
+
+ 1726152030692
+
+
+
+ 1726152030692
+
+
+ 1726153009186
+
+
+
+ 1726153009186
+
+
+ 1726153173228
+
+
+
+ 1726153173228
+
+
+ 1726153977485
+
+
+
+ 1726153977485
+
+
+ 1726154243358
+
+
+
+ 1726154243360
+
+
+ 1726154479052
+
+
+
+ 1726154479052
+
+
+ 1726197698087
+
+
+
+ 1726197698087
+
+
+ 1726198053495
+
+
+
+ 1726198053495
+
+
+ 1726209430618
+
+
+
+ 1726209430619
+
+
+ 1726210280295
+
+
+
+ 1726210280296
+
+
+ 1726212919328
+
+
+
+ 1726212919328
+
+
+ 1726214700141
+
+
+
+ 1726214700141
+
+
+ 1726214965146
+
+
+
+ 1726214965146
+
+
+ 1726215246855
+
+
+
+ 1726215246856
+
+
+ 1726215657277
+
+
+
+ 1726215657277
+
+
+ 1726234244501
+
+
+
+ 1726234244501
+
+
+ 1726235338624
+
+
+
+ 1726235338624
+
+
+ 1726235703488
+
+
+
+ 1726235703488
+
+
+ 1726236869086
+
+
+
+ 1726236869087
+
+
+ 1726238974056
+
+
+
+ 1726238974056
+
+
+ 1726241748943
+
+
+
+ 1726241748943
+
+
+ 1726284970450
+
+
+
+ 1726284970451
+
+
+ 1726298762626
+
+
+
+ 1726298762627
+
+
+ 1726315007495
+
+
+
+ 1726315007495
+
+
+ 1726315219011
+
+
+
+ 1726315219011
+
+
+ 1726316179151
+
+
+
+ 1726316179152
+
+
+ 1726326745122
+
+
+
+ 1726326745123
+
+
+ 1726413056810
+
+
+
+ 1726413056811
+
+
+ 1726413069101
+
+
+
+ 1726413069101
+
+
+ 1726471059208
+
+
+
+ 1726471059208
+
+
+ 1726471382852
+
+
+
+ 1726471382852
+
+
+ 1726472321577
+
+
+
+ 1726472321577
+
+
+ 1726474768114
+
+
+
+ 1726474768114
+
+
+ 1726491998608
+
+
+
+ 1726491998609
+
+
+ 1726496640760
+
+
+
+ 1726496640760
+
+
+ 1726554513045
+
+
+
+ 1726554513046
+
+
+ 1726555125392
+
+
+
+ 1726555125392
+
+
+ 1726561299659
+
+
+
+ 1726561299659
+
+
+ 1726583392370
+
+
+
+ 1726583392370
+
+
+ 1726587379509
+
+
+
+ 1726587379509
+
+
+ 1726588739459
+
+
+
+ 1726588739459
+
+
+ 1726590115566
+
+
+
+ 1726590115566
+
+
+ 1726591998690
+
+
+
+ 1726591998690
+
+
+ 1726628514219
+
+
+
+ 1726628514220
+
+
+ 1726629251761
+
+
+
+ 1726629251761
+
+
+ 1726629819863
+
+
+
+ 1726629819863
+
+
+ 1726631451338
+
+
+
+ 1726631451338
+
+
+ 1726633703475
+
+
+
+ 1726633703475
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sqlTranslate/pom.xml b/sqlTranslate/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a05364c07e844681162288674d20a4ff4953f2f4
--- /dev/null
+++ b/sqlTranslate/pom.xml
@@ -0,0 +1,53 @@
+
+
+
+ 4.0.0
+
+ org.example
+ sqlTranslate
+ 1.0-SNAPSHOT
+ jar
+
+ sqlTranslate
+ http://www.example.com
+
+
+ UTF-8
+ 1.8
+ 1.8
+
+
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ 5.7.1
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-params
+ 5.7.1
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.0.0-M5
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 9
+ 9
+
+
+
+
+
diff --git a/sqlTranslate/src/main/java/Main.java b/sqlTranslate/src/main/java/Main.java
new file mode 100644
index 0000000000000000000000000000000000000000..028d1bc29a67aebebf26fafeb82b4a7c58d80ad5
--- /dev/null
+++ b/sqlTranslate/src/main/java/Main.java
@@ -0,0 +1,19 @@
+import generator.OpenGaussGenerator;
+import lexer.OracleLexer;
+import parser.ast.ASTNode;
+import parser.OracleParser;
+
+
+public class Main {
+ public static void main(String[] args) {
+ String sql = "SELECT e.first_name, d.department_name FROM employees e JOIN departments d Using e.department_id = d.department_id;";
+ OracleLexer lexer = new OracleLexer(sql);
+ lexer.printTokens();
+ OracleParser parser = new OracleParser(lexer);
+ ASTNode root = parser.parse();
+ System.out.println(root.toQueryString());
+ System.out.println(root.getASTString());
+ OpenGaussGenerator generator = new OpenGaussGenerator(root);
+ System.out.println(generator.generate());
+ }
+}
diff --git a/sqlTranslate/src/main/java/config/CommonConfig.java b/sqlTranslate/src/main/java/config/CommonConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..97b7eb5d2f49d07b3a93caca7803ffa03ad67ea8
--- /dev/null
+++ b/sqlTranslate/src/main/java/config/CommonConfig.java
@@ -0,0 +1,25 @@
+package config;
+
+public class CommonConfig {
+ public static final String DEFAULT_SOURCE_DB = "Oracle-19C";
+ public static final String DEFAULT_TARGET_DB = "OpenGauss-3.0.0";
+ private static String sourceDB = DEFAULT_SOURCE_DB;
+ private static String targetDB = DEFAULT_TARGET_DB;
+
+ public static void setSourceDB(String sourceDB) {
+ CommonConfig.sourceDB = sourceDB;
+ }
+
+ public static void setTargetDB(String targetDB) {
+ CommonConfig.targetDB = targetDB;
+ }
+
+ public static String getSourceDB() {
+ return sourceDB;
+ }
+
+ public static String getTargetDB() {
+ return targetDB;
+ }
+
+}
diff --git a/sqlTranslate/src/main/java/document/Alter table in Oracle b/sqlTranslate/src/main/java/document/Alter table in Oracle
new file mode 100644
index 0000000000000000000000000000000000000000..9098a6647d342199b9279144d8d4dc3fc016582e
--- /dev/null
+++ b/sqlTranslate/src/main/java/document/Alter table in Oracle
@@ -0,0 +1,19 @@
+ALTER TABLE table_name action;
+action = ADD column_name data_type [constraint]
+| DROP COLUMN column_name
+| MODIFY column_name data_type
+| 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
+
+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/document/Commit,rollback,execute in Oracle b/sqlTranslate/src/main/java/document/Commit,rollback,execute in Oracle
new file mode 100644
index 0000000000000000000000000000000000000000..c96ea33fde3d0273bfc172eb0656dbf1dfd58884
--- /dev/null
+++ b/sqlTranslate/src/main/java/document/Commit,rollback,execute in Oracle
@@ -0,0 +1,14 @@
+BEGIN
+ -- some ddl sql
+ INSERT INTO my_table (id, value) VALUES (1, 'test');
+
+ -- Commit
+ COMMIT;
+
+ -- Failed
+ ROLLBACK;
+END;
+/
+
+EXECUTE: EXEC my_procedure('some value');
+ | EXECUTE IMMEDIATE 'INSERT INTO my_table (id, name) VALUES (1, ''John'')';
\ No newline at end of file
diff --git a/sqlTranslate/src/main/java/document/CreateTable in Oracle b/sqlTranslate/src/main/java/document/CreateTable in Oracle
new file mode 100644
index 0000000000000000000000000000000000000000..86114b175b9bbb5595eb9a38c31657b2ddbf395d
--- /dev/null
+++ b/sqlTranslate/src/main/java/document/CreateTable in Oracle
@@ -0,0 +1,21 @@
+CREATE TEMPORARY? TABLE _table ( (_column _type column_constraint), (_column _type column_constraint)* table_constraint?)
+table_constraint: PRIMARY KEY
+ # Example:CONSTRAINT pk_example PRIMARY KEY (column1, column2)
+ | UNIQUE
+ # Example:CONSTRAINT uk_example UNIQUE (column1)
+ | FOREIGN KEY
+ # Example:CONSTRAINT fk_example FOREIGN KEY (column1) REFERENCES other_table(column2)
+ | CHECK
+ # Example:CONSTRAINT chk_example CHECK (column1 > 0)
+column_constraint: NOT NULL
+ # Example:column_name VARCHAR2(50) NOT NULL
+ | PRIMARY KEY
+ # Example:column_name NUMBER(10) PRIMARY KEY
+ | UNIQUE
+ # Example:column_name VARCHAR2(50) UNIQUE
+ | CHECK
+ # Example:column_name NUMBER CHECK (column_name > 0)
+ | FOREIGN KEY
+ # Example:column_name NUMBER(10) REFERENCES other_table(other_column)
+ | DEFAULT
+ # Example:column_name VARCHAR2(50) DEFAULT 'default_value'
\ No newline at end of file
diff --git a/sqlTranslate/src/main/java/document/DataType in Oracle b/sqlTranslate/src/main/java/document/DataType in Oracle
new file mode 100644
index 0000000000000000000000000000000000000000..787d70a8a67838162fc2d0e18ab8877ef50ab4a2
--- /dev/null
+++ b/sqlTranslate/src/main/java/document/DataType in Oracle
@@ -0,0 +1,105 @@
+数值类型
+ NUMBER
+ 用于存储整数或浮点数。
+ 可以指定精度(总位数)和小数位数。
+ 示例:NUMBER(10, 2) 表示一个最多有 10 位数字的数,其中 2 位是小数位。
+ INTEGER
+ 用于存储整数。
+ 等价于 NUMBER 但默认没有精度限制。
+ 示例:INTEGER
+ SMALLINT
+ 用于存储较小的整数。
+ 等价于 INTEGER 但默认范围更小。
+ 示例:SMALLINT
+ BINARY_INTEGER
+ 用于存储整数。
+ 通常用于内部使用,而不是直接在表定义中使用。
+ 示例:BINARY_INTEGER
+ DECIMAL
+ 等价于 NUMBER。
+ 示例:DECIMAL(10, 2)
+ REAL
+ 用于存储单精度浮点数。
+ 示例:REAL
+ FLOAT
+ 用于存储双精度浮点数。
+ 可以指定精度。
+ 示例:FLOAT(128)
+ DOUBLE PRECISION
+ 用于存储双精度浮点数。
+ 示例:DOUBLE PRECISION
+
+字符串类型
+ CHAR
+ 用于存储固定长度的字符串。
+ 示例:CHAR(20)
+ VARCHAR2
+ 用于存储可变长度的字符串。
+ 最大长度为 4000 字节(在早期版本中)或 32767 字节(从 Oracle 12c 开始)。
+ 示例:VARCHAR2(255)
+ NCHAR
+ 用于存储固定长度的 Unicode 字符串。
+ 示例:NCHAR(20)
+ NVARCHAR2
+ 用于存储可变长度的 Unicode 字符串。
+ 示例:NVARCHAR2(255)
+ CLOB
+ 用于存储大文本块。
+ 示例:CLOB
+ NCLOB
+ 用于存储大 Unicode 文本块。
+ 示例:NCLOB
+
+日期/时间类型
+ DATE
+ 用于存储日期和时间信息。
+ 包括年、月、日、小时、分钟和秒。
+ 示例:DATE
+ TIMESTAMP
+ 用于存储日期和时间信息。
+ 可以包含毫秒。
+ 示例:TIMESTAMP
+ TIMESTAMP WITH TIME ZONE
+ 用于存储日期和时间信息,包括时区。
+ 示例:TIMESTAMP WITH TIME ZONE
+ TIMESTAMP WITH LOCAL TIME ZONE
+ 用于存储日期和时间信息,按照本地时区显示。
+ 示例:TIMESTAMP WITH LOCAL TIME ZONE
+
+二进制类型
+ BLOB
+ 用于存储大二进制对象,如图像或文件。
+ 示例:BLOB
+ RAW
+ 用于存储固定长度的二进制数据。
+ 示例:RAW(2000)
+ LONG RAW
+ 用于存储长二进制数据。
+ 最大长度为 2GB。
+ 示例:LONG RAW
+
+特殊类型
+ BOOLEAN
+ 用于存储布尔值 TRUE, FALSE 或 NULL。
+ 从 Oracle 12c 开始支持。
+ INTERVAL YEAR TO MONTH
+ 用于存储年份到月份的时间间隔。
+ 示例:INTERVAL YEAR TO MONTH
+ INTERVAL DAY TO SECOND
+ 用于存储天到秒的时间间隔。
+ 示例:INTERVAL DAY TO SECOND
+ ROWID
+ 用于存储行标识符。
+ 示例:ROWID
+ UROWID
+ 用于存储统一行标识符。
+ 示例:UROWID
+ REF
+ 用于存储对另一个表的引用。
+ 示例:REF
+ OBJECT
+ 用于存储用户定义的对象类型。
+ 示例:OBJECT (attr1 NUMBER, attr2 VARCHAR2(50))
+ REF CURSOR
+ 用于存储游标引用。
+ 示例:REF CURSOR
\ No newline at end of file
diff --git a/sqlTranslate/src/main/java/document/Delete statement in Oracle b/sqlTranslate/src/main/java/document/Delete statement in Oracle
new file mode 100644
index 0000000000000000000000000000000000000000..b02b4bdefcacd6a111e9a4a1481fbc84c5b50283
--- /dev/null
+++ b/sqlTranslate/src/main/java/document/Delete statement in Oracle
@@ -0,0 +1 @@
+DELETE FROM deleteObject WHERE condition ;
\ No newline at end of file
diff --git a/sqlTranslate/src/main/java/document/DropTable in Oracle b/sqlTranslate/src/main/java/document/DropTable in Oracle
new file mode 100644
index 0000000000000000000000000000000000000000..a78f4257a1f57149683b824a7db455eeaf6bc646
--- /dev/null
+++ b/sqlTranslate/src/main/java/document/DropTable in Oracle
@@ -0,0 +1 @@
+DROP TABLE _table (CASCADE CONSTRAINTS)?
\ No newline at end of file
diff --git a/sqlTranslate/src/main/java/document/Exception in Oracle b/sqlTranslate/src/main/java/document/Exception in Oracle
new file mode 100644
index 0000000000000000000000000000000000000000..769660b6ff213539693897c2f691c17498302a58
--- /dev/null
+++ b/sqlTranslate/src/main/java/document/Exception in Oracle
@@ -0,0 +1,18 @@
+DECLARE
+ -- declaration of variable
+BEGIN
+ -- PL/SQL
+EXCEPTION
+ -- custom exception
+ WHEN e_custom_exception THEN
+ DBMS_OUTPUT.PUT_LINE('Caught an exception: Custom exception raised');
+ -- divide by zero
+ WHEN ZERO_DIVIDE THEN
+ DBMS_OUTPUT.PUT_LINE('Caught an exception: Division by zero');
+ -- invalid number
+ WHEN INVALID_NUMBER THEN
+ DBMS_OUTPUT.PUT_LINE('Caught an exception: Invalid number');
+ -- other exceptions
+ WHEN OTHERS THEN
+ DBMS_OUTPUT.PUT_LINE('Caught an exception: ' || SQLERRM);
+END;
\ No newline at end of file
diff --git a/sqlTranslate/src/main/java/document/Function in Oracle b/sqlTranslate/src/main/java/document/Function in Oracle
new file mode 100644
index 0000000000000000000000000000000000000000..259cf54dfe2ee78209f14407e65198dbce2fd014
--- /dev/null
+++ b/sqlTranslate/src/main/java/document/Function in Oracle
@@ -0,0 +1,20 @@
+CREATE OR REPLACE FUNCTION function_name (
+ parameter1 [IN | OUT] datatype1 ,
+ parameter2 [IN | OUT] datatype2 ,
+ ...
+) RETURN return_datatype IS
+[DECLARE]
+-- declare part
+BEGIN
+ -- function body
+ RETURN result;
+END;
+/
+
+Example: CREATE OR REPLACE FUNCTION string_length (
+ input_string VARCHAR2
+ ) RETURN NUMBER IS
+ BEGIN
+ RETURN LENGTH(input_string);
+ END;
+ /
\ No newline at end of file
diff --git a/sqlTranslate/src/main/java/document/IF ELSEIF ELSE in Oracle b/sqlTranslate/src/main/java/document/IF ELSEIF ELSE in Oracle
new file mode 100644
index 0000000000000000000000000000000000000000..89dcc9841884559044a17a4eae796f36b588f468
--- /dev/null
+++ b/sqlTranslate/src/main/java/document/IF ELSEIF ELSE in Oracle
@@ -0,0 +1,14 @@
+IF condition1 THEN ...
+(ELSIF condition2 THEN ...)*
+[ELSE...]
+END IF;
+
+Example: IF v_salary >= 100000 THEN
+ v_bonus := v_salary * 0.1;
+ ELSIF v_salary >= 50000 THEN
+ v_bonus := v_salary * 0.08;
+ ELSIF v_salary >= 30000 THEN
+ v_bonus := v_salary * 0.05;
+ ELSE
+ v_bonus := v_salary * 0.03;
+ END IF;
\ No newline at end of file
diff --git a/sqlTranslate/src/main/java/document/Insert statement in Oracle b/sqlTranslate/src/main/java/document/Insert statement in Oracle
new file mode 100644
index 0000000000000000000000000000000000000000..d45fb273fbd88b65417aad254db1d48aa7ca6611
--- /dev/null
+++ b/sqlTranslate/src/main/java/document/Insert statement in Oracle
@@ -0,0 +1,2 @@
+INSERT INTO employees (first_name, last_name, email) VALUES ('Jane', 'Smith', 'janesm@example.com');
+INSERT INTO employees VALUES ('Jane', 'Smith', 'janesm@example.com');
\ No newline at end of file
diff --git a/sqlTranslate/src/main/java/document/Loop in PLSQL b/sqlTranslate/src/main/java/document/Loop in PLSQL
new file mode 100644
index 0000000000000000000000000000000000000000..e0d4249357daf36bbb0668aabefc0c1fb0cd0b65
--- /dev/null
+++ b/sqlTranslate/src/main/java/document/Loop in PLSQL
@@ -0,0 +1,40 @@
+LOOP
+ -- 循环体
+ EXIT WHEN condition;
+END LOOP;
+
+Example:
+ DECLARE
+ v_counter NUMBER := 1;
+ BEGIN
+ LOOP
+ DBMS_OUTPUT.PUT_LINE(v_counter);
+ v_counter := v_counter + 1;
+ EXIT WHEN v_counter > 10;
+ END LOOP;
+ END;
+
+WHILE condition LOOP
+ -- 循环体
+END LOOP;
+
+Example:
+ DECLARE
+ v_counter NUMBER := 1;
+ BEGIN
+ WHILE v_counter <= 10 LOOP
+ DBMS_OUTPUT.PUT_LINE(v_counter);
+ v_counter := v_counter + 1;
+ END LOOP;
+ END;
+
+FOR counter IN start..stop LOOP
+ -- 循环体
+END LOOP;
+
+Example:
+ BEGIN
+ FOR i IN 1..10 LOOP
+ DBMS_OUTPUT.PUT_LINE(i);
+ END LOOP;
+ END;
\ No newline at end of file
diff --git a/sqlTranslate/src/main/java/document/PL in Oracle b/sqlTranslate/src/main/java/document/PL in Oracle
new file mode 100644
index 0000000000000000000000000000000000000000..a30a64d1ce55237ffef88a31d08b3532fd98c710
--- /dev/null
+++ b/sqlTranslate/src/main/java/document/PL in Oracle
@@ -0,0 +1,17 @@
+DECLARE
+ v_var1 v_type;
+ ...
+BEGIN
+ -- PL/SQL
+END;
+
+Example: DECLARE
+ v_name Varchar2(20);
+ v_salary employees.salary%TYPE;
+ BEGIN
+ SELECT name, salary INTO v_name, v_salary FROM employees WHERE employee_id = 100;
+ DBMS_OUTPUT.PUT_LINE('Name: ' || v_name || ', Salary: ' || v_salary);
+ EXCEPTION
+ WHEN NO_DATA_FOUND THEN
+ DBMS_OUTPUT.PUT_LINE('No data found.');
+ END;
\ No newline at end of file
diff --git a/sqlTranslate/src/main/java/document/Procedure in Oracle b/sqlTranslate/src/main/java/document/Procedure in Oracle
new file mode 100644
index 0000000000000000000000000000000000000000..d7a0a3d83e57df717c78b3c109268764cbecb18b
--- /dev/null
+++ b/sqlTranslate/src/main/java/document/Procedure in Oracle
@@ -0,0 +1,37 @@
+CREATE [OR REPLACE] PROCEDURE procedure_name ([parameter_list])
+IS [LOCAL DECLARATIONS]
+[DECLARE]
+-- declare part
+BEGIN
+ -- PL/SQL statements
+[EXCEPTION]
+ -- exception handling
+END [procedure_name]; -- [procedure_name] should be removed in OpenGauss
+
+Example: CREATE OR REPLACE PROCEDURE update_salary (
+ employee_id IN NUMBER,
+ new_salary IN OUT NUMBER
+ ) IS
+ v_employee employees%ROWTYPE;
+ BEGIN
+ SELECT * INTO v_employee FROM employees WHERE employee_id = employee_id;
+
+ IF new_salary < 3000 THEN
+ new_salary := new_salary * 1.1;
+ ELSE
+ new_salary := new_salary * 1.05;
+ END IF;
+
+ UPDATE employees SET salary = new_salary WHERE employee_id = employee_id;
+ COMMIT;
+
+ DBMS_OUTPUT.PUT_LINE('Updated Salary: ' || new_salary);
+ EXCEPTION
+ WHEN NO_DATA_FOUND THEN
+ DBMS_OUTPUT.PUT_LINE('Employee not found.');
+ WHEN TOO_MANY_ROWS THEN
+ DBMS_OUTPUT.PUT_LINE('Multiple employees found.');
+ WHEN OTHERS THEN
+ DBMS_OUTPUT.PUT_LINE('An error occurred: ' || SQLERRM);
+ END update_salary;
+ /
\ No newline at end of file
diff --git a/sqlTranslate/src/main/java/document/Select statement in Oracle b/sqlTranslate/src/main/java/document/Select statement in Oracle
new file mode 100644
index 0000000000000000000000000000000000000000..446722398bb5cb41aacde18b6b82802c385ab8c4
--- /dev/null
+++ b/sqlTranslate/src/main/java/document/Select statement in Oracle
@@ -0,0 +1,20 @@
+SELECT DISTINCT? select_obj FROM select_tab where_clause? select_option? union_clause? ;
+select_obj = * | column* | function
+select_tab = table join_clause?
+select_option = GROUP BY | ORDER BY | HAVING
+function = COUNT() | SUM() | AVG() | MAX() | MIN()
+
+example:
+ SELECT * FROM employees Union SELECT employee_id, first_name, last_name FROM employees;
+ SELECT * FROM employees WHERE department_id = 10;
+ SELECT * FROM employees ORDER BY hire_date DESC;
+ SELECT COUNT(*), AVG(salary) FROM employees;
+ SELECT department_id, COUNT(*) FROM employees GROUP BY department_id;
+ SELECT e.first_name, d.department_name FROM employees e JOIN departments d ON e.department_id = d.department_id;
+ SELECT
+ column1,
+ CASE WHEN column2 > 0 THEN 'Positive' ELSE 'Non-positive' END as status,
+ SUBSTR(column3, 1, 5) as substring_column3
+ FROM table_name;
+ SELECT column1, COUNT(column2) FROM table_name GROUP BY column1 HAVING COUNT(column2) > 10;
+
diff --git a/sqlTranslate/src/main/java/document/Todolist b/sqlTranslate/src/main/java/document/Todolist
new file mode 100644
index 0000000000000000000000000000000000000000..ec2f584ca77b59abaa1d9de1d5ac9e1406b283d6
--- /dev/null
+++ b/sqlTranslate/src/main/java/document/Todolist
@@ -0,0 +1,27 @@
+Operation
+ select.. from.. where 1
+ join 1
+ group by 1
+ order by 1
+ union 1
+ insert into 1
+ update... set 1
+ delete 1
+ if... elsif... else... end if 1
+ case... when... then 1
+ loop... end loop 1
+ while... loop... end loop 1
+ for ... in () loop end loop 1
+ continue、exit 1
+ return 1
+ exception 1
+ commit、rollback、execute 1
+ alter table 1
+ create table 1
+ drop table 1
+Object
+ table 1
+ view 1
+ function 1
+ procedure 1
+ trigger 1
\ No newline at end of file
diff --git a/sqlTranslate/src/main/java/document/Trigger in Oracle b/sqlTranslate/src/main/java/document/Trigger in Oracle
new file mode 100644
index 0000000000000000000000000000000000000000..8139b684afc77252bb7474cf1c636b97e62f7734
--- /dev/null
+++ b/sqlTranslate/src/main/java/document/Trigger in Oracle
@@ -0,0 +1,80 @@
+CREATE OR REPLACE TRIGGER trigger_name
+BEFORE | AFTER
+{ INSERT | UPDATE | DELETE }
+ON table_name
+[REFERENCING NEW AS new OLD AS old] -- OpenGauss does not support this
+FOR EACH ROW
+[WHEN (condition)]
+[DECLARE]
+-- declare part
+BEGIN
+ -- trigger body
+END;
+
+Example: CREATE OR REPLACE TRIGGER log_insert_trigger
+ AFTER INSERT ON employees
+ FOR EACH ROW
+ DECLARE
+ l_action VARCHAR2(10) := 'INSERT';
+ BEGIN
+ INSERT INTO audit_log (action, employee_id) VALUES (l_action, 11);
+ DBMS_OUTPUT.PUT_LINE('Inserted record with ID: ' || 11);
+ EXCEPTION
+ WHEN OTHERS THEN
+ DBMS_OUTPUT.PUT_LINE('An error occurred: ' || SQLERRM);
+ END;
+ /
+
+ CREATE TABLE employees (
+ id NUMBER PRIMARY KEY,
+ name VARCHAR2(100) NOT NULL,
+ position VARCHAR2(50),
+ hire_date DATE
+ );
+
+ CREATE TABLE audit_log (
+ action VARCHAR2(10) NOT NULL,
+ employee_id NUMBER,
+ timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+ );
+
+ INSERT INTO employees (id, name, position, hire_date) VALUES (1, 'John Doe', 'Developer', SYSDATE);
+
+ select * from audit_log;
+
+Equal SQL on OpenGauss:
+ CREATE OR REPLACE FUNCTION log_insert_trigger()
+ RETURNS TRIGGER AS $$
+ DECLARE
+ l_action VARCHAR(10) := 'INSERT';
+ BEGIN
+ INSERT INTO audit_log (action, employee_id) VALUES (l_action, 11);
+ RETURN NEW;
+ EXCEPTION
+ WHEN OTHERS THEN
+ RAISE NOTICE 'An error occurred: %', SQLERRM;
+ END;
+ $$ LANGUAGE plpgsql;
+
+ CREATE TRIGGER log_insert_trigger
+ AFTER INSERT ON employees
+ FOR EACH ROW
+ EXECUTE PROCEDURE log_insert_trigger();
+
+ CREATE TABLE employees (
+ id NUMBER PRIMARY KEY,
+ name VARCHAR(100) NOT NULL,
+ position VARCHAR(50),
+ hire_date DATE
+ );
+
+ CREATE TABLE audit_log (
+ action VARCHAR(10) NOT NULL,
+ employee_id NUMERIC,
+ timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+ );
+
+ INSERT INTO employees (id, name, position, hire_date) VALUES (1, 'John Doe', 'Developer', SYSDATE);
+
+ select * from audit_log;
+
diff --git a/sqlTranslate/src/main/java/document/Update statement in Oracle b/sqlTranslate/src/main/java/document/Update statement in Oracle
new file mode 100644
index 0000000000000000000000000000000000000000..fa215a03a236e6ab8f088142a1febf75bce24e02
--- /dev/null
+++ b/sqlTranslate/src/main/java/document/Update statement in Oracle
@@ -0,0 +1,4 @@
+UPDATE table_name SET column1 = value1, column2 = value2, ... WHERE condition;
+
+Example: UPDATE employees e JOIN departments d using e.department_id = d.department_id
+ SET e.salary = e.salary * 1.10, d.budget = d.budget * 1.10 WHERE d.department_name = 'Sales';
\ No newline at end of file
diff --git a/sqlTranslate/src/main/java/document/View in Oracle b/sqlTranslate/src/main/java/document/View in Oracle
new file mode 100644
index 0000000000000000000000000000000000000000..332a80e7c6281f2912f1b050e7f1b474243482aa
--- /dev/null
+++ b/sqlTranslate/src/main/java/document/View in Oracle
@@ -0,0 +1,7 @@
+CREATE [OR REPLACE] VIEW view_name [(column_name [, column_name]...)] AS SELECT_statement;
+
+Example:
+ CREATE OR REPLACE VIEW employee_details AS SELECT first_name, last_name, salary FROM employees;
+ | CREATE OR REPLACE VIEW emp_info (full_name, pay) AS SELECT first_name || ' ' || last_name AS full_name, salary AS pay FROM employees;
+ | CREATE OR REPLACE VIEW emp_dept_info AS SELECT e.first_name, e.last_name, d.department_name FROM employees e JOIN departments d ON e.department_id = d.department_id;
+ | CREATE OR REPLACE VIEW high_salary_employees AS SELECT first_name, last_name, salary FROM employees WHERE salary > 50000;
\ No newline at end of file
diff --git a/sqlTranslate/src/main/java/exception/GenerateFailedException.java b/sqlTranslate/src/main/java/exception/GenerateFailedException.java
new file mode 100644
index 0000000000000000000000000000000000000000..49d54c1b50c95fc6562cdbc8b612cc77034ea102
--- /dev/null
+++ b/sqlTranslate/src/main/java/exception/GenerateFailedException.java
@@ -0,0 +1,8 @@
+package exception;
+
+public class GenerateFailedException extends RuntimeException{
+ public GenerateFailedException(String message)
+ {
+ super(message);
+ }
+}
diff --git a/sqlTranslate/src/main/java/exception/ParseFailedException.java b/sqlTranslate/src/main/java/exception/ParseFailedException.java
new file mode 100644
index 0000000000000000000000000000000000000000..547e9a2959d01c2f876870e83b9f4feeb9a0570d
--- /dev/null
+++ b/sqlTranslate/src/main/java/exception/ParseFailedException.java
@@ -0,0 +1,8 @@
+package exception;
+
+public class ParseFailedException extends RuntimeException{
+ public ParseFailedException(String message)
+ {
+ super(message);
+ }
+}
diff --git a/sqlTranslate/src/main/java/generator/OpenGaussGenerator.java b/sqlTranslate/src/main/java/generator/OpenGaussGenerator.java
new file mode 100644
index 0000000000000000000000000000000000000000..a43bc50f9c35dd1c69b7a5ebd0c9de4af2f67749
--- /dev/null
+++ b/sqlTranslate/src/main/java/generator/OpenGaussGenerator.java
@@ -0,0 +1,753 @@
+package generator;
+
+import config.CommonConfig;
+import interfaces.DataType;
+import lexer.OracleLexer;
+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.casewhen.CaseConditionNode;
+import parser.ast.createtable.ColumnNode;
+import parser.ast.createtable.CreateTabNode;
+import exception.GenerateFailedException;
+import parser.ast.delete.DeleteNode;
+import parser.ast.drop.DropNode;
+import parser.ast.drop.DropOptionNode;
+import parser.ast.exception.ExceptionActionNode;
+import parser.ast.exception.ExceptionNode;
+import parser.ast.function.*;
+import parser.ast.ifelsif.IFConditionNode;
+import parser.ast.insert.InsertNode;
+import parser.ast.join.JoinConditionNode;
+import parser.ast.join.JoinSourceTabNode;
+import parser.ast.loop.ForNode;
+import parser.ast.loop.LoopBodyNode;
+import parser.ast.loop.LoopNode;
+import parser.ast.loop.WhileNode;
+import parser.ast.pl.PLBodyNode;
+import parser.ast.pl.PLDeclareNode;
+import parser.ast.pl.PLEndNode;
+import parser.ast.pl.PLNode;
+import parser.ast.procedure.*;
+import parser.ast.select.SelectNode;
+import parser.ast.trigger.*;
+import parser.ast.update.UpdateNode;
+import parser.ast.view.ViewCreateNode;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class OpenGaussGenerator {
+ private ASTNode node;
+ public OpenGaussGenerator(ASTNode node) {
+ this.node = node;
+ }
+
+ public void setNode(ASTNode node) {
+ this.node = node;
+ }
+
+ public String generate() {
+ if (node instanceof CreateTabNode) {
+ return GenCreatTableSQL(node);
+ }
+ else if (node instanceof InsertNode) {
+ return GenInsertSQL(node);
+ }
+ else if (node instanceof DropNode) {
+ return GenDropTableSQL(node);
+ }
+ else if (node instanceof SelectNode) {
+ return GenSelectSQL(node);
+ }
+ else if (node instanceof JoinSourceTabNode) {
+ return GenJoinSQL(node);
+ }
+ else if (node instanceof UpdateNode) {
+ return GenUpdateSQL(node);
+ }
+ else if (node instanceof DeleteNode) {
+ return GenDeleteSQL(node);
+ }
+ else if (node instanceof AlterNode) {
+ return GenAlterSQL(node);
+ }
+ else if (node instanceof ViewCreateNode) {
+ return GenCreateViewSQL(node);
+ }
+ else if (node instanceof LoopNode || node instanceof WhileNode || node instanceof ForNode) {
+ return GenLoopSQL(node);
+ }
+ else if (node instanceof ExceptionNode) {
+ return GenExceptionSQL(node);
+ }
+ else if (node instanceof ProcedureNode) {
+ return GenProcedureSQL(node);
+ }
+ else if (node instanceof FunctionNode) {
+ return GenFunctionSQL(node);
+ }
+ else if (node instanceof TriggerNode) {
+ return GenTriggerSQL(node);
+ }
+ else if (node instanceof PLNode) {
+ return GenPLSQL(node);
+ }
+ else if (node instanceof IFConditionNode) {
+ return GenIfElseSQL(node);
+ }
+ else if (node instanceof CaseConditionNode) {
+ return GenCaseWhenSQL(node);
+ }
+ else {
+ try {
+ throw new GenerateFailedException("Root node:" + node.getClass() + "(Unsupported node type!)");
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ return "";
+ }
+ }
+
+ private String GenCreatTableSQL(ASTNode node) {
+ // type convert
+ visitCrt(node);
+// System.out.println(node.getASTString());
+ return node.toQueryString();
+ }
+
+ private String GenInsertSQL(ASTNode node) {
+ // Insert statements do not need to be converted for the time being
+ return node.toQueryString();
+ }
+
+ private String GenDropTableSQL(ASTNode node) {
+ visitDrop(node);
+ return node.toQueryString();
+ }
+
+ private String GenSelectSQL(ASTNode node) {
+ visitSelect(node);
+// System.out.println(node.getASTString());
+ return node.toQueryString();
+ }
+
+ private String GenJoinSQL(ASTNode node) {
+ visitJoin(node);
+ return node.toQueryString();
+ }
+
+ private String GenCaseWhenSQL(ASTNode node) {
+ visitCaseWhen(node);
+ return node.toQueryString();
+ }
+
+ private String GenUpdateSQL(ASTNode node) {
+ visitUpdate(node);
+// System.out.println(node.getASTString());
+ return node.toQueryString();
+ }
+
+ private String GenDeleteSQL(ASTNode node) {
+ return node.toQueryString();
+ }
+
+ private String GenAlterSQL(ASTNode node) {
+ visitAlter(node);
+// System.out.println(node.getASTString());
+ return node.toQueryString();
+ }
+
+ private String GenCreateViewSQL(ASTNode node) {
+ visitCreateView(node);
+ return node.toQueryString();
+ }
+
+ private String GenLoopSQL(ASTNode node) {
+ visitLoop(node);
+ return node.toQueryString();
+ }
+
+ private String GenExceptionSQL(ASTNode node) {
+ visitException(node);
+ return node.toQueryString();
+ }
+
+ private String GenProcedureSQL(ASTNode node) {
+ visitPL(node);
+// System.out.println(node.getASTString());
+ return node.toQueryString();
+ }
+
+ private String GenFunctionSQL(ASTNode node) {
+ visitFunc(node);
+ return node.toQueryString();
+ }
+
+ private String GenTriggerSQL(ASTNode node) {
+ visitTrigger(node);
+// System.out.println(node.getASTString());
+ return node.toQueryString();
+ }
+
+ private String GenPLSQL(ASTNode node) {
+ visitPLSQL(node);
+// System.out.println(node.getASTString());
+ return node.toQueryString();
+ }
+
+ private String GenIfElseSQL(ASTNode node) {
+ visitIfElse(node);
+ return node.toQueryString();
+ }
+
+ private void visitCrt(ASTNode node) {
+ if (CommonConfig.getSourceDB().equalsIgnoreCase("ORACLE-19C")
+ && CommonConfig.getTargetDB().equalsIgnoreCase("OPENGAUSS-3.0.0")) {
+ if (node instanceof ColumnNode) {
+ DataTypeConvert((ColumnNode) node);
+ }
+ }
+ for (ASTNode child : node.getChildren()) {
+ visitCrt(child);
+ }
+ }
+
+ private void visitDrop(ASTNode node) {
+ if (CommonConfig.getSourceDB().equalsIgnoreCase("ORACLE-19C")
+ && CommonConfig.getTargetDB().equalsIgnoreCase("OPENGAUSS-3.0.0")) {
+ if (node instanceof DropOptionNode) {
+ CommonConvert(node);
+ }
+ }
+ for (ASTNode child : node.getChildren()) {
+ visitDrop(child);
+ }
+ }
+
+ private void visitJoin(ASTNode node) {
+ if (CommonConfig.getSourceDB().equalsIgnoreCase("ORACLE-19C")
+ && CommonConfig.getTargetDB().equalsIgnoreCase("OPENGAUSS-3.0.0")) {
+ if (node instanceof JoinConditionNode) {
+ CommonConvert(node);
+ }
+ }
+ for (ASTNode child : node.getChildren()) {
+ visitJoin(child);
+ }
+ }
+
+ private void visitCaseWhen(ASTNode node) {
+
+ for (ASTNode child : node.getChildren()) {
+ visitCaseWhen(child);
+ }
+ }
+
+ private void visitLoop(ASTNode node) {
+ if (CommonConfig.getSourceDB().equalsIgnoreCase("ORACLE-19C")
+ && CommonConfig.getTargetDB().equalsIgnoreCase("OPENGAUSS-3.0.0")) {
+ if (node instanceof LoopBodyNode) {
+ CommonConvert(node);
+ }
+ }
+ for (ASTNode child : node.getChildren()) {
+ visitLoop(child);
+ }
+ }
+
+ private void visitIfElse(ASTNode node) {
+
+ for (ASTNode child : node.getChildren()) {
+ visitIfElse(child);
+ }
+ }
+
+ private void visitException(ASTNode node) {
+ if (CommonConfig.getSourceDB().equalsIgnoreCase("ORACLE-19C")
+ && CommonConfig.getTargetDB().equalsIgnoreCase("OPENGAUSS-3.0.0")) {
+ if (node instanceof ExceptionActionNode) {
+ CommonConvert(node);
+ }
+ }
+ for (ASTNode child : node.getChildren()) {
+ visitException(child);
+ }
+ }
+
+ private void visitSelect(ASTNode node) {
+ if (CommonConfig.getSourceDB().equalsIgnoreCase("ORACLE-19C")
+ && CommonConfig.getTargetDB().equalsIgnoreCase("OPENGAUSS-3.0.0")) {
+ if (node instanceof JoinSourceTabNode) {
+ visitJoin(node);
+ }
+ }
+ for (ASTNode child : node.getChildren()) {
+ visitSelect(child);
+ }
+ }
+
+ private void visitUpdate(ASTNode node) {
+ if (CommonConfig.getSourceDB().equalsIgnoreCase("ORACLE-19C")
+ && CommonConfig.getTargetDB().equalsIgnoreCase("OPENGAUSS-3.0.0")) {
+ if (node instanceof JoinSourceTabNode) {
+ visitJoin(node);
+ }
+ }
+ for (ASTNode child : node.getChildren()) {
+ visitUpdate(child);
+ }
+ }
+
+ private void visitAlter(ASTNode node) {
+ if (CommonConfig.getSourceDB().equalsIgnoreCase("ORACLE-19C")
+ && CommonConfig.getTargetDB().equalsIgnoreCase("OPENGAUSS-3.0.0")) {
+ if (node instanceof AlterAddColumnNode) {
+ DataTypeConvert((AlterAddColumnNode) node);
+ }
+ else if (node instanceof AlterModifyColumnNode) {
+ DataTypeConvert((AlterModifyColumnNode) node);
+ }
+ }
+ for (ASTNode child : node.getChildren()) {
+ visitAlter(child);
+ }
+ }
+
+ private void visitCreateView(ASTNode node) {
+ if (CommonConfig.getSourceDB().equalsIgnoreCase("ORACLE-19C")
+ && CommonConfig.getTargetDB().equalsIgnoreCase("OPENGAUSS-3.0.0")) {
+ if (node instanceof SelectNode) {
+ visitSelect(node);
+ }
+ }
+ for (ASTNode child : node.getChildren()) {
+ visitCreateView(child);
+ }
+ }
+
+ private void visitPL(ASTNode node) {
+ if (CommonConfig.getSourceDB().equalsIgnoreCase("ORACLE-19C")
+ && CommonConfig.getTargetDB().equalsIgnoreCase("OPENGAUSS-3.0.0")) {
+ if (node instanceof ProcedureRetDefNode) {
+ DataTypeConvert((ProcedureRetDefNode) node);
+ CommonConvert(node);
+ }
+ else if (node instanceof ProcedureDeclareContentNode) {
+ DataTypeConvert((ProcedureDeclareContentNode) node);
+ }
+ else if (node instanceof ProcedureColumnNode) {
+ DataTypeConvert((ProcedureColumnNode) node);
+ }
+ else if (node instanceof ProcedureEndNode) {
+ CommonConvert(node);
+ }
+ else if (node instanceof ExceptionNode) {
+ visitException(node);
+ }
+ else if (node instanceof ProcedurePLStatementNode) {
+ CommonConvert(node);
+ }
+ }
+ for (ASTNode child : node.getChildren()) {
+ visitPL(child);
+ }
+ }
+
+ private void visitFunc(ASTNode node) {
+ if (CommonConfig.getSourceDB().equalsIgnoreCase("ORACLE-19C")
+ && CommonConfig.getTargetDB().equalsIgnoreCase("OPENGAUSS-3.0.0")) {
+ if (node instanceof FunctionRetDefNode) {
+ CommonConvert(node);
+ }
+ else if (node instanceof FunctionDeclareContentNode) {
+ DataTypeConvert((FunctionDeclareContentNode) node);
+ }
+ else if (node instanceof ExceptionNode) {
+ visitException(node);
+ }
+ else if (node instanceof FunctionBodyNode) {
+ CommonConvert(node);
+ }
+ else if (node instanceof FunctionColumnNode) {
+ DataTypeConvert((FunctionColumnNode) node);
+ }
+ else if (node instanceof FunctionEndNode) {
+ CommonConvert(node);
+ }
+ }
+ for (ASTNode child : node.getChildren()) {
+ visitFunc(child);
+ }
+ }
+
+ private void visitTrigger(ASTNode node) {
+ if (CommonConfig.getSourceDB().equalsIgnoreCase("ORACLE-19C")
+ && CommonConfig.getTargetDB().equalsIgnoreCase("OPENGAUSS-3.0.0")) {
+ if (node instanceof TriggerBodyNode) {
+ CommonConvert(node);
+ }
+ else if (node instanceof TriggerConditionNode) {
+ CommonConvert(node);
+ }
+ else if (node instanceof TriggerOptionNode) {
+ CommonConvert(node);
+ }
+ else if (node instanceof TriggerDeclareContentNode) {
+ DataTypeConvert((TriggerDeclareContentNode) node);
+ }
+ }
+ if (!(node.getFirstChild() instanceof TriggerDeclareNode || node.getFirstChild() instanceof TriggerBeginNode)) {
+ for (ASTNode child : node.getChildren()) {
+ visitTrigger(child);
+ }
+ }
+ else {
+ CommonConvert(node);
+ }
+ }
+
+ private void visitPLSQL(ASTNode node) {
+ if (CommonConfig.getSourceDB().equalsIgnoreCase("ORACLE-19C")
+ && CommonConfig.getTargetDB().equalsIgnoreCase("OPENGAUSS-3.0.0")) {
+ if (node instanceof PLNode) {
+ CommonConvert(node);
+ }
+ else if (node instanceof PLDeclareNode) {
+ DataTypeConvert((PLDeclareNode) node);
+ }
+ else if (node instanceof PLEndNode) {
+ CommonConvert(node);
+ }
+ else if (node instanceof PLBodyNode) {
+ CommonConvert(node);
+ }
+ }
+ for (ASTNode child : node.getChildren()) {
+ visitPLSQL(child);
+ }
+ }
+
+ private void CommonConvert(ASTNode node) {
+ if (node.checkExistsByRegex("(?i)DBMS_OUTPUT.PUT_LINE\\(.*?\\)")) {
+ String printObj = "";
+ int index = -1;
+ for (Token token: node.getTokens()) {
+ if (token.getValue().matches("(?i)DBMS_OUTPUT.PUT_LINE\\(.*?\\)")) {
+ index = node.getTokenIndexByRegex("(?i)DBMS_OUTPUT.PUT_LINE\\(.*?\\)");
+ Pattern pattern = Pattern.compile("\\(([^()]*)\\)");
+ Matcher matcher = pattern.matcher(token.getValue());
+ while (matcher.find()) {
+ printObj = matcher.group(1);
+ }
+ break;
+ }
+ }
+ if (!printObj.contains("||")) {
+ List tokens = new ArrayList<>();
+ tokens.add(new Token(Token.TokenType.KEYWORD, "RAISE"));
+ tokens.add(new Token(Token.TokenType.KEYWORD, "NOTICE"));
+ tokens.add(new Token(Token.TokenType.STRING, "'%'"));
+ tokens.add(new Token(Token.TokenType.SYMBOL, ","));
+ tokens.add(new Token(Token.TokenType.IDENTIFIER, printObj));
+ node.moveTokenByIndex(index);
+ node.addTokensByIndex(index, tokens);
+ }
+ else {
+ OracleLexer lexer = new OracleLexer(printObj.replace("||", " "));
+ String output = "";
+ List outputObj = new ArrayList<>();
+ for (Token token: lexer.getTokens()) {
+ if (token.hasType(Token.TokenType.STRING) || token.hasType(Token.TokenType.NUMBER)) {
+ output += token.getValue().replace("'", "");
+ }
+ else if (token.hasType(Token.TokenType.IDENTIFIER) || token.hasType(Token.TokenType.KEYWORD)) {
+ output += "%";
+ outputObj.add(token);
+ }
+ else {
+ continue;
+ }
+ }
+ if (!outputObj.isEmpty()) {
+ List tokens = new ArrayList<>();
+ tokens.add(new Token(Token.TokenType.KEYWORD, "RAISE"));
+ tokens.add(new Token(Token.TokenType.KEYWORD, "NOTICE"));
+ tokens.add(new Token(Token.TokenType.STRING, "'" + output + "'"));
+ for (Token token: outputObj) {
+ tokens.add(new Token(Token.TokenType.SYMBOL, ","));
+ tokens.add(token);
+ }
+ node.moveTokenByIndex(index);
+ node.addTokensByIndex(index, tokens);
+ }
+ else {
+ List tokens = new ArrayList<>();
+ tokens.add(new Token(Token.TokenType.KEYWORD, "RAISE"));
+ tokens.add(new Token(Token.TokenType.KEYWORD, "NOTICE"));
+ tokens.add(new Token(Token.TokenType.STRING, "'%'"));
+ tokens.add(new Token(Token.TokenType.SYMBOL, ","));
+ tokens.add(new Token(Token.TokenType.STRING, "'" + output + "'"));
+ node.moveTokenByIndex(index);
+ node.addTokensByIndex(index, tokens);
+ }
+
+ }
+ }
+ if (node instanceof ProcedureRetDefNode) {
+ List tokens = new ArrayList<>();
+ tokens.add(new Token(Token.TokenType.KEYWORD, "AS"));
+ tokens.add(new Token(Token.TokenType.KEYWORD, "$$"));
+ for (Token token: node.getTokens()) {
+ if (token.hasType(Token.TokenType.KEYWORD) && token.getValue().equalsIgnoreCase("IS")) {
+ tokens.add(new Token(Token.TokenType.KEYWORD, "DECLARE"));
+ }
+ else {
+ tokens.add(token);
+ }
+ }
+ node.setTokens(tokens);
+ }
+ if (node instanceof ProcedureEndNode) {
+ List tokens = new ArrayList<>();
+ tokens.add(new Token(Token.TokenType.KEYWORD, "END"));
+ tokens.add(new Token(Token.TokenType.SYMBOL, ";"));
+ tokens.add(new Token(Token.TokenType.KEYWORD, "$$"));
+ tokens.add(new Token(Token.TokenType.KEYWORD, "LANGUAGE"));
+ tokens.add(new Token(Token.TokenType.KEYWORD, "plpgsql"));
+ tokens.add(new Token(Token.TokenType.SYMBOL, ";"));
+ node.setTokens(tokens);
+ }
+ if (node instanceof FunctionEndNode) {
+ List tokens = new ArrayList<>();
+ tokens.add(new Token(Token.TokenType.KEYWORD, "END"));
+ tokens.add(new Token(Token.TokenType.SYMBOL, ";"));
+ tokens.add(new Token(Token.TokenType.KEYWORD, "$$"));
+ tokens.add(new Token(Token.TokenType.KEYWORD, "LANGUAGE"));
+ tokens.add(new Token(Token.TokenType.KEYWORD, "plpgsql"));
+ tokens.add(new Token(Token.TokenType.SYMBOL, ";"));
+ node.setTokens(tokens);
+ }
+ if (node instanceof FunctionRetDefNode) {
+ List tokens = new ArrayList<>();
+ for (Token token: node.getTokens()) {
+ if (token.hasType(Token.TokenType.KEYWORD) && token.getValue().equalsIgnoreCase("RETURN")) {
+ tokens.add(new Token(Token.TokenType.KEYWORD, "RETURNS"));
+ }
+ else if (token.hasType(Token.TokenType.KEYWORD) && token.getValue().equalsIgnoreCase("IS")) {
+ tokens.add(new Token(Token.TokenType.KEYWORD, "AS"));
+ tokens.add(new Token(Token.TokenType.KEYWORD, "$$"));
+ }
+ else {
+ tokens.add(token);
+ }
+ }
+ node.setTokens(tokens);
+ }
+ if (node instanceof TriggerOptionNode) {
+ try {
+ throw new GenerateFailedException("Unsupported type:" + node.toString() + "(OpenGauss doesn't support the keyword -- " + node.toString() + " or have any expression that keeps the same semantic!)");
+ }
+ catch (GenerateFailedException e) {
+ e.printStackTrace();
+ }
+ }
+ if (node instanceof TriggerConditionNode) {
+ if (((TriggerConditionNode) node).getCondition().hasType(Token.TokenType.KEYWORD) &&
+ ((TriggerConditionNode) node).getCondition().getValue().equalsIgnoreCase("INSTEAD OF")) {
+ try {
+ throw new GenerateFailedException("Unsupported type:" + node.toString() + "(OpenGauss doesn't support the keyword -- " + node.toString() + " or have any expression that keeps the same semantic!)");
+ }
+ catch (GenerateFailedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ if (node instanceof PLNode) {
+ List tokens = new ArrayList<>();
+ tokens.add(new Token(Token.TokenType.KEYWORD, "DO"));
+ tokens.add(new Token(Token.TokenType.KEYWORD, "$$"));
+ tokens.add(new Token(Token.TokenType.KEYWORD, "DECLARE"));
+ node.setTokens(tokens);
+ }
+ if (node instanceof PLEndNode) {
+ List tokens = new ArrayList<>();
+ tokens.add(new Token(Token.TokenType.KEYWORD, "END"));
+ tokens.add(new Token(Token.TokenType.KEYWORD, "$$"));
+ tokens.add(new Token(Token.TokenType.SYMBOL, ";"));
+ node.setTokens(tokens);
+ }
+ if (node instanceof DropOptionNode) {
+ try {
+ List tokens = new ArrayList<>();
+ tokens.add(new Token(Token.TokenType.KEYWORD, "CASCADE"));
+ tokens.add(new Token(Token.TokenType.KEYWORD, "CONSTRAINTS"));
+ if (node.tokensEqual(tokens)) {
+ throw new GenerateFailedException("Unsupported type:" + node.toString() + "(OpenGauss doesn't support the keyword -- " + node.toString() + " or have any expression that keeps the same semantic!)");
+ }
+ } catch (GenerateFailedException e) {
+ e.printStackTrace();
+ }
+ }
+ if (node instanceof JoinConditionNode) {
+ if (((JoinConditionNode) node).getKeyword().equalsIgnoreCase("USING")) {
+ ((JoinConditionNode) node).setKeyword("ON");
+ }
+ }
+ if (node instanceof TriggerEndNode) {
+ List tokens = new ArrayList<>();
+ tokens.add(new Token(Token.TokenType.KEYWORD, "END"));
+ tokens.add(new Token(Token.TokenType.SYMBOL, ";"));
+ tokens.add(new Token(Token.TokenType.KEYWORD, "$$"));
+ tokens.add(new Token(Token.TokenType.KEYWORD, "LANGUAGE"));
+ tokens.add(new Token(Token.TokenType.KEYWORD, "plpgsql"));
+ tokens.add(new Token(Token.TokenType.SYMBOL, ";"));
+ node.setTokens(tokens);
+ }
+ if ((node.getFirstChild() instanceof TriggerDeclareNode || node.getFirstChild() instanceof TriggerBeginNode)) {
+ // EXEC the procedure function
+ ASTNode currentNode = null;
+ ASTNode childNode = new TriggerBodyNode();
+ childNode.addToken(new Token(Token.TokenType.KEYWORD, "EXECUTE"));
+ childNode.addToken(new Token(Token.TokenType.KEYWORD, "PROCEDURE"));
+ childNode.addToken(new Token(Token.TokenType.IDENTIFIER, "trigger_func()"));
+ childNode.addToken(new Token(Token.TokenType.SYMBOL, ";"));
+ ASTNode triggerFuncRoot = node.getFirstChild();
+ node.replaceChild(triggerFuncRoot, childNode);
+ currentNode = childNode;
+ ASTNode triggerEndNode = new TriggerEndNode();
+ currentNode.addChild(triggerEndNode);
+ currentNode = triggerEndNode;
+
+ // Define the trigger function
+ ASTNode triggerFuncNode = new FunctionNode();
+ triggerFuncNode.addToken(new Token(Token.TokenType.KEYWORD, "CREATE"));
+ triggerFuncNode.addToken(new Token(Token.TokenType.KEYWORD, "OR"));
+ triggerFuncNode.addToken(new Token(Token.TokenType.KEYWORD, "REPLACE"));
+ triggerFuncNode.addToken(new Token(Token.TokenType.KEYWORD, "FUNCTION"));
+ currentNode.addChild(triggerFuncNode);
+ currentNode = triggerFuncNode;
+ childNode = new FunctionNameNode();
+ childNode.addToken(new Token(Token.TokenType.IDENTIFIER, "trigger_func"));
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ childNode = new FunctionRetDefNode();
+ childNode.addToken(new Token(Token.TokenType.KEYWORD, "RETURNS"));
+ childNode.addToken(new Token(Token.TokenType.KEYWORD, "TRIGGER"));
+ childNode.addToken(new Token(Token.TokenType.KEYWORD, "AS"));
+ childNode.addToken(new Token(Token.TokenType.KEYWORD, "$$"));
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ //convert the other parts
+ currentNode.addChild(triggerFuncRoot);
+ currentNode = triggerFuncRoot;
+ while (true) {
+ if (currentNode instanceof TriggerDeclareContentNode) {
+ DataTypeConvert((TriggerDeclareContentNode) currentNode);
+ }
+ else if (currentNode instanceof TriggerBodyNode) {
+ CommonConvert(currentNode);
+ }
+ else if (currentNode instanceof TriggerEndNode) {
+ CommonConvert(currentNode);
+ break;
+ }
+ else {
+ CommonConvert(currentNode);
+ }
+ currentNode = currentNode.getFirstChild();
+ }
+ }
+
+ }
+
+
+ private void DataTypeConvert(DataType node) {
+ // type convert
+ if (node.getType().getValue().equalsIgnoreCase("NUMBER")) {
+ node.setType(new Token(Token.TokenType.KEYWORD, "NUMERIC"));
+ node.ResetTokensbyType();
+ }
+ if (node.getType().getValue().matches("(?i)NUMBER\\(.*?\\)")) {
+ node.setType(new Token(Token.TokenType.KEYWORD, node.getType().getValue().toUpperCase().replace("NUMBER", "DECIMAL")));
+ node.ResetTokensbyType();
+ }
+
+ if (node.getType().getValue().equalsIgnoreCase("VARCHAR2")) {
+ node.setType(new Token(Token.TokenType.KEYWORD, "VARCHAR"));
+ node.ResetTokensbyType();
+ }
+ if (node.getType().getValue().matches("(?i)VARCHAR2\\(.*?\\)")) {
+ node.setType(new Token(Token.TokenType.KEYWORD, node.getType().getValue().toUpperCase().replace("VARCHAR2", "VARCHAR")));
+ node.ResetTokensbyType();
+ }
+
+ if (node.getType().getValue().equalsIgnoreCase("RAW")) {
+ node.setType(new Token(Token.TokenType.KEYWORD, "BYTEA"));
+ node.ResetTokensbyType();
+ }
+ if (node.getType().getValue().matches("(?i)RAW\\(.*?\\)")) {
+ node.setType(new Token(Token.TokenType.KEYWORD, node.getType().getValue().toUpperCase().replace("RAW", "BYTEA")));
+ node.ResetTokensbyType();
+ }
+
+ if (node.getType().getValue().equalsIgnoreCase("BINARY_INTEGER")) {
+ node.setType(new Token(Token.TokenType.KEYWORD, "INTEGER"));
+ node.ResetTokensbyType();
+ }
+
+ if (node.getType().getValue().equalsIgnoreCase("NCHAR")) {
+ node.setType(new Token(Token.TokenType.KEYWORD, "VARCHAR"));
+ node.ResetTokensbyType();
+ }
+ if (node.getType().getValue().matches("(?i)NCHAR\\(.*?\\)")) {
+ node.setType(new Token(Token.TokenType.KEYWORD, node.getType().getValue().toUpperCase().replace("NCHAR", "VARCHAR")));
+ node.ResetTokensbyType();
+ }
+
+ if (node.getType().getValue().equalsIgnoreCase("NVARCHAR2")) {
+ node.setType(new Token(Token.TokenType.KEYWORD, "VARCHAR"));
+ node.ResetTokensbyType();
+ }
+ if (node.getType().getValue().matches("(?i)NVARCHAR2\\(.*?\\)")) {
+ node.setType(new Token(Token.TokenType.KEYWORD, node.getType().getValue().toUpperCase().replace("NVARCHAR2", "VARCHAR")));
+ node.ResetTokensbyType();
+ }
+
+ if (node.getType().getValue().equalsIgnoreCase("NCLOB")) {
+ node.setType(new Token(Token.TokenType.KEYWORD, "TEXT"));
+ node.ResetTokensbyType();
+ }
+
+ if (node.getType().getValue().equalsIgnoreCase("INTERVAL YEAR TO MONTH")) {
+ node.setType(new Token(Token.TokenType.KEYWORD, "INTERVAL"));
+ node.ResetTokensbyType();
+ }
+
+ if (node.getType().getValue().equalsIgnoreCase("INTERVAL DAY TO SECOND")) {
+ node.setType(new Token(Token.TokenType.KEYWORD, "INTERVAL"));
+ node.ResetTokensbyType();
+ }
+
+ // Impossible to convert
+ if (
+ node.getType().getValue().equalsIgnoreCase("TIMESTAMP WITH LOCAL TIME ZONE") ||
+ node.getType().getValue().equalsIgnoreCase("LONG RAW") ||
+ node.getType().getValue().equalsIgnoreCase("ROWID") ||
+ node.getType().getValue().equalsIgnoreCase("UROWID") ||
+ node.getType().getValue().equalsIgnoreCase("REF CURSOR")
+ ) {
+ try {
+ throw new GenerateFailedException("Unsupported type:" + node.getType().getValue() + "(OpenGauss doesn't support the keyword -- " + node.getType().getValue() + " or have any expression that keeps the same semantic!)");
+ }
+ catch (GenerateFailedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/interfaces/DataType.java b/sqlTranslate/src/main/java/interfaces/DataType.java
new file mode 100644
index 0000000000000000000000000000000000000000..486a52393e444b31e2a9776f0d97c0c8e777ca08
--- /dev/null
+++ b/sqlTranslate/src/main/java/interfaces/DataType.java
@@ -0,0 +1,9 @@
+package interfaces;
+
+import lexer.Token;
+
+public interface DataType {
+ Token getType();
+ void setType(Token type);
+ void ResetTokensbyType();
+}
diff --git a/sqlTranslate/src/main/java/lexer/OracleLexer.java b/sqlTranslate/src/main/java/lexer/OracleLexer.java
new file mode 100644
index 0000000000000000000000000000000000000000..fa85ba0c79f5585986408fc109e142d78a1e8ac3
--- /dev/null
+++ b/sqlTranslate/src/main/java/lexer/OracleLexer.java
@@ -0,0 +1,223 @@
+package lexer;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+
+public class OracleLexer {
+ public static final String[] keywords = {"SELECT", "FROM", "WHERE", "AND", "OR", "INSERT", "UPDATE", "DELETE", "VALUES", "INTO",
+ // keywords of creating table
+ "CREATE", "TABLE", "TEMPORARY", "GLOBAL",
+ "NUMBER", "INTEGER", "SMALLIN", "BINARY_INTEGER", "DECIMAL", "REAL", "FLOAT", "DOUBLE PRECISION", "CHAR", "VARCHAR2",
+ "NCHAR", "NVARCHAR2", "CLOB", "NCLOB", "DATE", "TIMESTAMP", "TIMESTAMP WITH TIME ZONE", "TIMESTAMP WITH LOCAL TIME ZONE", "BLOB", "RAW",
+ "LONG RAW", "BOOLEAN", "INTERVAL YEAR TO MONTH", "INTERVAL DAY TO SECOND", "ROWID", "UROWID", "REF CURSOR",
+ "NOT NULL", "PRIMARY KEY", "UNIQUE", "CHECK", "REFERENCES", "DEFAULT", "CONSTRAINT", "FOREIGN KEY"
+ // keywords of drop table
+ , "DROP", "CASCADE"
+ // keywords of select
+ , "DISTINCT", "JOIN", "GROUP BY", "ORDER BY", "HAVING", "UNION", "CASE", "WHEN", "END", "AS", "||"
+ // keywords of join
+ , "INNER JOIN", "LEFT JOIN", "LEFT OUTER JOIN", "RIGHT JOIN", "RIGHT OUTER JOIN", "FULL JOIN", "FULL OUTER JOIN", "CROSS JOIN", "JOIN", "ON", "USING"
+ // keywords of case when
+ , "THEN", "ELSE"
+ // keywords of update
+ , "SET"
+ // keywords of alter table
+ , "ALTER", "ADD", "DROP", "MODIFY", "RENAME", "TO", "COLUMN"
+ // keywords of view
+ , "REPLACE", "VIEW"
+ // PL/SQL
+ , ":=", "IF", "ELSIF", "BEGIN", "..", "DECLARE"
+ // Loop
+ , "LOOP", "EXIT", "WHILE", "FOR", "IN", "CONTINUE"
+ // Exception
+ , "EXCEPTION", "SQLERRM", "ZERO_DIVIDE", "INVALID_NUMBER", "OTHERS"
+ // Procedure
+ , "PROCEDURE", "IS", "IN", "OUT", "$$", "COMMIT", "ROLLBACK", "EXEC", "EXECUTE"
+ // function
+ , "FUNCTION", "RETURN"
+ // trigger
+ , "TRIGGER", "BEFORE", "AFTER", "INSTEAD OF", "REFERENCING", "NEW", "OLD", "EACH", "ROW"
+ };
+ private static final Pattern TOKEN_PATTERN = Pattern.compile(
+ "(NUMBER\\(.*?\\))|" + // NUMBER() function
+ "(DECIMAL\\(.*?\\))|" + // DECIMAL() function
+ "(FLOAT\\(.*?\\))|" + // FLOAT() function
+ "(CHAR\\(.*?\\))|" + // CHAR() function
+ "(VARCHAR2\\(.*?\\))|" + // VARCHAR2() function
+ "(NCHAR\\(.*?\\))|" + // NCHAR() function
+ "(NVARCHAR2\\(.*?\\))|" + // NVARCHAR2() function
+ "(RAW\\(.*?\\))|" + // RAW() function
+
+ "(COUNT\\(.*?\\))|" + // COUNT() function
+ "(SUM\\(.*?\\))|" + // SUM() function
+ "(AVG\\(.*?\\))|" + // AVG() function
+ "(MAX\\(.*?\\))|" + // MAX() function
+ "(MIN\\(.*?\\))|" + // MIN() function
+ "(\\|\\|\\s*'.*?'\\s*\\|\\|)|" + // || '*' ||
+ "(DBMS_OUTPUT.PUT_LINE\\(.*?\\))|" + // DBMS_OUTPUT.PUT_LINE() function
+ "(LENGTH\\(.*?\\))|" + // LENGTH() function
+
+ "(NOT NULL)|" +
+ "(PRIMARY KEY)|" +
+ "(FOREIGN KEY)|" +
+ "(DOUBLE PRECISION)|" +
+ "(TIMESTAMP WITH TIME ZONE)|" +
+ "(TIMESTAMP WITH LOCAL TIME ZONE)|" +
+ "(LONG RAW)|" +
+ "(INTERVAL YEAR TO MONTH)|" +
+ "(INTERVAL DAY TO SECOND)|" +
+ "(REF CURSOR)|" +
+ "(GROUP BY)|" +
+ "(ORDER BY)|" +
+ "(INNER JOIN)|" +
+ "(LEFT JOIN)|" +
+ "(LEFT OUTER JOIN)|" +
+ "(RIGHT JOIN)|" +
+ "(RIGHT OUTER JOIN)|" +
+ "(FULL JOIN)|" +
+ "(FULL OUTER JOIN)|" +
+ "(CROSS JOIN)|" +
+ "(INSTEAD OF)|" +
+ "(\\|\\|)|" +
+ "(:=)|" +
+ "(\\.\\.)|" +
+
+ "(\\b[A-Za-z_][A-Za-z0-9_.%]*\\b)|" + // Keywords and identifiers
+ "(\\d+\\.?\\d*)|" + // Numbers (integer or decimal)
+ "(\"[^\"]*\")|" + // Double-quoted strings
+ "('([^']|\\\\')*)'|" + // Single-quoted strings
+ "([;,()])|" + // Symbols: ;, (, ), ,
+ "([=<>+\\-*/<<>>])|" + // Operators, including shift operators
+ "(\\s+)", // Whitespace
+ Pattern.CASE_INSENSITIVE
+ );
+
+ private final List tokens = new ArrayList<>();
+ private final String input;
+ private int position = 0;
+
+ public OracleLexer(String input) {
+ this.input = dataProcess(input);
+ tokenize();
+ }
+
+ public List tokenize() {
+ Matcher matcher = TOKEN_PATTERN.matcher(input);
+ while (matcher.find()) {
+ String tokenValue = matcher.group();
+ Token token = createToken(tokenValue);
+ if (token != null) { // Skip whitespace
+ tokens.add(token);
+ // Update position based on the length of the matched group
+ position += tokenValue.length();
+ } else {
+ // If the token is null, we skip it (whitespace)
+ position += tokenValue.length();
+ }
+ }
+ tokens.add(new Token(Token.TokenType.EOF, ""));
+ return tokens;
+ }
+
+ private Token createToken(String tokenValue) {
+ if (tokenValue.matches("\\d+(\\.\\d+)?")) {
+ return new Token(Token.TokenType.NUMBER, tokenValue);
+ } else if (tokenValue.matches("\"[^\"]*\"")) {
+ return new Token(Token.TokenType.STRING, tokenValue);
+ } else if (tokenValue.matches("'([^']|\\\\')*'")) {
+ return new Token(Token.TokenType.STRING, tokenValue);
+ } else if (tokenValue.matches("([;(),])")) {
+ return new Token(Token.TokenType.SYMBOL, tokenValue);
+ } else if (tokenValue.matches("[=<>+\\-*/<<>>]")) {
+ return new Token(Token.TokenType.OPERATOR, tokenValue);
+ }
+
+ else if (tokenValue.matches("(?i)NUMBER\\(.*?\\)")) {
+ // NUMBER() function, CASE_INSENSITIVE
+ return new Token(Token.TokenType.KEYWORD, tokenValue);
+ } else if (tokenValue.matches("(?i)DECIMAL\\(.*?\\)")) {
+ // DECIMAL() function, CASE_INSENSITIVE
+ return new Token(Token.TokenType.KEYWORD, tokenValue);
+ } else if (tokenValue.matches("(?i)FLOAT\\(.*?\\)")) {
+ // FLOAT() function, CASE_INSENSITIVE
+ return new Token(Token.TokenType.KEYWORD, tokenValue);
+ } else if (tokenValue.matches("(?i)CHAR\\(.*?\\)")) {
+ // CHAR() function, CASE_INSENSITIVE
+ return new Token(Token.TokenType.KEYWORD, tokenValue);
+ } else if (tokenValue.matches("(?i)VARCHAR2\\(.*?\\)")) {
+ // VARCHAR2() function, CASE_INSENSITIVE
+ return new Token(Token.TokenType.KEYWORD, tokenValue);
+ } else if (tokenValue.matches("(?i)NCHAR\\(.*?\\)")) {
+ // NCHAR() function, CASE_INSENSITIVE
+ return new Token(Token.TokenType.KEYWORD, tokenValue);
+ } else if (tokenValue.matches("(?i)NVARCHAR2\\(.*?\\)")) {
+ // NVARCHAR2() function, CASE_INSENSITIVE
+ return new Token(Token.TokenType.KEYWORD, tokenValue);
+ } else if (tokenValue.matches("(?i)RAW\\(.*?\\)")) {
+ // RAW() function, CASE_INSENSITIVE
+ return new Token(Token.TokenType.KEYWORD, tokenValue);
+ } else if (tokenValue.matches("(?i)COUNT\\(.*?\\)")) {
+ // RAW() function, CASE_INSENSITIVE
+ return new Token(Token.TokenType.KEYWORD, tokenValue);
+ } else if (tokenValue.matches("(?i)SUM\\(.*?\\)")) {
+ // RAW() function, CASE_INSENSITIVE
+ return new Token(Token.TokenType.KEYWORD, tokenValue);
+ } else if (tokenValue.matches("(?i)AVG\\(.*?\\)")) {
+ // RAW() function, CASE_INSENSITIVE
+ return new Token(Token.TokenType.KEYWORD, tokenValue);
+ } else if (tokenValue.matches("(?i)MAX\\(.*?\\)")) {
+ // RAW() function, CASE_INSENSITIVE
+ return new Token(Token.TokenType.KEYWORD, tokenValue);
+ } else if (tokenValue.matches("(?i)MIN\\(.*?\\)")) {
+ // RAW() function, CASE_INSENSITIVE
+ return new Token(Token.TokenType.KEYWORD, tokenValue);
+ } else if (tokenValue.matches("\\|\\|\\s*'.*?'\\s*\\|\\|")) {
+ // RAW() function, CASE_INSENSITIVE
+ return new Token(Token.TokenType.KEYWORD, tokenValue);
+ } else if (tokenValue.matches("(?i)DBMS_OUTPUT.PUT_LINE\\(.*?\\)")) {
+ // RAW() function, CASE_INSENSITIVE
+ return new Token(Token.TokenType.KEYWORD, tokenValue);
+ } else if (tokenValue.matches("(?i)LENGTH\\(.*?\\)")) {
+ // RAW() function, CASE_INSENSITIVE
+ return new Token(Token.TokenType.KEYWORD, tokenValue);
+ }
+
+ else if (isKeyword(tokenValue)) {
+ return new Token(Token.TokenType.KEYWORD, tokenValue);
+ } else if (tokenValue.matches("[a-zA-Z_][a-zA-Z0-9_.%]*")) {
+ return new Token(Token.TokenType.IDENTIFIER, tokenValue);
+ }
+ return null;
+ }
+
+ private boolean isKeyword(String tokenValue) {
+ for (String keyword : keywords) {
+ if (keyword.equalsIgnoreCase(tokenValue)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static String dataProcess(String input){
+ while (input.contains(" ")) {
+ input = input.replace(" ", " ");
+ }
+ input = input.replace(" (", "(");
+ input = input.replace("..", " .. ");
+ return input;
+ }
+
+ public void printTokens() {
+ for (Token token : tokens) {
+ System.out.println(token);
+ }
+ }
+
+ public List getTokens() {
+ return tokens;
+ }
+}
diff --git a/sqlTranslate/src/main/java/lexer/Token.java b/sqlTranslate/src/main/java/lexer/Token.java
new file mode 100644
index 0000000000000000000000000000000000000000..b44ea7ecc5e85b4ca293c5dbf5f2f5412766045f
--- /dev/null
+++ b/sqlTranslate/src/main/java/lexer/Token.java
@@ -0,0 +1,46 @@
+package lexer;
+
+import java.util.Objects;
+
+public class Token {
+ public enum TokenType {
+ KEYWORD, IDENTIFIER, NUMBER, OPERATOR, STRING, SYMBOL, NULL, EOF
+ }
+
+ private TokenType type;
+ private final String value;
+
+ public Token(TokenType type, String value) {
+ this.type = type;
+ this.value = value;
+ }
+
+ public TokenType getType() {
+ return type;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public boolean hasType(TokenType type) {
+ return this.type == type;
+ }
+
+ @Override
+ public String toString() {
+ return "Token{" +
+ "type=" + type +
+ ", value='" + value + '\'' +
+ '}';
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (obj == null || getClass() != obj.getClass()) return false;
+ Token token = (Token) obj;
+ return type == token.type && Objects.equals(value, token.value);
+ }
+
+}
diff --git a/sqlTranslate/src/main/java/parser/OracleParser.java b/sqlTranslate/src/main/java/parser/OracleParser.java
new file mode 100644
index 0000000000000000000000000000000000000000..5ecd5602e678f01539d63a15d9f3708fa27803bd
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/OracleParser.java
@@ -0,0 +1,2669 @@
+package parser;
+
+import lexer.OracleLexer;
+import lexer.Token;
+import parser.ast.ASTNode;
+import exception.ParseFailedException;
+import parser.ast.altertable.*;
+import parser.ast.casewhen.CaseConditionNode;
+import parser.ast.casewhen.CaseElseNode;
+import parser.ast.casewhen.CaseEndNode;
+import parser.ast.casewhen.CaseThenNode;
+import parser.ast.createtable.*;
+import parser.ast.delete.DeleteConditionNode;
+import parser.ast.delete.DeleteEndNode;
+import parser.ast.delete.DeleteNode;
+import parser.ast.delete.DeleteObjNode;
+import parser.ast.drop.DropEndNode;
+import parser.ast.drop.DropObjNameNode;
+import parser.ast.drop.DropNode;
+import parser.ast.drop.DropOptionNode;
+import parser.ast.exception.*;
+import parser.ast.function.*;
+import parser.ast.ifelsif.*;
+import parser.ast.insert.InsertDataNode;
+import parser.ast.insert.InsertEndNode;
+import parser.ast.insert.InsertNode;
+import parser.ast.insert.InsertObjNode;
+import parser.ast.join.*;
+import parser.ast.loop.*;
+import parser.ast.pl.*;
+import parser.ast.procedure.*;
+import parser.ast.select.*;
+import parser.ast.trigger.*;
+import parser.ast.update.*;
+import parser.ast.view.ViewCreateNode;
+import parser.ast.view.ViewEndNode;
+import parser.ast.view.ViewNameNode;
+import parser.ast.view.ViewTargetNode;
+
+import java.util.Stack;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class OracleParser {
+ private OracleLexer lexer;
+ public OracleParser() {}
+ public OracleParser(OracleLexer lexer) {
+ this.lexer = lexer;
+ }
+ public void setLexer(OracleLexer lexer) {
+ this.lexer = lexer;
+ }
+ public ASTNode parse()
+ {
+ try {
+ // check if the input is a create table statement
+ if ((lexer.getTokens().get(0).getValue().equalsIgnoreCase("CREATE") && lexer.getTokens().get(1).getValue().equalsIgnoreCase("TABLE")) ||
+ (lexer.getTokens().get(0).getValue().equalsIgnoreCase("CREATE") && lexer.getTokens().get(2).getValue().equalsIgnoreCase("TEMPORARY") && lexer.getTokens().get(3).getValue().equalsIgnoreCase("TABLE"))) {
+ return parseCreateTab(lexer.getTokens());
+ } else if (lexer.getTokens().get(0).getValue().equalsIgnoreCase("INSERT")) {
+ return parseInsert(lexer.getTokens());
+ } else if (lexer.getTokens().get(0).getValue().equalsIgnoreCase("DROP")) {
+ return parseDrop(lexer.getTokens());
+ } else if (lexer.getTokens().get(0).getValue().equalsIgnoreCase("SELECT")) {
+ return parseSelect(lexer.getTokens());
+ } else if (lexer.getTokens().get(0).getValue().equalsIgnoreCase("UPDATE")) {
+ return parseUpdate(lexer.getTokens());
+ } else if (lexer.getTokens().get(0).getValue().equalsIgnoreCase("DELETE")) {
+ return parseDelete(lexer.getTokens());
+ } else if (lexer.getTokens().get(0).getValue().equalsIgnoreCase("ALTER")) {
+ return parseAlterTable(lexer.getTokens());
+ } else if (
+ (lexer.getTokens().get(0).getValue().equalsIgnoreCase("CREATE") && lexer.getTokens().get(1).getValue().equalsIgnoreCase("OR") && lexer.getTokens().get(2).getValue().equalsIgnoreCase("REPLACE") && lexer.getTokens().get(3).getValue().equalsIgnoreCase("VIEW"))
+ || (lexer.getTokens().get(0).getValue().equalsIgnoreCase("CREATE") && lexer.getTokens().get(1).getValue().equalsIgnoreCase("VIEW"))
+ ) {
+ return parseCreateView(lexer.getTokens());
+ } else if (
+ lexer.getTokens().get(0).getValue().equalsIgnoreCase("FOR")
+ || lexer.getTokens().get(0).getValue().equalsIgnoreCase("LOOP")
+ || lexer.getTokens().get(0).getValue().equalsIgnoreCase("WHILE")
+ ) {
+ return parseLoop(lexer.getTokens());
+ } else if (
+ (lexer.getTokens().get(0).getValue().equalsIgnoreCase("CREATE") && lexer.getTokens().get(1).getValue().equalsIgnoreCase("PROCEDURE"))
+ || (lexer.getTokens().get(0).getValue().equalsIgnoreCase("CREATE") && lexer.getTokens().get(1).getValue().equalsIgnoreCase("OR") && lexer.getTokens().get(2).getValue().equalsIgnoreCase("REPLACE") && lexer.getTokens().get(3).getValue().equalsIgnoreCase("PROCEDURE"))
+ )
+ {
+ return parseProcedure(lexer.getTokens());
+ } else if (
+ (lexer.getTokens().get(0).getValue().equalsIgnoreCase("CREATE") && lexer.getTokens().get(1).getValue().equalsIgnoreCase("FUNCTION"))
+ || (lexer.getTokens().get(0).getValue().equalsIgnoreCase("CREATE") && lexer.getTokens().get(1).getValue().equalsIgnoreCase("OR") && lexer.getTokens().get(2).getValue().equalsIgnoreCase("REPLACE") && lexer.getTokens().get(3).getValue().equalsIgnoreCase("FUNCTION"))
+ )
+ {
+ return parseFunction(lexer.getTokens());
+ } else if (
+ (lexer.getTokens().get(0).getValue().equalsIgnoreCase("CREATE") && lexer.getTokens().get(1).getValue().equalsIgnoreCase("TRIGGER"))
+ || (lexer.getTokens().get(0).getValue().equalsIgnoreCase("CREATE") && lexer.getTokens().get(1).getValue().equalsIgnoreCase("OR") && lexer.getTokens().get(2).getValue().equalsIgnoreCase("REPLACE") && lexer.getTokens().get(3).getValue().equalsIgnoreCase("TRIGGER"))
+ )
+ {
+ return parseTrigger(lexer.getTokens());
+ } else if (lexer.getTokens().get(0).getValue().equalsIgnoreCase("DECLARE")) {
+ return parsePL(lexer.getTokens());
+ }
+ else {
+ try {
+ throw new ParseFailedException("Parse failed!--Unsupport SQL:" + lexer.getTokens().get(0).getValue());
+ } catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public ASTNode parseTokens(List parseTokens) {
+ try {
+ if ((parseTokens.get(0).getValue().equalsIgnoreCase("CREATE") && parseTokens.get(1).getValue().equalsIgnoreCase("TABLE")) ||
+ (parseTokens.get(0).getValue().equalsIgnoreCase("CREATE") && parseTokens.get(2).getValue().equalsIgnoreCase("TEMPORARY") && parseTokens.get(3).getValue().equalsIgnoreCase("TABLE"))) {
+ return parseCreateTab(parseTokens);
+ } else if (parseTokens.get(0).getValue().equalsIgnoreCase("INSERT")) {
+ return parseInsert(parseTokens);
+ } else if (parseTokens.get(0).getValue().equalsIgnoreCase("DROP")) {
+ return parseDrop(parseTokens);
+ } else if (parseTokens.get(0).getValue().equalsIgnoreCase("SELECT")) {
+ return parseSelect(parseTokens);
+ } else if (parseTokens.get(0).getValue().equalsIgnoreCase("UPDATE")) {
+ return parseUpdate(parseTokens);
+ } else if (parseTokens.get(0).getValue().equalsIgnoreCase("DELETE")) {
+ return parseDelete(parseTokens);
+ } else if (parseTokens.get(0).getValue().equalsIgnoreCase("ALTER")) {
+ return parseAlterTable(parseTokens);
+ } else if (
+ (parseTokens.get(0).getValue().equalsIgnoreCase("CREATE") && parseTokens.get(1).getValue().equalsIgnoreCase("OR") && parseTokens.get(2).getValue().equalsIgnoreCase("REPLACE") && parseTokens.get(3).getValue().equalsIgnoreCase("VIEW"))
+ || (parseTokens.get(0).getValue().equalsIgnoreCase("CREATE") && parseTokens.get(1).getValue().equalsIgnoreCase("VIEW"))
+ ) {
+ return parseCreateView(parseTokens);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * CREATE TEMPORARY? TABLE _table ( (_column _type column_constraint), (_column _type column_constraint)* table_constraint?)
+ */
+ private ASTNode parseCreateTab(List parseTokens) {
+ List tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(0));
+ ASTNode root = new CreateTabNode(tokens);
+ ASTNode currentNode = null;
+ for (int i = 1; i < parseTokens.size(); i++) {
+// System.out.println("Parsing the token: " + parseTokens.get(i).getValue());
+ if (i == 1 && parseTokens.get(i).getValue().equalsIgnoreCase("TABLE")) {
+ tokens = new ArrayList<>();
+
+ tokens.add(parseTokens.get(i));
+ try {
+ tokens.add(parseTokens.get(i + 1));
+ }
+ catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ i++;
+ i++; // pass the "("
+ ASTNode child = new TableNode(tokens);
+ root.addChild(child);
+ currentNode = child;
+ }
+ else if (i == 1 && !parseTokens.get(i).getValue().equalsIgnoreCase("TABLE")){
+ tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(i));
+ for (int j = i + 1; j < parseTokens.size(); j++) {
+ if (parseTokens.get(j).getValue().equalsIgnoreCase("TABLE")) {
+ ASTNode child = new TableTypeNode(tokens);
+ root.addChild(child);
+ currentNode = child;
+ tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(j));
+ try {
+ tokens.add(parseTokens.get(j + 1));
+ }
+ catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ i = j + 2; // pass the "("
+ break;
+ }
+ tokens.add(parseTokens.get(j));
+ }
+
+ ASTNode child = new TableNode(tokens);
+ currentNode.addChild(child);
+ currentNode = child;
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.IDENTIFIER)) {
+ // Token.TokenType.IDENTIFIER ... , -> column node
+ tokens = new ArrayList<>();
+ ColumnNode child = new ColumnNode();
+ child.setName(parseTokens.get(i));
+ tokens.add(parseTokens.get(i));
+ List constraint = new ArrayList<>();
+ for (int j = i + 1; j < parseTokens.size(); j++) {
+ if (j == i + 1) {
+ child.setType(parseTokens.get(j));
+ }
+ // Check () or REFERENCES other_table(other_column)
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) &&
+ (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));
+ constraint.add(parseTokens.get(k));
+ if (parseTokens.get(k).getValue().equals("(")) {
+ stack.push("(");
+ for (int t = k + 1; t < parseTokens.size(); t++) {
+ tokens.add(parseTokens.get(t));
+ constraint.add(parseTokens.get(t));
+ if (parseTokens.get(t).getValue().equals("(")) {
+ stack.push("(");
+ }
+ else if (parseTokens.get(t).getValue().equals(")")) {
+ stack.pop();
+ if (stack.empty()) {
+ i = t;
+ break;
+ }
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+ if ((parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(",")) ||
+ (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(")")) ) {
+ i = j;
+ break;
+ }
+ tokens.add(parseTokens.get(j));
+ if (j != i + 1) {
+ constraint.add(parseTokens.get(j));
+ }
+ }
+ child.setTokens(tokens);
+ child.setConstraint(constraint);
+ currentNode.addChild(child);
+ currentNode = child;
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD)
+ && parseTokens.get(i).getValue().equalsIgnoreCase("CONSTRAINT")) {
+ // Table constraint
+ tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(i));
+ for (int j = i + 1; j < parseTokens.size(); j++) {
+ /**
+ * CONSTRAINT pk_example PRIMARY KEY (column1, column2)
+ * CONSTRAINT uk_example UNIQUE (column1)
+ * CONSTRAINT fk_example FOREIGN KEY (column1) REFERENCES other_table(column2)
+ * CONSTRAINT chk_example CHECK (column1 > 0)
+ */
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) &&
+ (parseTokens.get(j).getValue().equalsIgnoreCase("UNIQUE")
+ || parseTokens.get(j).getValue().equalsIgnoreCase("CHECK")
+ || parseTokens.get(j).getValue().equalsIgnoreCase("PRIMARY KEY")
+ || parseTokens.get(j).getValue().equalsIgnoreCase("FOREIGN KEY")
+ || parseTokens.get(j).getValue().equalsIgnoreCase("REFERENCES"))) {
+ tokens.add(parseTokens.get(j));
+ Stack stack = new Stack<>();
+ for (int k = j + 1; k < parseTokens.size(); k++) {
+ tokens.add(parseTokens.get(k));
+ if (parseTokens.get(k).getValue().equals("(")) {
+ stack.push("(");
+ for (int t = k + 1; t < parseTokens.size(); t++) {
+ tokens.add(parseTokens.get(t));
+ if (parseTokens.get(t).getValue().equals("(")) {
+ stack.push("(");
+ }
+ else if (parseTokens.get(t).getValue().equals(")")) {
+ stack.pop();
+ if (stack.empty()) {
+ i = t;
+ j = t;
+ break;
+ }
+ }
+ }
+ break;
+ }
+ }
+ continue;
+ }
+ if ((parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(",")) ||
+ (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(")")) ) {
+ i = j;
+ break;
+ }
+ tokens.add(parseTokens.get(j));
+ }
+ ASTNode childNode = new TableConstraintNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.SYMBOL) && parseTokens.get(i).getValue().equals(";")) {
+ tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(i));
+ ASTNode EndNode = new CRTEndNode(tokens);
+ currentNode.addChild(EndNode);
+ currentNode = EndNode;
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.SYMBOL) && parseTokens.get(i).getValue().equals(",")) {
+ continue;
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.EOF)) {
+ break;
+ }
+ else {
+// System.out.println("Fail to parse:" + parseTokens.get(i).getValue());
+ try {
+ throw new ParseFailedException("Parse failed!--" + parseTokens.get(i));
+ }
+ catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ return root;
+ }
+
+ /**
+ * INSERT INTO table_name VALUES (value1, value2, ...)
+ */
+ private ASTNode parseInsert(List parseTokens) {
+ List tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(0));
+ try {
+ tokens.add(parseTokens.get(1));
+ }
+ catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ ASTNode root = new InsertNode(tokens);
+ ASTNode currentNode = root;
+
+ for (int i = 2; i < parseTokens.size(); i++) {
+ if (parseTokens.get(i).hasType(Token.TokenType.IDENTIFIER)) { // table name
+ tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(i));
+ if (i + 1 < parseTokens.size() && ! (parseTokens.get(i + 1).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i + 1).getValue().equalsIgnoreCase("VALUES"))) {
+ for (int j = i + 1; j < parseTokens.size(); j++) {
+ tokens.add(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(")")) {
+ i = j;
+ break;
+ }
+ }
+ }
+ ASTNode childNode = new InsertObjNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("VALUES")) {
+ tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(i));
+ for (int j = i + 1; j < parseTokens.size(); j++) {
+ if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";")) {
+ i = j - 1;
+ break;
+ }
+ tokens.add(parseTokens.get(j));
+ }
+ ASTNode childNode = new InsertDataNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.SYMBOL) && parseTokens.get(i).getValue().equals(";")) {
+ tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(i));
+ ASTNode childNode = new InsertEndNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.EOF)) {
+ break;
+ }
+ else {
+ try {
+ throw new ParseFailedException("Parse failed!");
+ }
+ catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ }
+
+ return root;
+ }
+
+ /**
+ * DROP TABLE _table (CASCADE CONSTRAINTS)? | DROP VIEW _view
+ */
+ private ASTNode parseDrop(List parseTokens) {
+ List tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(0));
+ try {
+ tokens.add(parseTokens.get(1));
+ }
+ catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ ASTNode root = new DropNode(tokens);
+ ASTNode currentNode = root;
+
+ for (int i = 2; i < parseTokens.size(); i++) {
+ if (parseTokens.get(i).hasType(Token.TokenType.IDENTIFIER)) {
+ tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(i));
+ ASTNode childNode = new DropObjNameNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("CASCADE")) {
+ tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(i));
+ if (i + 1 < parseTokens.size() && (parseTokens.get(i + 1).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i + 1).getValue().equals("CONSTRAINTS"))) {
+ tokens.add(parseTokens.get(i + 1));
+ i++;
+ }
+ ASTNode childNode = new DropOptionNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.SYMBOL) && parseTokens.get(i).getValue().equals(";")) {
+ tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(i));
+ ASTNode childNode = new DropEndNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.EOF)) {
+ break;
+ }
+ else {
+ try {
+ throw new ParseFailedException("Parse failed!");
+ }
+ catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ return root;
+ }
+
+ /**
+ * SELECT DISTINCT? select_obj FROM select_tab where_clause? select_option? union_clause?
+ */
+ private ASTNode parseSelect(List parseTokens) {
+ List tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(0));
+ ASTNode root = new SelectNode(tokens);
+ ASTNode currentNode = root;
+ for(int i = 1; i < parseTokens.size(); i++) {
+ // match select_obj
+ if (i == 1 && parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("DISTINCT")) {
+ SelectContentNode childNode = new SelectContentNode();
+ childNode.setIsDistinct(parseTokens.get(i).getValue());
+ tokens = new ArrayList<>();
+ for (int j = i + 1; j < parseTokens.size(); j++) {
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("FROM")) {
+ i = j;
+ break;
+ }
+ tokens.add(parseTokens.get(j));
+ }
+ childNode.setTokens(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else if (i == 1 && (!parseTokens.get(i).hasType(Token.TokenType.KEYWORD) || !parseTokens.get(i).getValue().equalsIgnoreCase("DISTINCT"))) {
+ tokens = new ArrayList<>();
+ for (int j = i; j < parseTokens.size(); j++) {
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("FROM")) {
+ i = j;
+ break;
+ }
+ tokens.add(parseTokens.get(j));
+ }
+ ASTNode childNode = new SelectContentNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ // match select_tab (possible last token: ; | GROUP BY | ORDER BY | HAVING | WHERE | UNION)
+ else if (currentNode instanceof SelectContentNode) {
+ tokens = new ArrayList<>();
+ for (int j = i; j < parseTokens.size(); j++) {
+ if (
+ (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("WHERE"))
+ || (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("GROUP BY"))
+ || (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("ORDER BY"))
+ || (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("HAVING"))
+ || (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("UNION"))
+ || (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";"))
+ ) {
+ i = j - 1;
+ break;
+ }
+ tokens.add(parseTokens.get(j));
+ }
+ if (tokens.contains(new Token(Token.TokenType.KEYWORD, "JOIN"))) {
+ ASTNode joinRootNode = parseJoin(tokens);
+ currentNode.addChild(joinRootNode);
+ currentNode = joinRootNode.getDeepestChild();
+ }
+ else {
+ ASTNode childNode = new SelectObjNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ }
+ // match where_clause (possible last token: ; | GROUP | ORDER | HAVING | UNION)
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("WHERE")) {
+ tokens = new ArrayList<>();
+ for (int j = i; j < parseTokens.size(); j++) {
+ if (
+ (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("GROUP BY"))
+ || (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("ORDER BY"))
+ || (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("HAVING"))
+ || (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("UNION"))
+ || (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";"))
+ ) {
+ i = j - 1;
+ break;
+ }
+ tokens.add(parseTokens.get(j));
+ }
+ ASTNode childNode = new SelectWhereClauseNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ // match select_option
+ else if (
+ (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("GROUP BY"))
+ || (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("ORDER BY"))
+ || (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("HAVING"))
+ ) {
+ tokens = new ArrayList<>();
+ String optionName = parseTokens.get(i).getValue();
+ for (int j = i; j < parseTokens.size(); j++) {
+ if (
+ j != i && !parseTokens.get(j).getValue().equalsIgnoreCase(optionName) &&
+ ((parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("UNION"))
+ || (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";"))
+ || (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("GROUP BY"))
+ || (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("ORDER BY"))
+ || (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("HAVING")))
+ ) {
+ i = j - 1;
+ break;
+ }
+ tokens.add(parseTokens.get(j));
+ }
+ ASTNode childNode = new SelectOptionNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ // match union_clause
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("UNION")) {
+ tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(i));
+ ASTNode childNode = new SelectUnionNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ List unionTokens = parseTokens.subList(i + 1, parseTokens.size());
+ ASTNode unionChildNode = parseSelect(unionTokens);
+ currentNode.addChild(unionChildNode);
+ currentNode = unionChildNode;
+ break;
+ }
+ // match ;
+ else if (parseTokens.get(i).hasType(Token.TokenType.SYMBOL) && parseTokens.get(i).getValue().equals(";")) {
+ tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(i));
+ ASTNode childNode = new SelectEndNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.EOF)) {
+ break;
+ }
+ else {
+ try {
+ throw new ParseFailedException("Parse failed!--" + parseTokens.get(i).getValue());
+ }
+ catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ return root;
+ }
+
+ /**
+ * IF condition1 THEN ...
+ * (ELSIF condition2 THEN ...)*
+ * [ELSE...]
+ * END IF;
+ * @param parseTokens should start with IF
+ */
+ public static ASTNode parseIFELSE(List parseTokens) {
+ ASTNode root = new IFConditionNode();
+ ASTNode currentNode = root;
+ for (int i = 0; i < parseTokens.size(); i++) {
+ // match IF condition
+ if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("IF")) {
+ for (int j = i; j < parseTokens.size(); j++) {
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("THEN")) {
+ i = j - 1;
+ break;
+ }
+ root.addToken(parseTokens.get(j));
+ }
+ }
+ // match IF action
+ else if (currentNode instanceof IFConditionNode && parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("THEN")) {
+ ASTNode childNode = new IFActionNode();
+ for (int j = i; j < parseTokens.size(); j++) {
+ childNode.addToken(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";")) {
+ i = j;
+ break;
+ }
+ }
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ // match ELSIF condition
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("ELSIF")) {
+ ASTNode childNode = new ELSIFConditionNode();
+ for (int j = i; j < parseTokens.size(); j++) {
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("THEN")) {
+ i = j - 1;
+ break;
+ }
+ childNode.addToken(parseTokens.get(j));
+ }
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ // match ELSIF action
+ else if (currentNode instanceof ELSIFConditionNode && parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("THEN")) {
+ ASTNode childNode = new ELSIFActionNode();
+ for (int j = i; j < parseTokens.size(); j++) {
+ childNode.addToken(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";")) {
+ i = j;
+ break;
+ }
+ }
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ // match ELSE
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("ELSE")) {
+ ASTNode childNode = new ELSENode();
+ for (int j = i; j < parseTokens.size(); j++) {
+ childNode.addToken(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";")) {
+ i = j;
+ break;
+ }
+ }
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ //match end if;
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("END")) {
+ ASTNode childNode = new EndIFNode();
+ for (int j = i; j < parseTokens.size(); j++) {
+ childNode.addToken(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";")) {
+ i = j;
+ break;
+ }
+ }
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.EOF)) {
+ break;
+ }
+ else {
+ try {
+ throw new ParseFailedException("Parse failed!--" + parseTokens.get(i).getValue());
+ }
+ catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ return root;
+ }
+
+
+ /**
+ * CASE WHEN expr THEN expr [ELSE expr] END
+ * @param parseTokens should start with CASE
+ */
+ public static ASTNode parseCaseWhen(List parseTokens) {
+ List tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(0));
+
+ try {
+ tokens.add(parseTokens.get(1));
+ }
+ catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ int currentIndex = 2;
+ for (int i = currentIndex; i < parseTokens.size(); i++) {
+ if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("THEN")) {
+ currentIndex = i;
+ break;
+ }
+ tokens.add(parseTokens.get(i));
+ }
+ ASTNode root = new CaseConditionNode(tokens);
+ ASTNode currentNode = root;
+
+ tokens = new ArrayList<>();
+ for (int i = currentIndex; i < parseTokens.size(); i++) {
+ if ( (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("ELSE"))
+ || (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("END")) ) {
+ currentIndex = i;
+ break;
+ }
+ tokens.add(parseTokens.get(i));
+ }
+ ASTNode childNode = new CaseThenNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+
+ tokens = new ArrayList<>();
+ for (int i = currentIndex; i < parseTokens.size(); i++) {
+ if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("ELSE")) {
+ for (int j = i; j < parseTokens.size(); j++) {
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("END")) {
+ childNode = new CaseElseNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ i = j - 1;
+ break;
+ }
+ tokens.add(parseTokens.get(j));
+ }
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("END")) {
+ tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(i));
+ childNode = new CaseEndNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ break;
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.EOF)) {
+ break;
+ }
+ else {
+ try {
+ throw new ParseFailedException("Parse failed!--" + parseTokens.get(i));
+ }
+ catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ return root;
+ }
+
+ /**
+ * Loop_clauses
+ * 1:LOOP
+ * --
+ * EXIT WHEN condition;
+ * END LOOP;
+ *
+ * 2:WHILE condition LOOP
+ * --
+ * END LOOP;
+ *
+ * 3:FOR counter IN start..stop LOOP
+ * --
+ * END LOOP;
+ *
+ * @param parseTokens should start with LOOP | WHILE | FOR
+ */
+ public static ASTNode parseLoop(List parseTokens) {
+ ASTNode root = null;
+ ASTNode currentNode = null;
+ for (int i = 0; i < parseTokens.size(); i++) {
+ //match LOOP
+ if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("LOOP")) {
+ root = new LoopNode();
+ root.addToken(parseTokens.get(i));
+ currentNode = root;
+ }
+ // match WHILE condition LOOP
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("WHILE")) {
+ root = new WhileNode();
+ for (int j = i; j < parseTokens.size(); j++) {
+ root.addToken(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equals("LOOP")) {
+ i = j;
+ break;
+ }
+ }
+ currentNode = root;
+
+ }
+ // match FOR counter IN start..stop LOOP
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("FOR")) {
+ root = new ForNode();
+ for (int j = i; j < parseTokens.size(); j++) {
+ root.addToken(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equals("LOOP")) {
+ i = j;
+ break;
+ }
+ }
+ currentNode = root;
+ }
+ // match END LOOP;
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("END")) {
+ ASTNode childNode = new LoopEndNode();
+ for (int j = i; j < parseTokens.size(); j++) {
+ childNode.addToken(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";")) {
+ i = j;
+ break;
+ }
+ }
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ // match EXIT condition;
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("EXIT")) {
+ ASTNode childNode = new LoopExitNode();
+ for (int j = i; j < parseTokens.size(); j++) {
+ childNode.addToken(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";")) {
+ i = j;
+ break;
+ }
+ }
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ //match LOOP BODY
+ else if (
+ (currentNode == root && root instanceof LoopNode)
+ || (currentNode == root && root instanceof WhileNode)
+ || (currentNode == root && root instanceof ForNode)
+ ) {
+ ASTNode childNode = new LoopBodyNode();
+ for (int j = i; j < parseTokens.size(); j++) {
+ if (
+ parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equals("EXIT")
+ || parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equals("END")
+ ) {
+ i = j - 1;
+ break;
+ }
+ childNode.addToken(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";")) {
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ childNode = new LoopBodyNode();
+ }
+ }
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.EOF)) {
+ break;
+ }
+ else {
+ try {
+ throw new ParseFailedException("Parse failed!--" + parseTokens.get(i));
+ }
+ catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ return root;
+ }
+
+ /**
+ * Exception
+ * For example: EXCEPTION
+ * -- custom exception
+ * WHEN e_custom_exception THEN
+ * DBMS_OUTPUT.PUT_LINE('Caught an exception: Custom exception raised');
+ * -- divide by zero
+ * WHEN ZERO_DIVIDE THEN
+ * DBMS_OUTPUT.PUT_LINE('Caught an exception: Division by zero');
+ * -- invalid number
+ * WHEN INVALID_NUMBER THEN
+ * DBMS_OUTPUT.PUT_LINE('Caught an exception: Invalid number');
+ * -- other exceptions
+ * WHEN OTHERS THEN
+ * DBMS_OUTPUT.PUT_LINE('Caught an exception: ' || SQLERRM);
+ * @param parseTokens should start with Exception keyword
+ * @return ASTNode will not contain 'END'
+ */
+ public static ASTNode parseException(List parseTokens) {
+ ASTNode root = new ExceptionNode();
+ root.addToken(parseTokens.get(0));
+ ASTNode currentNode = root;
+ for (int i = 1; i < parseTokens.size(); i++) {
+ // match exception type
+ if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("WHEN")) {
+ if (i + 1 < parseTokens.size() && parseTokens.get(i + 1).hasType(Token.TokenType.IDENTIFIER)) {
+ ASTNode childNode = new CustomExceptionNode();
+ for (int j = i; j < parseTokens.size(); j++) {
+ childNode.addToken(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("THEN")) {
+ i = j;
+ break;
+ }
+ }
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else if (i + 1 < parseTokens.size() && parseTokens.get(i + 1).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i + 1).getValue().equalsIgnoreCase("ZERO_DIVIDE")) {
+ ASTNode childNode = new Zero_divideNode();
+ for (int j = i; j < parseTokens.size(); j++) {
+ childNode.addToken(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("THEN")) {
+ i = j;
+ break;
+ }
+ }
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else if (i + 1 < parseTokens.size() && parseTokens.get(i + 1).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i + 1).getValue().equalsIgnoreCase("INVALID_NUMBER")) {
+ ASTNode childNode = new Invalid_numberNode();
+ for (int j = i; j < parseTokens.size(); j++) {
+ childNode.addToken(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("THEN")) {
+ i = j;
+ break;
+ }
+ }
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else if (i + 1 < parseTokens.size() && parseTokens.get(i + 1).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i + 1).getValue().equalsIgnoreCase("OTHERS")) {
+ ASTNode childNode = new OtherExceptionNode();
+ for (int j = i; j < parseTokens.size(); j++) {
+ childNode.addToken(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("THEN")) {
+ i = j;
+ break;
+ }
+ }
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else {
+ try {
+ throw new ParseFailedException("Parse failed:There exists syntex error in the input sql!");
+ }
+ catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("END")) {
+ ASTNode childNode = new ExceptionEndNode();
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ break;
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.EOF)) {
+ if (!(currentNode instanceof ExceptionEndNode)) {
+ ASTNode childNode = new ExceptionEndNode();
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else {
+ break;
+ }
+ }
+ // match exception action
+ else {
+ ASTNode childNode = new ExceptionActionNode();
+ for (int j = i; j < parseTokens.size(); j++) {
+ childNode.addToken(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";")) {
+ i = j;
+ break;
+ }
+ }
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ }
+
+ return root;
+ }
+
+ /**
+ * JOIN clause
+ * For example: table1 t1 JOIN table2 t2 ON|USING t1.id = t2.id
+ * @param parseTokens should start with _table
+ */
+ public static ASTNode parseJoin(List parseTokens) {
+ List tokens = new ArrayList<>();
+ int index = 0;
+ boolean parseState = false;
+ ASTNode currentNode = null;
+ ASTNode root = null;
+ // match table 1
+ for (int i = index; i < parseTokens.size(); i++) {
+ if (
+ (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("JOIN"))
+ || (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("INNER JOIN"))
+ || (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("LEFT JOIN"))
+ || (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("RIGHT JOIN"))
+ || (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("FULL JOIN"))
+ || (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("LEFT OUTER JOIN"))
+ || (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("RIGHT OUTER JOIN"))
+ || (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("FULL OUTER JOIN"))
+ || (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("CROSS JOIN"))
+ ) {
+ index = i;
+ parseState = true;
+ break;
+ }
+ tokens.add(parseTokens.get(i));
+ }
+ if (parseState) {
+ root = new JoinSourceTabNode(tokens);
+ currentNode = root;
+ }
+ else {
+ try {
+ throw new ParseFailedException("Fail to parse:" + parseTokens.get(index));
+ }
+ catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ // match join type
+ if (parseState) {
+ tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(index));
+ index++;
+ ASTNode childNode = new JoinTypeNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else {
+ try {
+ throw new ParseFailedException("Fail to parse:" + parseTokens.get(index));
+ }
+ catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ // match table 2
+ tokens = new ArrayList<>();
+ parseState = false;
+ for (int i = index; i < parseTokens.size(); i++) {
+ if (
+ (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("ON"))
+ || (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("USING"))
+ || (parseTokens.get(i).hasType(Token.TokenType.SYMBOL) && parseTokens.get(i).getValue().equalsIgnoreCase(";"))
+ || (parseTokens.get(i).hasType(Token.TokenType.KEYWORD))
+ ) {
+ index = i;
+ parseState = true;
+ break;
+ }
+ tokens.add(parseTokens.get(i));
+ }
+ if (parseState) {
+ ASTNode childNode = new JoinTargetTabNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else {
+ ASTNode childNode = new JoinTargetTabNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+
+ // match join condition
+ if (parseState) {
+ // match end
+ if (parseTokens.get(index).hasType(Token.TokenType.SYMBOL) && parseTokens.get(index).getValue().equalsIgnoreCase(";")) {
+ tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(index));
+ ASTNode childNode = new JoinEndNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ // match end with keyword
+ else if (parseTokens.get(index).hasType(Token.TokenType.KEYWORD) && !parseTokens.get(index).getValue().equalsIgnoreCase("ON") && !parseTokens.get(index).getValue().equalsIgnoreCase("USING")) {
+ ASTNode childNode = new JoinEndNode();
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else {
+ parseState = false;
+ JoinConditionNode joinConditionNode = new JoinConditionNode();
+ joinConditionNode.setKeyword(parseTokens.get(index).getValue());
+ index++;
+ tokens = new ArrayList<>();
+ for (int i = index; i < parseTokens.size(); i++) {
+ if (
+ parseTokens.get(i).hasType(Token.TokenType.KEYWORD)
+ || (parseTokens.get(i).hasType(Token.TokenType.SYMBOL) && parseTokens.get(i).getValue().equalsIgnoreCase(";"))
+ )
+ {
+ index = i;
+ parseState = true;
+ break;
+ }
+ tokens.add(parseTokens.get(i));
+ }
+ if (parseState) {
+ joinConditionNode.setTokens(tokens);
+ currentNode.addChild(joinConditionNode);
+ currentNode = joinConditionNode;
+ // match end
+ if (parseTokens.get(index).hasType(Token.TokenType.SYMBOL) && parseTokens.get(index).getValue().equalsIgnoreCase(";")) {
+ tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(index));
+ ASTNode childNode = new JoinEndNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ // match end with keyword
+ else if (parseTokens.get(index).hasType(Token.TokenType.KEYWORD)) {
+ ASTNode childNode = new JoinEndNode();
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ }
+ else {
+ joinConditionNode.setTokens(tokens);
+ currentNode.addChild(joinConditionNode);
+ currentNode = joinConditionNode;
+ ASTNode childNode = new JoinEndNode();
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ }
+ }
+ else {
+ ASTNode childNode = new JoinEndNode();
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+
+ return root;
+ }
+
+ /**
+ * Update
+ * For example: UPDATE table_name SET column1 = value1, column2 = value2, ... WHERE condition;
+ * | UPDATE view_name SET column1 = value1, column2 = value2, ... WHERE condition;
+ */
+ private ASTNode parseUpdate(List parseTokens) {
+ List tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(0));
+ ASTNode root = new UpdateNode(tokens);
+ ASTNode currentNode = root;
+ for (int i = 1; i < parseTokens.size(); i++) {
+ if (i == 1 && parseTokens.get(i).hasType(Token.TokenType.IDENTIFIER)) {
+ // match update object
+ tokens = new ArrayList<>();
+ for (int j = i; j < parseTokens.size(); j++) {
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("SET")) {
+ i = j - 1;
+ break;
+ }
+ tokens.add(parseTokens.get(j));
+ }
+ if (tokens.contains(new Token(Token.TokenType.KEYWORD, "JOIN"))) {
+ ASTNode joinRootNode = parseJoin(tokens);
+ currentNode.addChild(joinRootNode);
+ currentNode = joinRootNode.getDeepestChild();
+ }
+ else {
+ ASTNode childNode = new UpdateObjNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("SET")) {
+ // match SET
+ tokens = new ArrayList<>();
+ for (int j = i; j < parseTokens.size(); j++) {
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("WHERE")) {
+ i = j - 1;
+ break;
+ }
+ tokens.add(parseTokens.get(j));
+ }
+ ASTNode childNode = new UpdateSetNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("WHERE")) {
+ // match WHERE
+ tokens = new ArrayList<>();
+ for (int j = i; j < parseTokens.size(); j++) {
+ if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equalsIgnoreCase(";")) {
+ i = j - 1;
+ break;
+ }
+ tokens.add(parseTokens.get(j));
+ }
+ ASTNode childNode = new UpdateWhereNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.SYMBOL) && parseTokens.get(i).getValue().equalsIgnoreCase(";")) {
+ tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(i));
+ ASTNode childNode = new UpdateEndNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.EOF)) {
+ break;
+ }
+ else {
+ try {
+ throw new ParseFailedException("Parse failed:" + parseTokens.get(i));
+ }
+ catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ return root;
+ }
+
+ /**
+ * Delete
+ * For example:
+ * DELETE FROM employees e
+ * WHERE e.department_id IN (
+ * SELECT d.department_id
+ * FROM departments d
+ * WHERE d.department_name = 'Sales'
+ * );
+ */
+ private ASTNode parseDelete(List parseTokens) {
+ List tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(0));
+ try{
+ tokens.add(parseTokens.get(1));
+ } catch (IndexOutOfBoundsException e) {
+ e.printStackTrace();
+ }
+ ASTNode root = new DeleteNode(tokens);
+ ASTNode currentNode = root;
+ for (int i = 2; i < parseTokens.size(); i++) {
+ // match delete object
+ if (i == 2 && parseTokens.get(i).hasType(Token.TokenType.IDENTIFIER)) {
+ tokens = new ArrayList<>();
+ for (int j = i; j < parseTokens.size(); j++) {
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("WHERE")) {
+ i = j - 1;
+ break;
+ }
+ tokens.add(parseTokens.get(j));
+ }
+ ASTNode childNode = new DeleteObjNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ // match WHERE condition
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("WHERE")) {
+ tokens = new ArrayList<>();
+ for (int j = i; j < parseTokens.size(); j++) {
+ if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equalsIgnoreCase(";")) {
+ i = j - 1;
+ break;
+ }
+ tokens.add(parseTokens.get(j));
+ }
+ ASTNode childNode = new DeleteConditionNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.SYMBOL) && parseTokens.get(i).getValue().equals(";")) {
+ tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(i));
+ ASTNode childNode = new DeleteEndNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.EOF)) {
+ break;
+ }
+ else {
+ try {
+ throw new ParseFailedException("Parse failed:" + parseTokens.get(i));
+ }
+ catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ return root;
+ }
+
+ /**
+ * Alter table
+ * Grammar: ALTER TABLE table_name action;
+ * action = ADD column_name data_type [constraint]
+ * | DROP COLUMN column_name
+ * | MODIFY column_name data_type
+ * | 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
+ */
+ private ASTNode parseAlterTable(List parseTokens) {
+ List tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(0));
+ try{
+ tokens.add(parseTokens.get(1));
+ } catch (IndexOutOfBoundsException e) {
+ e.printStackTrace();
+ }
+ ASTNode root = new AlterNode(tokens);
+ ASTNode currentNode = root;
+ for (int i = 2; i < parseTokens.size(); i++) {
+ // match table
+ if (i == 2 && parseTokens.get(i).hasType(Token.TokenType.IDENTIFIER)) {
+ tokens = new ArrayList<>();
+ for (int j = i; j < parseTokens.size(); j++) {
+ if (
+ (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("ADD"))
+ || (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("DROP"))
+ || (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("MODIFY"))
+ || (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("RENAME"))
+ ) {
+ i = j - 1;
+ break;
+ }
+ tokens.add(parseTokens.get(j));
+ }
+ ASTNode childNode = new AlterObjNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("ADD")) {
+ // add column
+ if (i + 1 < parseTokens.size() && parseTokens.get(i + 1).hasType(Token.TokenType.IDENTIFIER)) {
+ tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(i));
+ i++;
+ boolean state = false;
+ AlterAddColumnNode child = new AlterAddColumnNode();
+ child.setName(parseTokens.get(i));
+ tokens.add(parseTokens.get(i));
+ List constraint = new ArrayList<>();
+ for (int j = i + 1; j < parseTokens.size(); j++) {
+ state = false;
+ if (j == i + 1) {
+ child.setType(parseTokens.get(j));
+ }
+ // Check () or REFERENCES other_table(other_column)
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) &&
+ (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));
+ constraint.add(parseTokens.get(k));
+ if (parseTokens.get(k).getValue().equals("(")) {
+ stack.push("(");
+ for (int t = k + 1; t < parseTokens.size(); t++) {
+ tokens.add(parseTokens.get(t));
+ constraint.add(parseTokens.get(t));
+ if (parseTokens.get(t).getValue().equals("(")) {
+ stack.push("(");
+ }
+ else if (parseTokens.get(t).getValue().equals(")")) {
+ stack.pop();
+ if (stack.empty()) {
+ j = t;
+ state = true;
+ break;
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+ if ((parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";")) ) {
+ i = j - 1;
+ break;
+ }
+ if (!state)
+ tokens.add(parseTokens.get(j));
+ if (!state && j != i + 1) {
+ constraint.add(parseTokens.get(j));
+ }
+ }
+ child.setTokens(tokens);
+ child.setConstraint(constraint);
+ currentNode.addChild(child);
+ currentNode = child;
+ }
+ // add constraint
+ else if (i + 1 < parseTokens.size() && parseTokens.get(i + 1).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i + 1).getValue().equalsIgnoreCase("CONSTRAINT")) {
+ tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(i));
+ i++;
+ tokens.add(parseTokens.get(i));
+ for (int j = i + 1; j < parseTokens.size(); j++) {
+ /**
+ * CONSTRAINT pk_example PRIMARY KEY (column1, column2)
+ * CONSTRAINT uk_example UNIQUE (column1)
+ * CONSTRAINT fk_example FOREIGN KEY (column1) REFERENCES other_table(column2)
+ * CONSTRAINT chk_example CHECK (column1 > 0)
+ */
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) &&
+ (parseTokens.get(j).getValue().equalsIgnoreCase("UNIQUE")
+ || parseTokens.get(j).getValue().equalsIgnoreCase("CHECK")
+ || parseTokens.get(j).getValue().equalsIgnoreCase("PRIMARY KEY")
+ || parseTokens.get(j).getValue().equalsIgnoreCase("FOREIGN KEY")
+ || parseTokens.get(j).getValue().equalsIgnoreCase("REFERENCES"))) {
+ tokens.add(parseTokens.get(j));
+ Stack stack = new Stack<>();
+ for (int k = j + 1; k < parseTokens.size(); k++) {
+ tokens.add(parseTokens.get(k));
+ if (parseTokens.get(k).getValue().equals("(")) {
+ stack.push("(");
+ for (int t = k + 1; t < parseTokens.size(); t++) {
+ tokens.add(parseTokens.get(t));
+ if (parseTokens.get(t).getValue().equals("(")) {
+ stack.push("(");
+ }
+ else if (parseTokens.get(t).getValue().equals(")")) {
+ stack.pop();
+ if (stack.empty()) {
+ i = t;
+ j = t;
+ break;
+ }
+ }
+ }
+ break;
+ }
+ }
+ continue;
+ }
+ if ((parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";"))) {
+ i = j - 1;
+ break;
+ }
+ tokens.add(parseTokens.get(j));
+ }
+ ASTNode childNode = new AlterAddConstraintNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ // error sql
+ else {
+ try {
+ throw new ParseFailedException("Parse failed:There exists syntex error in the input sql!");
+ }
+ catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("DROP")) {
+ if (i + 1 < parseTokens.size() && parseTokens.get(i + 1).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i + 1).getValue().equalsIgnoreCase("COLUMN")) {
+ tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(i));
+ for (int j = i + 1; j < parseTokens.size(); j++) {
+ if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equalsIgnoreCase(";")) {
+ i = j - 1;
+ break;
+ }
+ tokens.add(parseTokens.get(j));
+ }
+ ASTNode childNode = new AlterDropColumnNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else if (i + 1 < parseTokens.size() && parseTokens.get(i + 1).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i + 1).getValue().equalsIgnoreCase("CONSTRAINT")) {
+ tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(i));
+ for (int j = i + 1; j < parseTokens.size(); j++) {
+ if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equalsIgnoreCase(";")) {
+ i = j - 1;
+ break;
+ }
+ tokens.add(parseTokens.get(j));
+ }
+ ASTNode childNode = new AlterDropConstraintNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else {
+ try {
+ throw new ParseFailedException("Parse failed:There exists syntex error in the input sql!");
+ }
+ catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("MODIFY")) {
+ tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(i));
+ AlterModifyColumnNode childNode = new AlterModifyColumnNode();
+ for (int j = i + 1; j < parseTokens.size(); j++) {
+ if (j == i + 1) {
+ childNode.setName(parseTokens.get(j));
+ }
+ if (j == i + 2) {
+ childNode.setType(parseTokens.get(j));
+ }
+ if (j > i + 3) {
+ try {
+ throw new ParseFailedException("Parse failed:There exists syntex error in the input sql!");
+ }
+ catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ break;
+ }
+ if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equalsIgnoreCase(";")) {
+ i = j - 1;
+ break;
+ }
+ tokens.add(parseTokens.get(j));
+ }
+ childNode.setTokens(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("RENAME")) {
+ if (i + 1 < parseTokens.size() && parseTokens.get(i + 1).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i + 1).getValue().equalsIgnoreCase("COLUMN")) {
+ tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(i));
+ for (int j = i + 1; j < parseTokens.size(); j++) {
+ if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equalsIgnoreCase(";")) {
+ i = j - 1;
+ break;
+ }
+ tokens.add(parseTokens.get(j));
+ }
+ ASTNode childNode = new AlterRenameColumnNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ 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++) {
+ if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equalsIgnoreCase(";")) {
+ i = j - 1;
+ break;
+ }
+ tokens.add(parseTokens.get(j));
+ }
+ ASTNode childNode = new AlterRenameTableNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else {
+ try {
+ throw new ParseFailedException("Parse failed:There exists syntex error in the input sql!");
+ }
+ catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.SYMBOL) && parseTokens.get(i).getValue().equals(";")) {
+ tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(i));
+ ASTNode childNode = new AlterEndNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.EOF)) {
+ break;
+ }
+ else {
+ try {
+ throw new ParseFailedException("Parse failed:" + parseTokens.get(i));
+ }
+ catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ return root;
+ }
+
+ /**
+ * Create view
+ * Grammar: CREATE [OR REPLACE] VIEW view_name [(column_name [, column_name]...)] AS SELECT_statement;
+ * Example: CREATE OR REPLACE VIEW employee_details (full_name, pay)
+ * AS SELECT first_name, last_name, salary FROM employees;
+ */
+ private ASTNode parseCreateView(List parseTokens) {
+ List tokens = new ArrayList<>();
+ ASTNode root = new ViewCreateNode();
+ ASTNode currentNode = root;
+ for (int i = 0; i < parseTokens.size(); i++) {
+ if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("CREATE")) {
+ tokens.add(parseTokens.get(i));
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("OR")) {
+ tokens.add(parseTokens.get(i));
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("REPLACE")) {
+ tokens.add(parseTokens.get(i));
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("VIEW")) {
+ tokens.add(parseTokens.get(i));
+ root.setTokens(tokens);
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.IDENTIFIER) && currentNode instanceof ViewCreateNode) {
+ tokens = new ArrayList<>();
+ for (int j = i; j < parseTokens.size(); j++) {
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("AS")) {
+ i = j - 1;
+ break;
+ }
+ tokens.add(parseTokens.get(j));
+ }
+ ASTNode childNode = new ViewNameNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("AS")) {
+ tokens = new ArrayList<>();
+ tokens.add(parseTokens.get(i));
+ ASTNode childNode = new ViewTargetNode(tokens);
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ tokens = parseTokens.subList(i + 1, parseTokens.size());
+ ASTNode selectRootNode = parseSelect(tokens);
+ currentNode.addChild(selectRootNode);
+ currentNode = selectRootNode.getDeepestChild();
+ ASTNode viewEndNode = new ViewEndNode();
+ currentNode.addChild(viewEndNode);
+ currentNode = viewEndNode;
+ break;
+ }
+ else {
+ try {
+ throw new ParseFailedException("Failed to parse:" + parseTokens.get(i));
+ }
+ catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ return root;
+ }
+
+ /**
+ * Create PROCEDURE
+ * Grammar: CREATE [OR REPLACE] PROCEDURE procedure_name ([parameter_list])
+ * IS [LOCAL DECLARATIONS]
+ * BEGIN
+ * -- PL/SQL statements
+ * [EXCEPTION]
+ * -- Exception handling
+ * END [procedure_name];
+ * Example: CREATE OR REPLACE PROCEDURE update_salary(
+ * employee_id IN NUMBER,
+ * new_salary IN OUT NUMBER
+ * ) IS
+ * BEGIN
+ * IF new_salary < 3000 THEN
+ * new_salary := new_salary * 1.1;
+ * ELSE
+ * new_salary := new_salary * 1.05;
+ * END IF;
+ * END update_salary;
+ * /
+ */
+ private ASTNode parseProcedure(List parseTokens) {
+ ASTNode root = new ProcedureNode(new ArrayList<>());
+ ASTNode currentNode = root;
+ for (int i = 0; i < parseTokens.size(); i++) {
+ // match CREATE PROCEDURE
+ if (root.getTokens().isEmpty()) {
+ for (int j = i; j < parseTokens.size(); j++) {
+ root.addToken(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("PROCEDURE")) {
+ i = j;
+ break;
+ }
+ }
+ }
+ // match procedure name
+ else if (currentNode == root && parseTokens.get(i).hasType(Token.TokenType.IDENTIFIER)) {
+ ASTNode childNode = new ProcedureObjNode();
+ childNode.addToken(parseTokens.get(i));
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ i++;
+ if (parseTokens.get(i).hasType(Token.TokenType.SYMBOL) && parseTokens.get(i).getValue().equals(")")) {
+ i++;
+ }
+ }
+ // match parameter list
+ else if (currentNode instanceof ProcedureObjNode && parseTokens.get(i).hasType(Token.TokenType.IDENTIFIER)) {
+ i++;
+ for (int ii = i; ii < parseTokens.size(); ii++) {
+ if (parseTokens.get(ii).hasType(Token.TokenType.KEYWORD) && parseTokens.get(ii).getValue().equalsIgnoreCase("IS")) {
+ i = ii - 1;
+ break;
+ }
+ List tokens = new ArrayList<>();
+ ProcedureColumnNode child = new ProcedureColumnNode();
+ child.setName(parseTokens.get(ii));
+ tokens.add(parseTokens.get(ii));
+ List constraint = new ArrayList<>();
+ boolean typeMatch = false;
+ int typeIdx = -1;
+ for (int j = ii + 1; j < parseTokens.size(); j++) {
+ if (!typeMatch && !(parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && (parseTokens.get(j).getValue().equalsIgnoreCase("IN") || parseTokens.get(j).getValue().equalsIgnoreCase("OUT"))))
+ {
+ child.setType(parseTokens.get(j));
+ typeMatch = true;
+ typeIdx = j;
+ }
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && (parseTokens.get(j).getValue().equalsIgnoreCase("IN") || parseTokens.get(j).getValue().equalsIgnoreCase("OUT"))) {
+ child.addInOut(parseTokens.get(j));
+ }
+ // Check () or REFERENCES other_table(other_column)
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) &&
+ (parseTokens.get(j).getValue().equalsIgnoreCase("REFERENCES")
+ || parseTokens.get(j).getValue().equalsIgnoreCase("CHECK"))) {
+ tokens.add(parseTokens.get(j));
+ if (!(parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && (parseTokens.get(j).getValue().equalsIgnoreCase("IN") || parseTokens.get(j).getValue().equalsIgnoreCase("OUT"))))
+ constraint.add(parseTokens.get(j));
+ Stack stack = new Stack<>();
+ for (int k = j + 1; k < parseTokens.size(); k++) {
+ tokens.add(parseTokens.get(k));
+ if (!(parseTokens.get(k).hasType(Token.TokenType.KEYWORD) && (parseTokens.get(k).getValue().equalsIgnoreCase("IN") || parseTokens.get(k).getValue().equalsIgnoreCase("OUT"))))
+ constraint.add(parseTokens.get(k));
+ if (parseTokens.get(k).getValue().equals("(")) {
+ stack.push("(");
+ for (int t = k + 1; t < parseTokens.size(); t++) {
+ tokens.add(parseTokens.get(t));
+ if (!(parseTokens.get(t).hasType(Token.TokenType.KEYWORD) && (parseTokens.get(t).getValue().equalsIgnoreCase("IN") || parseTokens.get(t).getValue().equalsIgnoreCase("OUT"))))
+ constraint.add(parseTokens.get(t));
+ if (parseTokens.get(t).getValue().equals("(")) {
+ stack.push("(");
+ } else if (parseTokens.get(t).getValue().equals(")")) {
+ stack.pop();
+ if (stack.empty()) {
+ ii = t;
+ break;
+ }
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+ if ((parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(",")) ||
+ (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(")"))) {
+ ii = j;
+ break;
+ }
+ tokens.add(parseTokens.get(j));
+ if (typeMatch && j != typeIdx) {
+ if (!(parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && (parseTokens.get(j).getValue().equalsIgnoreCase("IN") || parseTokens.get(j).getValue().equalsIgnoreCase("OUT"))))
+ constraint.add(parseTokens.get(j));
+ }
+ }
+ child.setTokens(tokens);
+ child.setConstraint(constraint);
+ currentNode.addChild(child);
+ currentNode = child;
+ }
+ }
+ // match procedure return definition
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("IS")) {
+ ProcedureRetDefNode childNode = new ProcedureRetDefNode();
+ for (int j = i; j < parseTokens.size(); j++) {
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("BEGIN")) {
+ i = j - 1;
+ break;
+ }
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && !parseTokens.get(j).getValue().equalsIgnoreCase("IS")) {
+ childNode.setType(parseTokens.get(j));
+ }
+ childNode.addToken(parseTokens.get(j));
+ }
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ // match declare
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("DECLARE")) {
+ ASTNode childNode = new ProcedureDeclareNode();
+ childNode.addToken(parseTokens.get(i));
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ // match declare content
+ else if (currentNode instanceof TriggerDeclareNode && parseTokens.get(i).hasType(Token.TokenType.IDENTIFIER)) {
+ ProcedureDeclareContentNode childNode = new ProcedureDeclareContentNode();
+ for (int j = i; j < parseTokens.size(); j++) {
+ childNode.addToken(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";")) {
+ i = j;
+ break;
+ }
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && !parseTokens.get(j).getValue().equalsIgnoreCase(":=")) {
+ childNode.setType(parseTokens.get(j));
+ }
+ }
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else if (currentNode instanceof TriggerDeclareContentNode && parseTokens.get(i).hasType(Token.TokenType.IDENTIFIER)) {
+ ProcedureDeclareContentNode childNode = new ProcedureDeclareContentNode();
+ for (int j = i; j < parseTokens.size(); j++) {
+ childNode.addToken(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";")) {
+ i = j;
+ break;
+ }
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && !parseTokens.get(j).getValue().equalsIgnoreCase(":=")) {
+ childNode.setType(parseTokens.get(j));
+ }
+ }
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ // match procedure begin
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("BEGIN")) {
+ ASTNode childNode = new ProcedureBeginNode();
+ childNode.addToken(parseTokens.get(i));
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ // match procedure body
+ else if (currentNode instanceof ProcedureBeginNode) {
+ for (int ii = i; ii < parseTokens.size(); ii++) {
+ if (parseTokens.get(ii).hasType(Token.TokenType.KEYWORD) && parseTokens.get(ii).getValue().equalsIgnoreCase("END")) {
+ i = ii - 1;
+ break;
+ }
+ else if (parseTokens.get(ii).hasType(Token.TokenType.KEYWORD) && parseTokens.get(ii).getValue().equalsIgnoreCase("EXCEPTION")) {
+ i = ii - 1;
+ break;
+ }
+ else if (parseTokens.get(ii).hasType(Token.TokenType.KEYWORD) && parseTokens.get(ii).getValue().equalsIgnoreCase("IF")) {
+ int index = -1;
+ for (int j = ii; j < parseTokens.size(); j++) {
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("END")
+ && j + 1 < parseTokens.size() && parseTokens.get(j + 1).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j + 1).getValue().equalsIgnoreCase("IF")
+ && j + 2 < parseTokens.size() && parseTokens.get(j + 2).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j + 2).getValue().equals(";") ) {
+ index = j + 2;
+ break;
+ }
+ }
+ if (index == -1) {
+ try {
+ throw new ParseFailedException("There exists syntax error and no END if block is found!");
+ } catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ }
+ else {
+ ASTNode childNode = parseIFELSE(parseTokens.subList(ii, index + 1));
+ currentNode.addChild(childNode);
+ currentNode = childNode.getDeepestChild();
+ ii = index;
+ }
+ }
+ else {
+ ASTNode childNode = new ProcedurePLStatementNode();
+ for (int j = ii; j < parseTokens.size(); j++) {
+ childNode.addToken(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";")) {
+ ii = j;
+ break;
+ }
+ }
+ ASTNode bodystatementNode = parseTokens(childNode.getTokens());
+ if (bodystatementNode != null) {
+ currentNode.addChild(bodystatementNode);
+ currentNode = bodystatementNode.getDeepestChild();
+ ASTNode bodystatementEndNode = new ProcedurePLStatementNode();
+ currentNode.addChild(bodystatementEndNode);
+ currentNode = bodystatementEndNode;
+ }
+ else {
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ }
+ }
+ }
+ // match exception
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("EXCEPTION")) {
+ int index = -1;
+ for (int j = i; j < parseTokens.size(); j++) {
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("END")) {
+ index = j;
+ break;
+ }
+ }
+ if (index == -1) {
+ try {
+ throw new ParseFailedException("There exists syntax error and no END block is found!");
+ } catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ }
+ ASTNode childNode = parseException(parseTokens.subList(i, index + 1));
+ currentNode.addChild(childNode);
+ currentNode = childNode.getDeepestChild();
+ childNode = new ProcedureEndNode();
+ for (int j = index; j < parseTokens.size(); j++) {
+ childNode.addToken(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";")) {
+ i = j;
+ break;
+ }
+ }
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ break;
+ }
+ // match procedure end
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("END")) {
+ ASTNode childNode = new ProcedureEndNode();
+ for (int j = i; j < parseTokens.size(); j++) {
+ childNode.addToken(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";")) {
+ i = j;
+ break;
+ }
+ }
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ break;
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.EOF)) {
+ break;
+ }
+ else {
+ try {
+ throw new ParseFailedException("Failed to parse:" + parseTokens.get(i));
+ }
+ catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ }
+
+ return root;
+ }
+
+ /**
+ * Create FUNCTION
+ * Grammar: CREATE OR REPLACE FUNCTION function_name (
+ * parameter1 [IN | OUT] datatype1 ,
+ * parameter2 [IN | OUT] datatype2 ,
+ * ...
+ * ) RETURN return_datatype IS
+ * BEGIN
+ * -- function body
+ * RETURN result;
+ * END;
+ * /
+ * Example: CREATE OR REPLACE FUNCTION string_length (
+ * input_string VARCHAR2
+ * ) RETURN NUMBER IS
+ * BEGIN
+ * RETURN LENGTH(input_string);
+ * END;
+ * /
+ */
+ private ASTNode parseFunction(List parseTokens) {
+ ASTNode root = new FunctionNode();
+ ASTNode currentNode = root;
+ for (int i = 0; i < parseTokens.size(); i++) {
+ // CREATE [OR REPLACE] FUNCTION
+ if (root.getTokens().isEmpty()) {
+ for (int j = i; j < parseTokens.size(); j++) {
+ root.addToken(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("FUNCTION")) {
+ i = j;
+ break;
+ }
+ }
+ }
+ // match function name
+ else if (currentNode == root && parseTokens.get(i).hasType(Token.TokenType.IDENTIFIER)) {
+ ASTNode childNode = new FunctionNameNode();
+ childNode.addToken(parseTokens.get(i));
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ i++;
+ if (parseTokens.get(i).hasType(Token.TokenType.SYMBOL) && parseTokens.get(i).getValue().equals(")")) {
+ i++;
+ }
+ }
+ // match parameters
+ else if (currentNode instanceof FunctionNameNode && parseTokens.get(i).hasType(Token.TokenType.IDENTIFIER)) {
+ for (int ii = i; ii < parseTokens.size(); ii++) {
+ if (parseTokens.get(ii).hasType(Token.TokenType.KEYWORD) && parseTokens.get(ii).getValue().equalsIgnoreCase("RETURN")) {
+ i = ii - 1;
+ break;
+ }
+ List tokens = new ArrayList<>();
+ FunctionColumnNode child = new FunctionColumnNode();
+ child.setName(parseTokens.get(ii));
+ tokens.add(parseTokens.get(ii));
+ List constraint = new ArrayList<>();
+ boolean typeMatch = false;
+ int typeIdx = -1;
+ for (int j = ii + 1; j < parseTokens.size(); j++) {
+ if (!typeMatch && !(parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && (parseTokens.get(j).getValue().equalsIgnoreCase("IN") || parseTokens.get(j).getValue().equalsIgnoreCase("OUT"))))
+ {
+ child.setType(parseTokens.get(j));
+ typeMatch = true;
+ typeIdx = j;
+ }
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && (parseTokens.get(j).getValue().equalsIgnoreCase("IN") || parseTokens.get(j).getValue().equalsIgnoreCase("OUT"))) {
+ child.addInOut(parseTokens.get(j));
+ }
+ // Check () or REFERENCES other_table(other_column)
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) &&
+ (parseTokens.get(j).getValue().equalsIgnoreCase("REFERENCES")
+ || parseTokens.get(j).getValue().equalsIgnoreCase("CHECK"))) {
+ tokens.add(parseTokens.get(j));
+ if (!(parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && (parseTokens.get(j).getValue().equalsIgnoreCase("IN") || parseTokens.get(j).getValue().equalsIgnoreCase("OUT"))))
+ constraint.add(parseTokens.get(j));
+ Stack stack = new Stack<>();
+ for (int k = j + 1; k < parseTokens.size(); k++) {
+ tokens.add(parseTokens.get(k));
+ if (!(parseTokens.get(k).hasType(Token.TokenType.KEYWORD) && (parseTokens.get(k).getValue().equalsIgnoreCase("IN") || parseTokens.get(k).getValue().equalsIgnoreCase("OUT"))))
+ constraint.add(parseTokens.get(k));
+ if (parseTokens.get(k).getValue().equals("(")) {
+ stack.push("(");
+ for (int t = k + 1; t < parseTokens.size(); t++) {
+ tokens.add(parseTokens.get(t));
+ if (!(parseTokens.get(t).hasType(Token.TokenType.KEYWORD) && (parseTokens.get(t).getValue().equalsIgnoreCase("IN") || parseTokens.get(t).getValue().equalsIgnoreCase("OUT"))))
+ constraint.add(parseTokens.get(t));
+ if (parseTokens.get(t).getValue().equals("(")) {
+ stack.push("(");
+ } else if (parseTokens.get(t).getValue().equals(")")) {
+ stack.pop();
+ if (stack.empty()) {
+ ii = t;
+ break;
+ }
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+ if ((parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(",")) ||
+ (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(")"))) {
+ ii = j;
+ break;
+ }
+ tokens.add(parseTokens.get(j));
+ if (typeMatch && j != typeIdx) {
+ if (!(parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && (parseTokens.get(j).getValue().equalsIgnoreCase("IN") || parseTokens.get(j).getValue().equalsIgnoreCase("OUT"))))
+ constraint.add(parseTokens.get(j));
+ }
+ }
+ child.setTokens(tokens);
+ child.setConstraint(constraint);
+ currentNode.addChild(child);
+ currentNode = child;
+ }
+ }
+ // match return definition
+ else if ((currentNode instanceof FunctionColumnNode || currentNode instanceof FunctionNameNode) && parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("RETURN")) {
+ FunctionRetDefNode childNode = new FunctionRetDefNode();
+ for (int j = i; j < parseTokens.size(); j++) {
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("RETURN")) {
+ childNode.addToken(parseTokens.get(j));
+ }
+ else if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equals("IS")) {
+ childNode.addToken(parseTokens.get(j));
+ i = j;
+ break;
+ }
+ else {
+ childNode.addToken(parseTokens.get(j));
+ childNode.setType(parseTokens.get(j));
+ }
+ }
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ // match declare
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("DECLARE")) {
+ ASTNode childNode = new FunctionDeclareNode();
+ childNode.addToken(parseTokens.get(i));
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ // match declare content
+ else if (currentNode instanceof TriggerDeclareNode && parseTokens.get(i).hasType(Token.TokenType.IDENTIFIER)) {
+ FunctionDeclareContentNode childNode = new FunctionDeclareContentNode();
+ for (int j = i; j < parseTokens.size(); j++) {
+ childNode.addToken(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";")) {
+ i = j;
+ break;
+ }
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && !parseTokens.get(j).getValue().equalsIgnoreCase(":=")) {
+ childNode.setType(parseTokens.get(j));
+ }
+ }
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else if (currentNode instanceof TriggerDeclareContentNode && parseTokens.get(i).hasType(Token.TokenType.IDENTIFIER)) {
+ FunctionDeclareContentNode childNode = new FunctionDeclareContentNode();
+ for (int j = i; j < parseTokens.size(); j++) {
+ childNode.addToken(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";")) {
+ i = j;
+ break;
+ }
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && !parseTokens.get(j).getValue().equalsIgnoreCase(":=")) {
+ childNode.setType(parseTokens.get(j));
+ }
+ }
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ // match function begin
+ else if (currentNode instanceof FunctionRetDefNode && parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("BEGIN")) {
+ ASTNode childNode = new FunctionBeginNode();
+ childNode.addToken(parseTokens.get(i));
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ // match function body
+ else if (currentNode instanceof FunctionBeginNode) {
+ for (int ii = i; ii < parseTokens.size(); ii++) {
+ if (parseTokens.get(ii).hasType(Token.TokenType.KEYWORD) && parseTokens.get(ii).getValue().equalsIgnoreCase("END")) {
+ i = ii - 1;
+ break;
+ }
+ else if (parseTokens.get(ii).hasType(Token.TokenType.KEYWORD) && parseTokens.get(ii).getValue().equalsIgnoreCase("EXCEPTION")) {
+ i = ii - 1;
+ break;
+ }
+ else if (parseTokens.get(ii).hasType(Token.TokenType.KEYWORD) && parseTokens.get(ii).getValue().equalsIgnoreCase("IF")) {
+ int index = -1;
+ for (int j = ii; j < parseTokens.size(); j++) {
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("END")
+ && j + 1 < parseTokens.size() && parseTokens.get(j + 1).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j + 1).getValue().equalsIgnoreCase("IF")
+ && j + 2 < parseTokens.size() && parseTokens.get(j + 2).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j + 2).getValue().equals(";") ) {
+ index = j + 2;
+ break;
+ }
+ }
+ if (index == -1) {
+ try {
+ throw new ParseFailedException("There exists syntax error and no END if block is found!");
+ } catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ }
+ else {
+ ASTNode childNode = parseIFELSE(parseTokens.subList(ii, index + 1));
+ currentNode.addChild(childNode);
+ currentNode = childNode.getDeepestChild();
+ ii = index;
+ }
+ }
+ else if (parseTokens.get(ii).hasType(Token.TokenType.KEYWORD) && parseTokens.get(ii).getValue().equalsIgnoreCase("RETURN")) {
+ ASTNode childNode = new FunctionReturnNode();
+ for (int j = ii; j < parseTokens.size(); j++) {
+ childNode.addToken(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";")) {
+ ii = j;
+ break;
+ }
+ }
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else {
+ ASTNode childNode = new FunctionBodyNode();
+ for (int j = ii; j < parseTokens.size(); j++) {
+ childNode.addToken(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";")) {
+ ii = j;
+ break;
+ }
+ }
+ ASTNode bodystatementNode = parseTokens(childNode.getTokens());
+ if (bodystatementNode != null) {
+ currentNode.addChild(bodystatementNode);
+ currentNode = bodystatementNode.getDeepestChild();
+ ASTNode bodystatementEndNode = new FunctionBodyNode();
+ currentNode.addChild(bodystatementEndNode);
+ currentNode = bodystatementEndNode;
+ }
+ else {
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ }
+ }
+ }
+ // match exception
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("EXCEPTION")) {
+ int index = -1;
+ for (int j = i; j < parseTokens.size(); j++) {
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("END")) {
+ index = j;
+ break;
+ }
+ }
+ if (index == -1) {
+ try {
+ throw new ParseFailedException("There exists syntax error and no END block is found!");
+ } catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ }
+ ASTNode childNode = parseException(parseTokens.subList(i, index + 1));
+ currentNode.addChild(childNode);
+ currentNode = childNode.getDeepestChild();
+ childNode = new FunctionEndNode();
+ for (int j = index; j < parseTokens.size(); j++) {
+ childNode.addToken(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";")) {
+ i = j;
+ break;
+ }
+ }
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ break;
+ }
+ // match function end
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("END")) {
+ ASTNode childNode = new FunctionEndNode();
+ for (int j = i; j < parseTokens.size(); j++) {
+ childNode.addToken(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";")) {
+ i = j;
+ break;
+ }
+ }
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ break;
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.EOF)) {
+ break;
+ }
+ else {
+ try {
+ throw new ParseFailedException("Failed to parse:" + parseTokens.get(i));
+ }
+ catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ }
+
+ return root;
+ }
+
+ /**
+ * Create TRIGGER
+ * Grammar: CREATE OR REPLACE TRIGGER trigger_name
+ * BEFORE | AFTER
+ * { INSERT | UPDATE | DELETE }
+ * ON table_name
+ * [REFERENCING NEW AS new OLD AS old] -- OpenGauss does not support this
+ * FOR EACH ROW
+ * [WHEN (condition)]
+ * BEGIN
+ * -- trigger body
+ * END;
+ * Example: CREATE OR REPLACE TRIGGER log_insert
+ * BEFORE INSERT ON employees
+ * FOR EACH ROW
+ * BEGIN
+ * INSERT INTO audit_log (action, employee_id) VALUES ('INSERT', :NEW.id);
+ * END;
+ */
+ private ASTNode parseTrigger(List parseTokens) {
+ ASTNode root = new TriggerNode();
+ ASTNode currentNode = root;
+ for (int i = 0; i < parseTokens.size(); i++) {
+ // match create trigger
+ if (root.getTokens().isEmpty()) {
+ for (int j = i; j < parseTokens.size(); j++) {
+ root.addToken(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("TRIGGER")) {
+ i = j;
+ break;
+ }
+ }
+ }
+ // match trigger name
+ else if (currentNode == root && parseTokens.get(i).hasType(Token.TokenType.IDENTIFIER)) {
+ ASTNode childNode = new TriggerNameNode();
+ childNode.addToken(parseTokens.get(i));
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ // match trigger condition
+ else if (currentNode instanceof TriggerNameNode && (
+ parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("BEFORE") ||
+ parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("AFTER") ||
+ parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("INSTEAD OF")
+ )) {
+ if (i + 1 < parseTokens.size() && (
+ parseTokens.get(i + 1).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i + 1).getValue().equalsIgnoreCase("INSERT") ||
+ parseTokens.get(i + 1).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i + 1).getValue().equalsIgnoreCase("UPDATE") ||
+ parseTokens.get(i + 1).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i + 1).getValue().equalsIgnoreCase("DELETE")
+ )) {
+ TriggerConditionNode childNode = new TriggerConditionNode();
+ childNode.setCondition(parseTokens.get(i));
+ childNode.setAction(parseTokens.get(i + 1));
+ i++;
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else {
+ try {
+ throw new ParseFailedException("There exists syntax error!");
+ } catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ // match trigger on table
+ else if (currentNode instanceof TriggerConditionNode && parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("ON")) {
+ if (i + 1 < parseTokens.size() && parseTokens.get(i + 1).hasType(Token.TokenType.IDENTIFIER)) {
+ ASTNode childNode = new TriggerObjNode();
+ childNode.addToken(parseTokens.get(i));
+ childNode.addToken(parseTokens.get(i + 1));
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ i++;
+ }
+ else {
+ try {
+ throw new ParseFailedException("There exists syntax error!");
+ } catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ // match [REFERENCING NEW AS new OLD AS old]
+ else if (currentNode instanceof TriggerObjNode && parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("REFERENCING")) {
+ ASTNode childNode = new TriggerOptionNode();
+ for (int j = i; j < parseTokens.size(); j++) {
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("FOR")) {
+ i = j - 1;
+ break;
+ }
+ childNode.addToken(parseTokens.get(j));
+ }
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ // match FOR EACH ROW
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("FOR")) {
+ if ((i + 1 < parseTokens.size() && parseTokens.get(i + 1).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i + 1).getValue().equalsIgnoreCase("EACH"))
+ && (i + 2 < parseTokens.size() && parseTokens.get(i + 2).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i + 2).getValue().equalsIgnoreCase("ROW"))) {
+ ASTNode childNode = new TriggerForEachRowNode();
+ childNode.addToken(parseTokens.get(i));
+ childNode.addToken(parseTokens.get(i + 1));
+ childNode.addToken(parseTokens.get(i + 2));
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ i += 2;
+ }
+ else {
+ try {
+ throw new ParseFailedException("There exists syntax error!");
+ } catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ // match when
+ else if (currentNode instanceof TriggerForEachRowNode && parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("WHEN")) {
+ ASTNode childNode = new TriggerWhenNode();
+ for(int j = i; j < parseTokens.size(); j++) {
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("BEGIN")) {
+ i = j - 1;
+ break;
+ }
+ childNode.addToken(parseTokens.get(j));
+ }
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ // match declare
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("DECLARE")) {
+ ASTNode childNode = new TriggerDeclareNode();
+ childNode.addToken(parseTokens.get(i));
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ // match declare content
+ else if (currentNode instanceof TriggerDeclareNode && parseTokens.get(i).hasType(Token.TokenType.IDENTIFIER)) {
+ TriggerDeclareContentNode childNode = new TriggerDeclareContentNode();
+ for (int j = i; j < parseTokens.size(); j++) {
+ childNode.addToken(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";")) {
+ i = j;
+ break;
+ }
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && !parseTokens.get(j).getValue().equalsIgnoreCase(":=")) {
+ childNode.setType(parseTokens.get(j));
+ }
+ }
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else if (currentNode instanceof TriggerDeclareContentNode && parseTokens.get(i).hasType(Token.TokenType.IDENTIFIER)) {
+ TriggerDeclareContentNode childNode = new TriggerDeclareContentNode();
+ for (int j = i; j < parseTokens.size(); j++) {
+ childNode.addToken(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";")) {
+ i = j;
+ break;
+ }
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && !parseTokens.get(j).getValue().equalsIgnoreCase(":=")) {
+ childNode.setType(parseTokens.get(j));
+ }
+ }
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ // match begin
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("BEGIN")) {
+ ASTNode childNode = new TriggerBeginNode();
+ childNode.addToken(parseTokens.get(i));
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ // match trigger body
+ else if ( ((currentNode instanceof TriggerBeginNode) || (currentNode instanceof TriggerBodyNode)) && !(parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("END"))) {
+ ASTNode childNode = new TriggerBodyNode();
+ for (int j = i; j < parseTokens.size(); j++) {
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("END")) {
+ i = j - 1;
+ break;
+ }
+ else if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equalsIgnoreCase(";")) {
+ i = j;
+ childNode.addToken(parseTokens.get(j));
+ break;
+ }
+ childNode.addToken(parseTokens.get(j));
+ }
+ ASTNode bodystatementNode = parseTokens(childNode.getTokens());
+ if (bodystatementNode != null) {
+ currentNode.addChild(bodystatementNode);
+ currentNode = bodystatementNode.getDeepestChild();
+ ASTNode bodystatementEndNode = new TriggerBodyNode();
+ currentNode.addChild(bodystatementEndNode);
+ currentNode = bodystatementEndNode;
+ }
+ else {
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("END")) {
+ ASTNode childNode = new TriggerEndNode();
+ for (int j = i; j < parseTokens.size(); j++) {
+ childNode.addToken(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";")) {
+ i = j;
+ break;
+ }
+ }
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.EOF)) {
+ break;
+ }
+ else {
+ try {
+ throw new ParseFailedException("Failed to parse:" + parseTokens.get(i));
+ }
+ catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ return root;
+ }
+
+ /**
+ * PL/SQL
+ * Grammar: DECLARE
+ * v_var1 v_type;
+ * ...
+ * BEGIN
+ * -- PL/SQL
+ * END;
+ * Example: DECLARE
+ * v_name Varchar2(20);
+ * v_salary employees.salary%TYPE;
+ * BEGIN
+ * SELECT name, salary INTO v_name, v_salary FROM employees WHERE employee_id = 100;
+ * DBMS_OUTPUT.PUT_LINE('Name: ' || v_name || ', Salary: ' || v_salary);
+ * EXCEPTION
+ * WHEN NO_DATA_FOUND THEN
+ * DBMS_OUTPUT.PUT_LINE('No data found.');
+ * END;
+ */
+ private ASTNode parsePL(List parseTokens) {
+ ASTNode root = new PLNode();
+ root.addToken(parseTokens.get(0));
+ ASTNode currentNode = root;
+ for (int i = 1; i < parseTokens.size(); i++) {
+ // match declare
+ if (currentNode == root && !(parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("BEGIN"))) {
+ for (int j = i; j < parseTokens.size(); j++) {
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("BEGIN")) {
+ i = j - 1;
+ break;
+ }
+ PLDeclareNode childNode = new PLDeclareNode();
+ for (int k = j; k < parseTokens.size(); k++) {
+ childNode.addToken(parseTokens.get(k));
+ if (parseTokens.get(k).hasType(Token.TokenType.KEYWORD) && !parseTokens.get(k).getValue().equalsIgnoreCase(":=")) {
+ childNode.setType(parseTokens.get(k));
+ }
+ if (parseTokens.get(k).hasType(Token.TokenType.SYMBOL) && parseTokens.get(k).getValue().equals(";")) {
+ j = k;
+ break;
+ }
+ }
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ }
+ // match begin
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("BEGIN")) {
+ ASTNode childNode = new PLBeginNode();
+ childNode.addToken(parseTokens.get(i));
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ // match body
+ else if (
+ (currentNode instanceof PLBeginNode || currentNode instanceof PLBodyNode) &&
+ !(parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("END"))
+ ) {
+ ASTNode childNode = new PLBodyNode();
+ for (int j = i; j < parseTokens.size(); j++) {
+ if (parseTokens.get(j).hasType(Token.TokenType.KEYWORD) && parseTokens.get(j).getValue().equalsIgnoreCase("END")) {
+ i = j - 1;
+ break;
+ }
+ else if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";")) {
+ i = j;
+ childNode.addToken(parseTokens.get(j));
+ break;
+ }
+ childNode.addToken(parseTokens.get(j));
+ }
+ ASTNode bodystatementNode = parseTokens(childNode.getTokens());
+ if (bodystatementNode != null) {
+ currentNode.addChild(bodystatementNode);
+ currentNode = bodystatementNode.getDeepestChild();
+ ASTNode bodystatementEndNode = new PLBodyNode();
+ currentNode.addChild(bodystatementEndNode);
+ currentNode = bodystatementEndNode;
+ }
+ else {
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ }
+ // match end
+ else if (parseTokens.get(i).hasType(Token.TokenType.KEYWORD) && parseTokens.get(i).getValue().equalsIgnoreCase("END")) {
+ ASTNode childNode = new PLEndNode();
+ for (int j = i; j < parseTokens.size(); j++) {
+ childNode.addToken(parseTokens.get(j));
+ if (parseTokens.get(j).hasType(Token.TokenType.SYMBOL) && parseTokens.get(j).getValue().equals(";")) {
+ i = j;
+ break;
+ }
+ }
+ currentNode.addChild(childNode);
+ currentNode = childNode;
+ }
+ else if (parseTokens.get(i).hasType(Token.TokenType.EOF)) {
+ break;
+ }
+ else {
+ try {
+ throw new ParseFailedException("Failed to parse:" + parseTokens.get(i));
+ }
+ catch (ParseFailedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+
+ return root;
+ }
+
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/ASTNode.java b/sqlTranslate/src/main/java/parser/ast/ASTNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..5d57574d14d4ba924d596ed6175b2edc0dc11374
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/ASTNode.java
@@ -0,0 +1,221 @@
+package parser.ast;
+
+import lexer.Token;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.regex.Pattern;
+
+public abstract class ASTNode {
+ private List tokens;
+ private ASTNode parent;
+ private List children = new ArrayList<>();
+
+ public ASTNode() {
+ }
+
+ public ASTNode(List tokens) {
+ this.tokens = tokens;
+ }
+
+ public ASTNode(ASTNode node) {
+ this.tokens = node.tokens;
+ this.parent = node.parent;
+ this.children = new ArrayList<>(node.children);
+ }
+
+ public List getTokens() {
+ return tokens;
+ }
+
+ public void setTokens(List tokens) {
+ this.tokens = tokens;
+ }
+
+ public void modifyTokens(int index, Token token) {
+ tokens.set(index, token);
+ }
+
+ public void moveTokenByIndex(int index) {
+ tokens.remove(index);
+ }
+
+ public void addTokenByIndex(int index, Token token) {
+ tokens.add(index, token);
+ }
+
+ public void addTokensByIndex(int index, List tokens) {
+ this.tokens.addAll(index, tokens);
+ }
+
+ public int getTokenIndexByRegex(String regex) {
+ Pattern pattern = Pattern.compile(regex);
+ Optional indexOpt = tokens.stream()
+ .filter(token -> pattern.matcher(token.getValue()).matches())
+ .map(token -> tokens.indexOf(token))
+ .findFirst();
+ if (indexOpt.isPresent()) {
+ int index = indexOpt.get();
+ return index;
+ } else {
+ return -1;
+ }
+
+ }
+
+ public boolean checkExistsByRegex (String regex) {
+ return tokens.stream().anyMatch(token -> token.getValue().matches(regex));
+ }
+
+ public void addToken(Token token) {
+ tokens.add(token);
+ }
+
+ public boolean tokensEqual(List tokens) {
+ if (this.tokens.size() != tokens.size())
+ return false;
+
+ for (int i = 0; i < tokens.size(); i++) {
+ if (!this.tokens.get(i).getValue().equals(tokens.get(i).getValue()))
+ return false;
+ }
+
+ return true;
+ }
+
+ public ASTNode getParent() {
+ return parent;
+ }
+
+ public void setParent(ASTNode parent) {
+ this.parent = parent;
+ }
+
+ public List getChildren() {
+ return children;
+ }
+
+ public boolean hasChild() {
+ return !children.isEmpty();
+ }
+
+ public ASTNode getChildByName(String childName) {
+ for (ASTNode child : children) {
+ if (child.toString().equals(childName)) {
+ return child;
+ }
+ }
+
+ return null;
+ }
+
+ public ASTNode getFirstChild() {
+ if (hasChild())
+ return children.get(0);
+ else
+ return null;
+ }
+
+ public List getChildrenByName(String childName) {
+ List nodes = new ArrayList<>();
+ for (ASTNode child : children) {
+ if (child.toString().equals(childName)) {
+ nodes.add(child);
+ }
+ }
+
+ return nodes;
+ }
+
+ public ASTNode getDeepestChild() {
+ if (hasChild()) {
+ ASTNode child = getChildren().get(0);
+ while (child.hasChild()) {
+ child = child.getChildren().get(0);
+ }
+ return child;
+ }
+ else {
+ return this;
+ }
+
+ }
+
+ /**
+ * 将对应名称的node更新为新的child
+ */
+ public void setChildrenByName(String childName, ASTNode child) {
+ for (int i = 0; i < this.children.size(); i++) {
+ if (this.children.get(i).toString().contains(childName)) {
+ this.children.set(i, child);
+ break;
+ }
+ }
+ }
+
+ public void addChild(ASTNode childNode) {
+ childNode.setParent(this);
+ children.add(childNode);
+ }
+
+ public void replaceChild(ASTNode oldChild, ASTNode newChild) {
+ newChild.setParent(this);
+ children.set(children.indexOf(oldChild), newChild);
+ }
+
+ // add a child node at position index of children
+ public void addChild(int index, ASTNode childNode) {
+ childNode.setParent(this);
+ children.add(index, childNode);
+ }
+
+ public void removeChild(ASTNode childNode) {
+ children.remove(childNode);
+ }
+
+ public String toQueryString() {
+ StringBuilder queryString = new StringBuilder();
+ visit(this, queryString);
+ return queryString.toString();
+ }
+
+ public abstract void visit(ASTNode node, StringBuilder queryString);
+
+ @Override
+ public String toString() {
+ String str = "";
+ if (tokens != null) {
+ for (int i = 0; i < tokens.size(); i++) {
+ if (i < tokens.size() - 1)
+ str += tokens.get(i).getValue() + " ";
+ else
+ str += tokens.get(i).getValue();
+ }
+ }
+ return str;
+ }
+
+ public String getASTString() {
+ StringBuilder ASTString = new StringBuilder();
+ VisitAST(this, ASTString, 0);
+ return ASTString.toString();
+ }
+
+ private void VisitAST(ASTNode node, StringBuilder ASTString, int depth) {
+ addASTStructure(depth, ASTString);
+ ASTString.append(node.getClass() + ":" + node.toString() + "\n");
+ for (ASTNode child : node.getChildren()) {
+ if (child.getClass() == node.getClass())
+ VisitAST(child, ASTString, depth);
+ else
+ VisitAST(child, ASTString, depth + 1);
+ }
+ }
+
+ private void addASTStructure(int depth, StringBuilder ASTString) {
+ for (int i = 1; i <= depth; i++) {
+ ASTString.append("--");
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/altertable/AlterAddColumnNode.java b/sqlTranslate/src/main/java/parser/ast/altertable/AlterAddColumnNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..7da13de9283087b2f312cb49e9bb0a2ed939312b
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/altertable/AlterAddColumnNode.java
@@ -0,0 +1,74 @@
+package parser.ast.altertable;
+
+import interfaces.DataType;
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class AlterAddColumnNode extends ASTNode implements DataType {
+ private Token name;
+ private Token type;
+ private List constraint;
+
+ public AlterAddColumnNode() {
+ super();
+ }
+
+ public AlterAddColumnNode(ASTNode node)
+ {
+ super(node);
+ }
+
+ public AlterAddColumnNode(List tokens)
+ {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+
+ public Token getName() {
+ return name;
+ }
+
+ public void setName(Token name) {
+ this.name = name;
+ }
+
+ @Override
+ public Token getType() {
+ return type;
+ }
+
+ @Override
+ public void setType(Token type) {
+ this.type = type;
+ }
+
+ public List getConstraint() {
+ return constraint;
+ }
+
+ public void setConstraint(List constraint) {
+ this.constraint = constraint;
+ }
+
+ @Override
+ public void ResetTokensbyType() {
+ List tokens = new ArrayList<>();
+ tokens.add(new Token(Token.TokenType.KEYWORD, "ADD"));
+ tokens.add(name);
+ tokens.add(type);
+ for (Token token : constraint) {
+ tokens.add(token);
+ }
+ setTokens(tokens);
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/altertable/AlterAddConstraintNode.java b/sqlTranslate/src/main/java/parser/ast/altertable/AlterAddConstraintNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..16dd594fe973deac5c55eda94ae06dddd9e7ee21
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/altertable/AlterAddConstraintNode.java
@@ -0,0 +1,24 @@
+package parser.ast.altertable;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.List;
+
+public class AlterAddConstraintNode extends ASTNode {
+ public AlterAddConstraintNode(ASTNode node) {
+ super(node);
+ }
+
+ public AlterAddConstraintNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/altertable/AlterDropColumnNode.java b/sqlTranslate/src/main/java/parser/ast/altertable/AlterDropColumnNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..d1cc81f1213fba4e65c89d64cd16471035180fda
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/altertable/AlterDropColumnNode.java
@@ -0,0 +1,25 @@
+package parser.ast.altertable;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.List;
+
+public class AlterDropColumnNode extends ASTNode {
+
+ public AlterDropColumnNode(ASTNode node) {
+ super(node);
+ }
+
+ public AlterDropColumnNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/altertable/AlterDropConstraintNode.java b/sqlTranslate/src/main/java/parser/ast/altertable/AlterDropConstraintNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..079daa924e9fe71e01d8da21d436a191416ae240
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/altertable/AlterDropConstraintNode.java
@@ -0,0 +1,24 @@
+package parser.ast.altertable;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.List;
+
+public class AlterDropConstraintNode extends ASTNode {
+ public AlterDropConstraintNode(ASTNode node) {
+ super(node);
+ }
+
+ public AlterDropConstraintNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/altertable/AlterEndNode.java b/sqlTranslate/src/main/java/parser/ast/altertable/AlterEndNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..0daf45c3c145bbe9391c59f4a63bc2b70db6f00d
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/altertable/AlterEndNode.java
@@ -0,0 +1,26 @@
+package parser.ast.altertable;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.List;
+
+public class AlterEndNode extends ASTNode {
+ public AlterEndNode(ASTNode node) {
+ super(node);
+ }
+
+ public AlterEndNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString());
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
+
diff --git a/sqlTranslate/src/main/java/parser/ast/altertable/AlterModifyColumnNode.java b/sqlTranslate/src/main/java/parser/ast/altertable/AlterModifyColumnNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..6903af4894bfbe22183376be4621326367d4b358
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/altertable/AlterModifyColumnNode.java
@@ -0,0 +1,60 @@
+package parser.ast.altertable;
+
+import interfaces.DataType;
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class AlterModifyColumnNode extends ASTNode implements DataType {
+ private Token name;
+ private Token type;
+
+ public AlterModifyColumnNode() {
+ super();
+ }
+
+ public AlterModifyColumnNode(ASTNode node) {
+ super(node);
+ }
+
+ public AlterModifyColumnNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void setType(Token columnType) {
+ this.type = columnType;
+ }
+
+ @Override
+ public Token getType() {
+ return type;
+ }
+
+ public void setName(Token columnName) {
+ this.name = columnName;
+ }
+
+ public Token getName() {
+ return name;
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+
+ @Override
+ public void ResetTokensbyType() {
+ List tokens = new ArrayList<>();
+ tokens.add(new Token(Token.TokenType.KEYWORD, "MODIFY"));
+ tokens.add(name);
+ tokens.add(type);
+ setTokens(tokens);
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/altertable/AlterNode.java b/sqlTranslate/src/main/java/parser/ast/altertable/AlterNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..c7a2b13f641e38f86c320fc5801ef5b4d87aa2ec
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/altertable/AlterNode.java
@@ -0,0 +1,24 @@
+package parser.ast.altertable;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.List;
+
+public class AlterNode extends ASTNode {
+ public AlterNode(ASTNode node) {
+ super(node);
+ }
+
+ public AlterNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/altertable/AlterObjNode.java b/sqlTranslate/src/main/java/parser/ast/altertable/AlterObjNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..7b44124c0e9411e25c15bb0066863e62ba92c152
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/altertable/AlterObjNode.java
@@ -0,0 +1,24 @@
+package parser.ast.altertable;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.List;
+
+public class AlterObjNode extends ASTNode {
+ public AlterObjNode(ASTNode node) {
+ super(node);
+ }
+
+ public AlterObjNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/altertable/AlterRenameColumnNode.java b/sqlTranslate/src/main/java/parser/ast/altertable/AlterRenameColumnNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..e407cc22675e74d729994889b2878e434b0d70da
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/altertable/AlterRenameColumnNode.java
@@ -0,0 +1,24 @@
+package parser.ast.altertable;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.List;
+
+public class AlterRenameColumnNode extends ASTNode {
+ public AlterRenameColumnNode(ASTNode node) {
+ super(node);
+ }
+
+ public AlterRenameColumnNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/altertable/AlterRenameTableNode.java b/sqlTranslate/src/main/java/parser/ast/altertable/AlterRenameTableNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..3e4f1759025253edd2238687f7064ef1b8885fc7
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/altertable/AlterRenameTableNode.java
@@ -0,0 +1,24 @@
+package parser.ast.altertable;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.List;
+
+public class AlterRenameTableNode extends ASTNode {
+ public AlterRenameTableNode(ASTNode node) {
+ super(node);
+ }
+
+ public AlterRenameTableNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/casewhen/CaseConditionNode.java b/sqlTranslate/src/main/java/parser/ast/casewhen/CaseConditionNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..a97ff738b1a668cfcc06a816c93f1bc736f45c12
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/casewhen/CaseConditionNode.java
@@ -0,0 +1,25 @@
+package parser.ast.casewhen;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.List;
+
+public class CaseConditionNode extends ASTNode {
+ public CaseConditionNode(ASTNode node) {
+ super(node);
+ }
+
+ public CaseConditionNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/casewhen/CaseElseNode.java b/sqlTranslate/src/main/java/parser/ast/casewhen/CaseElseNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..fcbf1110127277dde0916ae29ecee5be6a77f11f
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/casewhen/CaseElseNode.java
@@ -0,0 +1,24 @@
+package parser.ast.casewhen;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.List;
+
+public class CaseElseNode extends ASTNode {
+ public CaseElseNode(ASTNode node) {
+ super(node);
+ }
+
+ public CaseElseNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/casewhen/CaseEndNode.java b/sqlTranslate/src/main/java/parser/ast/casewhen/CaseEndNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..7b92c8a593ce0e94494a7478e2790811709acb97
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/casewhen/CaseEndNode.java
@@ -0,0 +1,27 @@
+package parser.ast.casewhen;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.List;
+
+public class CaseEndNode extends ASTNode {
+ public CaseEndNode(ASTNode node)
+ {
+ super(node);
+ }
+
+ public CaseEndNode(List tokens)
+ {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString());
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/casewhen/CaseThenNode.java b/sqlTranslate/src/main/java/parser/ast/casewhen/CaseThenNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..17f86846ed3c8bff07de468083368dd5a4b07ef2
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/casewhen/CaseThenNode.java
@@ -0,0 +1,25 @@
+package parser.ast.casewhen;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.List;
+
+public class CaseThenNode extends ASTNode {
+ public CaseThenNode(ASTNode node) {
+ super(node);
+ }
+
+ public CaseThenNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/createtable/CRTEndNode.java b/sqlTranslate/src/main/java/parser/ast/createtable/CRTEndNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..aa8220e323708661c3d3fb9f75d1f495ed45ec33
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/createtable/CRTEndNode.java
@@ -0,0 +1,24 @@
+package parser.ast.createtable;
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.List;
+
+public class CRTEndNode extends ASTNode {
+ public CRTEndNode(ASTNode node)
+ {
+ super(node);
+ }
+ public CRTEndNode(List tokens)
+ {
+ super(tokens);
+ }
+ public void visit(ASTNode node, StringBuilder queryString)
+ {
+ queryString.append(")" + toString());
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/createtable/ColumnNode.java b/sqlTranslate/src/main/java/parser/ast/createtable/ColumnNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..77f254af67f453ddf7f78776557018c85fccec0c
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/createtable/ColumnNode.java
@@ -0,0 +1,76 @@
+package parser.ast.createtable;
+
+import interfaces.DataType;
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ColumnNode extends ASTNode implements DataType {
+ private Token name;
+ private Token type;
+ private List constraint;
+ public ColumnNode() {
+ super();
+ }
+ public ColumnNode(ASTNode node)
+ {
+ super(node);
+ }
+ public ColumnNode(List tokens)
+ {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString)
+ {
+ if (node.hasChild() && !(node.getChildren().get(0) instanceof CRTEndNode) )
+ queryString.append(toString() + ", ");
+ else if (node.hasChild() && (node.getChildren().get(0) instanceof CRTEndNode))
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+
+ public Token getName() {
+ return name;
+ }
+
+ public void setName(Token name) {
+ this.name = name;
+ }
+
+ @Override
+ public Token getType() {
+ return type;
+ }
+
+ @Override
+ public void setType(Token type) {
+ this.type = type;
+ }
+
+ public List getConstraint() {
+ return constraint;
+ }
+
+ public void setConstraint(List constraint) {
+ this.constraint = constraint;
+ }
+
+ @Override
+ public void ResetTokensbyType() {
+ List tokens = new ArrayList<>();
+ tokens.add(name);
+ tokens.add(type);
+ for (Token token : constraint) {
+ tokens.add(token);
+ }
+ setTokens(tokens);
+ }
+
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/createtable/CreateTabNode.java b/sqlTranslate/src/main/java/parser/ast/createtable/CreateTabNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..d392672277f923404a7f9198a5e6dce2b5ac2e45
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/createtable/CreateTabNode.java
@@ -0,0 +1,24 @@
+package parser.ast.createtable;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+import java.util.List;
+
+public class CreateTabNode extends ASTNode {
+ public CreateTabNode(ASTNode node) {
+ super(node);
+ }
+ public CreateTabNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ // judge the type of the table
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/createtable/TableConstraintNode.java b/sqlTranslate/src/main/java/parser/ast/createtable/TableConstraintNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..4072f420c6255c4afc3e4f2926814e33b81fdeef
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/createtable/TableConstraintNode.java
@@ -0,0 +1,29 @@
+package parser.ast.createtable;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.List;
+
+public class TableConstraintNode extends ASTNode{
+ public TableConstraintNode(ASTNode node)
+ {
+ super(node);
+ }
+ public TableConstraintNode(List tokens)
+ {
+ super(tokens);
+ }
+
+ public void visit(ASTNode node, StringBuilder queryString)
+ {
+ if (node.hasChild() && !(node.getChildren().get(0) instanceof CRTEndNode) )
+ queryString.append(toString() + ", ");
+ else if (node.hasChild() && (node.getChildren().get(0) instanceof CRTEndNode))
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/createtable/TableNode.java b/sqlTranslate/src/main/java/parser/ast/createtable/TableNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..d4b5feadd0e5ba3fec4e06d6c200e3feb46cfe74
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/createtable/TableNode.java
@@ -0,0 +1,27 @@
+package parser.ast.createtable;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.List;
+
+public class TableNode extends ASTNode{
+ public TableNode(ASTNode node)
+ {
+ super(node);
+ }
+ public TableNode(List tokens)
+ {
+ super(tokens);
+ }
+
+ public void visit(ASTNode node, StringBuilder queryString)
+ {
+ queryString.append(toString() + " ( ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/createtable/TableTypeNode.java b/sqlTranslate/src/main/java/parser/ast/createtable/TableTypeNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..87e0f54e4f2e555f5f70b9633d0b0797f7749bcf
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/createtable/TableTypeNode.java
@@ -0,0 +1,27 @@
+package parser.ast.createtable;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.List;
+
+public class TableTypeNode extends ASTNode {
+ public TableTypeNode(ASTNode node)
+ {
+ super(node);
+ }
+ public TableTypeNode(List tokens)
+ {
+ super(tokens);
+ }
+
+ public void visit(ASTNode node, StringBuilder queryString)
+ {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/delete/DeleteConditionNode.java b/sqlTranslate/src/main/java/parser/ast/delete/DeleteConditionNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..34bb43f6e37d35d1d7920f091ed0c2879c41b2d5
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/delete/DeleteConditionNode.java
@@ -0,0 +1,24 @@
+package parser.ast.delete;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.List;
+
+public class DeleteConditionNode extends ASTNode {
+ public DeleteConditionNode(ASTNode node) {
+ super(node);
+ }
+
+ public DeleteConditionNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/delete/DeleteEndNode.java b/sqlTranslate/src/main/java/parser/ast/delete/DeleteEndNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..e128f1158b52e438c6bcd2234058714cf4dfb2ca
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/delete/DeleteEndNode.java
@@ -0,0 +1,24 @@
+package parser.ast.delete;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.List;
+
+public class DeleteEndNode extends ASTNode {
+ public DeleteEndNode(ASTNode node) {
+ super(node);
+ }
+
+ public DeleteEndNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString());
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/delete/DeleteNode.java b/sqlTranslate/src/main/java/parser/ast/delete/DeleteNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..499b343d9aafdaac27e7d006898e12a8abda3ee4
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/delete/DeleteNode.java
@@ -0,0 +1,23 @@
+package parser.ast.delete;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.List;
+
+public class DeleteNode extends ASTNode {
+ public DeleteNode(ASTNode node) {
+ super(node);
+ }
+ public DeleteNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/delete/DeleteObjNode.java b/sqlTranslate/src/main/java/parser/ast/delete/DeleteObjNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..8e29c3023cb116df0489ba6a9b8a318a8a69acad
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/delete/DeleteObjNode.java
@@ -0,0 +1,24 @@
+package parser.ast.delete;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.List;
+
+public class DeleteObjNode extends ASTNode {
+ public DeleteObjNode(ASTNode node) {
+ super(node);
+ }
+
+ public DeleteObjNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/drop/DropEndNode.java b/sqlTranslate/src/main/java/parser/ast/drop/DropEndNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..690896f7d5195394bcabe002870e1c8283555925
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/drop/DropEndNode.java
@@ -0,0 +1,23 @@
+package parser.ast.drop;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+import java.util.List;
+
+public class DropEndNode extends ASTNode {
+ public DropEndNode(ASTNode node) {
+ super(node);
+ }
+
+ public DropEndNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString());
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/drop/DropNode.java b/sqlTranslate/src/main/java/parser/ast/drop/DropNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..f6cf18ec3c0406e361474ad58645f36114749d4f
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/drop/DropNode.java
@@ -0,0 +1,24 @@
+package parser.ast.drop;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+import java.util.List;
+
+public class DropNode extends ASTNode {
+ public DropNode(ASTNode node) {
+ super(node);
+ }
+
+ public DropNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/drop/DropObjNameNode.java b/sqlTranslate/src/main/java/parser/ast/drop/DropObjNameNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..09ac982caecffbba8e406df968d2d0651c552015
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/drop/DropObjNameNode.java
@@ -0,0 +1,24 @@
+package parser.ast.drop;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+import java.util.List;
+
+public class DropObjNameNode extends ASTNode {
+ public DropObjNameNode(ASTNode node) {
+ super(node);
+ }
+
+ public DropObjNameNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/drop/DropOptionNode.java b/sqlTranslate/src/main/java/parser/ast/drop/DropOptionNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..67ba522496eb6410d2002a3e7dc39d9a8ed744b7
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/drop/DropOptionNode.java
@@ -0,0 +1,25 @@
+package parser.ast.drop;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.List;
+
+public class DropOptionNode extends ASTNode {
+ public DropOptionNode(ASTNode node) {
+ super(node);
+ }
+
+ public DropOptionNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/exception/CustomExceptionNode.java b/sqlTranslate/src/main/java/parser/ast/exception/CustomExceptionNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..4207a4cd3d3b7c9d0e2b030fb5dc346f77d3375a
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/exception/CustomExceptionNode.java
@@ -0,0 +1,30 @@
+package parser.ast.exception;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class CustomExceptionNode extends ASTNode {
+ public CustomExceptionNode () {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public CustomExceptionNode (ASTNode node) {
+ super(node);
+ }
+
+ public CustomExceptionNode (List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : node.getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/exception/ExceptionActionNode.java b/sqlTranslate/src/main/java/parser/ast/exception/ExceptionActionNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..0b2d206d204b1bab7bf17dbf8974bb276f0d031d
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/exception/ExceptionActionNode.java
@@ -0,0 +1,30 @@
+package parser.ast.exception;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ExceptionActionNode extends ASTNode {
+ public ExceptionActionNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public ExceptionActionNode(ASTNode node) {
+ super(node);
+ }
+
+ public ExceptionActionNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : node.getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/exception/ExceptionEndNode.java b/sqlTranslate/src/main/java/parser/ast/exception/ExceptionEndNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..fca56c9f543f520ab149d319c2ad77390a58f936
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/exception/ExceptionEndNode.java
@@ -0,0 +1,30 @@
+package parser.ast.exception;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ExceptionEndNode extends ASTNode {
+ public ExceptionEndNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public ExceptionEndNode(ASTNode node) {
+ super(node);
+ }
+
+ public ExceptionEndNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString());
+ for (ASTNode child : node.getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/exception/ExceptionNode.java b/sqlTranslate/src/main/java/parser/ast/exception/ExceptionNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..9c83f1d2b8af02153353364708ee92f77b32b87c
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/exception/ExceptionNode.java
@@ -0,0 +1,30 @@
+package parser.ast.exception;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ExceptionNode extends ASTNode {
+
+ public ExceptionNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public ExceptionNode(ASTNode node) {
+ super(node);
+ }
+
+ public ExceptionNode(List tokens) {
+ super(tokens);
+ }
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : node.getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/exception/Invalid_numberNode.java b/sqlTranslate/src/main/java/parser/ast/exception/Invalid_numberNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..cbecad469c95185882ca38de8c03d7b6aa010558
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/exception/Invalid_numberNode.java
@@ -0,0 +1,31 @@
+package parser.ast.exception;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Invalid_numberNode extends ASTNode {
+
+ public Invalid_numberNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public Invalid_numberNode(ASTNode node) {
+ super(node);
+ }
+
+ public Invalid_numberNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : node.getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/exception/OtherExceptionNode.java b/sqlTranslate/src/main/java/parser/ast/exception/OtherExceptionNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..df5852162af5dec4195bb935f8354000cf5da3e9
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/exception/OtherExceptionNode.java
@@ -0,0 +1,31 @@
+package parser.ast.exception;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class OtherExceptionNode extends ASTNode {
+
+ public OtherExceptionNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public OtherExceptionNode(ASTNode node) {
+ super(node);
+ }
+
+ public OtherExceptionNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : node.getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/exception/Zero_divideNode.java b/sqlTranslate/src/main/java/parser/ast/exception/Zero_divideNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..54d635a12ec21ba4d8d34db4a15b41dbfe60b175
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/exception/Zero_divideNode.java
@@ -0,0 +1,31 @@
+package parser.ast.exception;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Zero_divideNode extends ASTNode {
+
+ public Zero_divideNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public Zero_divideNode(ASTNode node) {
+ super(node);
+ }
+
+ public Zero_divideNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : node.getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/function/FunctionBeginNode.java b/sqlTranslate/src/main/java/parser/ast/function/FunctionBeginNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..77a564c7d950b173b1e8c0f93960afd640ce5fa7
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/function/FunctionBeginNode.java
@@ -0,0 +1,30 @@
+package parser.ast.function;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class FunctionBeginNode extends ASTNode {
+ public FunctionBeginNode(List tokens) {
+ super(tokens);
+ }
+
+ public FunctionBeginNode(ASTNode node) {
+ super(node);
+ }
+
+ public FunctionBeginNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : node.getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/function/FunctionBodyNode.java b/sqlTranslate/src/main/java/parser/ast/function/FunctionBodyNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..a813da850d4265a22ba4a6bafc877e4ebbd12b68
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/function/FunctionBodyNode.java
@@ -0,0 +1,30 @@
+package parser.ast.function;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class FunctionBodyNode extends ASTNode {
+ public FunctionBodyNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public FunctionBodyNode(ASTNode node) {
+ super(node);
+ }
+
+ public FunctionBodyNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : node.getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/function/FunctionColumnNode.java b/sqlTranslate/src/main/java/parser/ast/function/FunctionColumnNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..70a934f5d48d66d25b047b652afc8ffb051a9571
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/function/FunctionColumnNode.java
@@ -0,0 +1,93 @@
+package parser.ast.function;
+
+import interfaces.DataType;
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class FunctionColumnNode extends ASTNode implements DataType {
+ private Token name;
+ private Token type;
+ private List constraint;
+ private List InOut;
+ public FunctionColumnNode() {
+ super();
+ setTokens(new ArrayList<>());
+ setInOut(new ArrayList<>());
+ }
+
+ public FunctionColumnNode(ASTNode node) {
+ super(node);
+ }
+
+ public FunctionColumnNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString)
+ {
+ if (node.hasChild() && (node.getChildren().get(0) instanceof FunctionColumnNode) )
+ queryString.append(toString() + ", ");
+ else if (node.hasChild() && !(node.getChildren().get(0) instanceof FunctionColumnNode))
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+
+ public Token getName() {
+ return name;
+ }
+
+ public void setName(Token name) {
+ this.name = name;
+ }
+
+ @Override
+ public Token getType() {
+ return type;
+ }
+
+ @Override
+ public void setType(Token type) {
+ this.type = type;
+ }
+
+ public List getConstraint() {
+ return constraint;
+ }
+
+ public void setConstraint(List constraint) {
+ this.constraint = constraint;
+ }
+
+ public List getInOut() {
+ return InOut;
+ }
+
+ public void setInOut(List InOut) {
+ this.InOut = InOut;
+ }
+
+ public void addInOut(Token InOut) {
+ this.InOut.add(InOut);
+ }
+
+ @Override
+ public void ResetTokensbyType() {
+ List tokens = new ArrayList<>();
+ tokens.add(name);
+ for (Token token : InOut) {
+ tokens.add(token);
+ }
+ tokens.add(type);
+ for (Token token : constraint) {
+ tokens.add(token);
+ }
+ setTokens(tokens);
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/function/FunctionDeclareContentNode.java b/sqlTranslate/src/main/java/parser/ast/function/FunctionDeclareContentNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..335a3753cb3d96b85db9c2b9419ae5f47b06ab1d
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/function/FunctionDeclareContentNode.java
@@ -0,0 +1,57 @@
+package parser.ast.function;
+
+import interfaces.DataType;
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class FunctionDeclareContentNode extends ASTNode implements DataType {
+ private Token type;
+ public FunctionDeclareContentNode() {
+ super();
+ setTokens(new ArrayList<>());
+ setType(new Token(Token.TokenType.NULL, ""));
+ }
+
+ public FunctionDeclareContentNode(List tokens) {
+ super(tokens);
+ }
+
+ public FunctionDeclareContentNode(ASTNode node) {
+ super(node);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : node.getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+
+ @Override
+ public Token getType() {
+ return type;
+ }
+
+ @Override
+ public void setType(Token type) {
+ this.type = type;
+ }
+
+ @Override
+ public void ResetTokensbyType() {
+ List tokens = new ArrayList<>();
+ for (Token token : getTokens()) {
+ if (token.hasType(Token.TokenType.KEYWORD) && !token.getValue().equalsIgnoreCase(":=")) {
+ tokens.add(getType());
+ }
+ else {
+ tokens.add(token);
+ }
+ }
+ setTokens(tokens);
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/function/FunctionDeclareNode.java b/sqlTranslate/src/main/java/parser/ast/function/FunctionDeclareNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..2942f4ae0772116a5bc9bf49c02581e887ae3d6b
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/function/FunctionDeclareNode.java
@@ -0,0 +1,30 @@
+package parser.ast.function;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class FunctionDeclareNode extends ASTNode {
+ public FunctionDeclareNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public FunctionDeclareNode(ASTNode node) {
+ super(node);
+ }
+
+ public FunctionDeclareNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : node.getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/function/FunctionEndNode.java b/sqlTranslate/src/main/java/parser/ast/function/FunctionEndNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..bf9f9c65edf70c7c75f4a2cb0d1ea8ff9b5ac1bf
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/function/FunctionEndNode.java
@@ -0,0 +1,30 @@
+package parser.ast.function;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class FunctionEndNode extends ASTNode {
+ public FunctionEndNode(List tokens) {
+ super(tokens);
+ }
+
+ public FunctionEndNode(ASTNode node) {
+ super(node);
+ }
+
+ public FunctionEndNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString());
+ for (ASTNode child : node.getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/function/FunctionNameNode.java b/sqlTranslate/src/main/java/parser/ast/function/FunctionNameNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..b8548ee5f0e03cba944317d3e87eac0de8700587
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/function/FunctionNameNode.java
@@ -0,0 +1,30 @@
+package parser.ast.function;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class FunctionNameNode extends ASTNode {
+ public FunctionNameNode(List tokens) {
+ super(tokens);
+ }
+
+ public FunctionNameNode(ASTNode node) {
+ super(node);
+ }
+
+ public FunctionNameNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ( ");
+ for (ASTNode child : node.getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/function/FunctionNode.java b/sqlTranslate/src/main/java/parser/ast/function/FunctionNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..6e2de6e66a76b8336a581af0379162eb93257d88
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/function/FunctionNode.java
@@ -0,0 +1,31 @@
+package parser.ast.function;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class FunctionNode extends ASTNode {
+ public FunctionNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public FunctionNode(ASTNode node) {
+ super(node);
+ }
+
+ public FunctionNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : node.getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/function/FunctionRetDefNode.java b/sqlTranslate/src/main/java/parser/ast/function/FunctionRetDefNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..7572007e283e8b305208e67785bf4a42b69042a6
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/function/FunctionRetDefNode.java
@@ -0,0 +1,52 @@
+package parser.ast.function;
+
+import interfaces.DataType;
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class FunctionRetDefNode extends ASTNode implements DataType {
+ private Token type;
+ public FunctionRetDefNode() {
+ super();
+ setTokens(new ArrayList<>());
+ setType(new Token(Token.TokenType.NULL, ""));
+ }
+
+ public FunctionRetDefNode(ASTNode node) {
+ super(node);
+ }
+
+ public FunctionRetDefNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(") " + toString() + " ");
+ for (ASTNode child : node.getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+
+ @Override
+ public Token getType() {
+ return type;
+ }
+
+ @Override
+ public void setType(Token type) {
+ this.type = type;
+ }
+
+ @Override
+ public void ResetTokensbyType() {
+ List tokens = new ArrayList<>();
+ tokens.add(new Token(Token.TokenType.KEYWORD, "RETURN"));
+ tokens.add(type);
+ tokens.add(new Token(Token.TokenType.KEYWORD, "IS"));
+ setTokens(tokens);
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/function/FunctionReturnNode.java b/sqlTranslate/src/main/java/parser/ast/function/FunctionReturnNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..7f56ba5cbcb92eaf2de3fd8c3764b8c2fdd59429
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/function/FunctionReturnNode.java
@@ -0,0 +1,30 @@
+package parser.ast.function;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class FunctionReturnNode extends ASTNode {
+ public FunctionReturnNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public FunctionReturnNode(ASTNode node) {
+ super(node);
+ }
+
+ public FunctionReturnNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : node.getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/ifelsif/ELSENode.java b/sqlTranslate/src/main/java/parser/ast/ifelsif/ELSENode.java
new file mode 100644
index 0000000000000000000000000000000000000000..966532684988291ff21f172c591f3767c7a87cf5
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/ifelsif/ELSENode.java
@@ -0,0 +1,30 @@
+package parser.ast.ifelsif;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ELSENode extends ASTNode {
+ public ELSENode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public ELSENode(ASTNode node) {
+ super(node);
+ }
+
+ public ELSENode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : node.getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/ifelsif/ELSIFActionNode.java b/sqlTranslate/src/main/java/parser/ast/ifelsif/ELSIFActionNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..c8a0ff82042a9ed3db8594738e65fc20c249b744
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/ifelsif/ELSIFActionNode.java
@@ -0,0 +1,30 @@
+package parser.ast.ifelsif;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ELSIFActionNode extends ASTNode {
+ public ELSIFActionNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public ELSIFActionNode(ASTNode node) {
+ super(node);
+ }
+
+ public ELSIFActionNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : node.getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/ifelsif/ELSIFConditionNode.java b/sqlTranslate/src/main/java/parser/ast/ifelsif/ELSIFConditionNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..819bafb375101ea6d0ef94cd836746f96e9d92a8
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/ifelsif/ELSIFConditionNode.java
@@ -0,0 +1,31 @@
+package parser.ast.ifelsif;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ELSIFConditionNode extends ASTNode {
+ public ELSIFConditionNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public ELSIFConditionNode(ASTNode node) {
+ super(node);
+ }
+
+ public ELSIFConditionNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : node.getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
+
diff --git a/sqlTranslate/src/main/java/parser/ast/ifelsif/EndIFNode.java b/sqlTranslate/src/main/java/parser/ast/ifelsif/EndIFNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..a1ecb9b20a968d1173f2e2ba5baa4316574f5c24
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/ifelsif/EndIFNode.java
@@ -0,0 +1,30 @@
+package parser.ast.ifelsif;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class EndIFNode extends ASTNode {
+ public EndIFNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public EndIFNode (ASTNode node) {
+ super(node);
+ }
+
+ public EndIFNode (List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString());
+ for (ASTNode child : node.getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/ifelsif/IFActionNode.java b/sqlTranslate/src/main/java/parser/ast/ifelsif/IFActionNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..1d834382f78c47e29fa9f77250fd929fd285ccad
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/ifelsif/IFActionNode.java
@@ -0,0 +1,30 @@
+package parser.ast.ifelsif;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class IFActionNode extends ASTNode {
+ public IFActionNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public IFActionNode(ASTNode node) {
+ super(node);
+ }
+
+ public IFActionNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : node.getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/ifelsif/IFConditionNode.java b/sqlTranslate/src/main/java/parser/ast/ifelsif/IFConditionNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..aba574fb6e1a0d4bc37cdec1542fb173f591bc97
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/ifelsif/IFConditionNode.java
@@ -0,0 +1,30 @@
+package parser.ast.ifelsif;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class IFConditionNode extends ASTNode {
+ public IFConditionNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public IFConditionNode(ASTNode node) {
+ super(node);
+ }
+
+ public IFConditionNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : node.getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/insert/InsertDataNode.java b/sqlTranslate/src/main/java/parser/ast/insert/InsertDataNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..f7b4191906a69fc3fe5cca8b982b9d47ff039ba5
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/insert/InsertDataNode.java
@@ -0,0 +1,23 @@
+package parser.ast.insert;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+import java.util.List;
+
+public class InsertDataNode extends ASTNode {
+ public InsertDataNode(List tokens) {
+ super(tokens);
+ }
+
+ public InsertDataNode(ASTNode node) {
+ super(node);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/insert/InsertEndNode.java b/sqlTranslate/src/main/java/parser/ast/insert/InsertEndNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..df72f2ac72a2658bc3e7904c320b84ec07c9f9db
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/insert/InsertEndNode.java
@@ -0,0 +1,24 @@
+package parser.ast.insert;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+import java.util.List;
+
+public class InsertEndNode extends ASTNode {
+ public InsertEndNode(ASTNode node) {
+ super(node);
+ }
+
+ public InsertEndNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString());
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/insert/InsertNode.java b/sqlTranslate/src/main/java/parser/ast/insert/InsertNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..cc73161b517c4f124c03dd572eb8d1347bf8c7be
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/insert/InsertNode.java
@@ -0,0 +1,28 @@
+package parser.ast.insert;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+import java.util.List;
+
+public class InsertNode extends ASTNode {
+ public InsertNode(List tokens)
+ {
+ super(tokens);
+ }
+
+ public InsertNode(ASTNode node)
+ {
+ super(node);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString)
+ {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/insert/InsertObjNode.java b/sqlTranslate/src/main/java/parser/ast/insert/InsertObjNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..b9bde4d357c55595a27d73328c972894d6c72147
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/insert/InsertObjNode.java
@@ -0,0 +1,23 @@
+package parser.ast.insert;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+import java.util.List;
+
+public class InsertObjNode extends ASTNode{
+ public InsertObjNode(List tokens) {
+ super(tokens);
+ }
+
+ public InsertObjNode(ASTNode node) {
+ super(node);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/join/JoinConditionNode.java b/sqlTranslate/src/main/java/parser/ast/join/JoinConditionNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..7bad80ac8b7cf419ce15139535505ef45f5104cf
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/join/JoinConditionNode.java
@@ -0,0 +1,42 @@
+package parser.ast.join;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+import java.util.List;
+
+public class JoinConditionNode extends ASTNode {
+ private String keyword;
+ public JoinConditionNode(List tokens)
+ {
+ super(tokens);
+ this.keyword = "";
+ }
+
+ public JoinConditionNode(ASTNode node)
+ {
+ super(node);
+ this.keyword = "";
+ }
+
+ public JoinConditionNode() {
+ super();
+ }
+
+ public String getKeyword() {
+ return keyword.replace(" ", "");
+ }
+
+ public void setKeyword(String keyword) {
+ this.keyword = keyword + " ";
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString)
+ {
+ queryString.append(this.keyword + toString() + " ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/join/JoinEndNode.java b/sqlTranslate/src/main/java/parser/ast/join/JoinEndNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..ce0de85351a3ee5fec960d0a492384a63134bb02
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/join/JoinEndNode.java
@@ -0,0 +1,28 @@
+package parser.ast.join;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+import java.util.List;
+
+public class JoinEndNode extends ASTNode {
+ public JoinEndNode(List tokens) {
+ super(tokens);
+ }
+
+ public JoinEndNode(ASTNode node) {
+ super(node);
+ }
+
+ public JoinEndNode() {
+ super();
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString());
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/join/JoinSourceTabNode.java b/sqlTranslate/src/main/java/parser/ast/join/JoinSourceTabNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..6ae208db7054626cb84e1b3a2c6efef1c0e89af3
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/join/JoinSourceTabNode.java
@@ -0,0 +1,23 @@
+package parser.ast.join;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+import java.util.List;
+
+public class JoinSourceTabNode extends ASTNode {
+ public JoinSourceTabNode(List tokens) {
+ super(tokens);
+ }
+
+ public JoinSourceTabNode(ASTNode node) {
+ super(node);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/join/JoinTargetTabNode.java b/sqlTranslate/src/main/java/parser/ast/join/JoinTargetTabNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..434e4532b6acb9364869c628e47f2247d7b6b224
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/join/JoinTargetTabNode.java
@@ -0,0 +1,23 @@
+package parser.ast.join;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+import java.util.List;
+
+public class JoinTargetTabNode extends ASTNode {
+ public JoinTargetTabNode(List tokens) {
+ super(tokens);
+ }
+
+ public JoinTargetTabNode(ASTNode node) {
+ super(node);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/join/JoinTypeNode.java b/sqlTranslate/src/main/java/parser/ast/join/JoinTypeNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..712716b8b528f2ec52ad955df23f5c85a8bd9c3a
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/join/JoinTypeNode.java
@@ -0,0 +1,24 @@
+package parser.ast.join;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+import java.util.List;
+
+public class JoinTypeNode extends ASTNode {
+ public JoinTypeNode(List tokens) {
+ super(tokens);
+ }
+
+ public JoinTypeNode(ASTNode node) {
+ super(node);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/loop/ForNode.java b/sqlTranslate/src/main/java/parser/ast/loop/ForNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..1fb738480e33fcba8f5259b3a86abff691992184
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/loop/ForNode.java
@@ -0,0 +1,31 @@
+package parser.ast.loop;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ForNode extends ASTNode {
+ public ForNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public ForNode(ASTNode node) {
+ super(node);
+ }
+
+ public ForNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/loop/LoopBodyNode.java b/sqlTranslate/src/main/java/parser/ast/loop/LoopBodyNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..d2a0a43c008ace14b0a4ffb6e8270543d440c15c
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/loop/LoopBodyNode.java
@@ -0,0 +1,31 @@
+package parser.ast.loop;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LoopBodyNode extends ASTNode {
+ public LoopBodyNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public LoopBodyNode(ASTNode node) {
+ super(node);
+ }
+
+ public LoopBodyNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/loop/LoopEndNode.java b/sqlTranslate/src/main/java/parser/ast/loop/LoopEndNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..6a0676aa32fe1dd7f2d536aaa6c3f4c38b5974d2
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/loop/LoopEndNode.java
@@ -0,0 +1,31 @@
+package parser.ast.loop;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LoopEndNode extends ASTNode {
+ public LoopEndNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public LoopEndNode(ASTNode node) {
+ super(node);
+ }
+
+ public LoopEndNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString());
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/loop/LoopExitNode.java b/sqlTranslate/src/main/java/parser/ast/loop/LoopExitNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..77ee1c91ef380e541396d24a543175474feaaae7
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/loop/LoopExitNode.java
@@ -0,0 +1,31 @@
+package parser.ast.loop;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LoopExitNode extends ASTNode {
+ public LoopExitNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public LoopExitNode(ASTNode node) {
+ super(node);
+ }
+
+ public LoopExitNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/loop/LoopNode.java b/sqlTranslate/src/main/java/parser/ast/loop/LoopNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..b0bb2c27e70304087d78d57002706448e0039044
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/loop/LoopNode.java
@@ -0,0 +1,31 @@
+package parser.ast.loop;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LoopNode extends ASTNode {
+ public LoopNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public LoopNode(ASTNode node) {
+ super(node);
+ }
+
+ public LoopNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/loop/WhileNode.java b/sqlTranslate/src/main/java/parser/ast/loop/WhileNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..d354cb17773804fb3852ae80a597e87109826f9c
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/loop/WhileNode.java
@@ -0,0 +1,31 @@
+package parser.ast.loop;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class WhileNode extends ASTNode {
+ public WhileNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public WhileNode(ASTNode node) {
+ super(node);
+ }
+
+ public WhileNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/pl/PLBeginNode.java b/sqlTranslate/src/main/java/parser/ast/pl/PLBeginNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..b91a19694934296634f3379d43a0f3789029bd30
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/pl/PLBeginNode.java
@@ -0,0 +1,31 @@
+package parser.ast.pl;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PLBeginNode extends ASTNode {
+ public PLBeginNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public PLBeginNode(ASTNode node) {
+ super(node);
+ }
+
+ public PLBeginNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/pl/PLBodyNode.java b/sqlTranslate/src/main/java/parser/ast/pl/PLBodyNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..3c6e3d8d81536c16ef501e472da941f47c3cc236
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/pl/PLBodyNode.java
@@ -0,0 +1,31 @@
+package parser.ast.pl;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PLBodyNode extends ASTNode {
+ public PLBodyNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public PLBodyNode(ASTNode node) {
+ super(node);
+ }
+
+ public PLBodyNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/pl/PLDeclareNode.java b/sqlTranslate/src/main/java/parser/ast/pl/PLDeclareNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..0c7f35a8cda106b514dd26e77ddb34faf2b53cf8
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/pl/PLDeclareNode.java
@@ -0,0 +1,58 @@
+package parser.ast.pl;
+
+import interfaces.DataType;
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PLDeclareNode extends ASTNode implements DataType {
+ private Token type;
+ public PLDeclareNode() {
+ super();
+ setTokens(new ArrayList<>());
+ setType(new Token(Token.TokenType.NULL, ""));
+ }
+
+ public PLDeclareNode(ASTNode node) {
+ super(node);
+ }
+
+ public PLDeclareNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+
+ @Override
+ public Token getType() {
+ return type;
+ }
+
+ @Override
+ public void setType(Token type) {
+ this.type = type;
+ }
+
+ @Override
+ public void ResetTokensbyType() {
+ List tokens = new ArrayList<>();
+ for (Token token: getTokens()) {
+ if (token.hasType(Token.TokenType.KEYWORD)) {
+ tokens.add(getType());
+ }
+ else {
+ tokens.add(token);
+ }
+ }
+ setTokens(tokens);
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/pl/PLEndNode.java b/sqlTranslate/src/main/java/parser/ast/pl/PLEndNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..5e1e2d4c5eeb78aec0590ad3c69dbb4514ca31f0
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/pl/PLEndNode.java
@@ -0,0 +1,31 @@
+package parser.ast.pl;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PLEndNode extends ASTNode {
+ public PLEndNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public PLEndNode(ASTNode node) {
+ super(node);
+ }
+
+ public PLEndNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString());
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/pl/PLNode.java b/sqlTranslate/src/main/java/parser/ast/pl/PLNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..61c04083f4ae67f8e6b1ae0b973e8c83dca70ca0
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/pl/PLNode.java
@@ -0,0 +1,31 @@
+package parser.ast.pl;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PLNode extends ASTNode {
+ public PLNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public PLNode(ASTNode node) {
+ super(node);
+ }
+
+ public PLNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/procedure/ProcedureBeginNode.java b/sqlTranslate/src/main/java/parser/ast/procedure/ProcedureBeginNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..ca1444707f56f5b8fa08b2b6b95d832a16f2ee76
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/procedure/ProcedureBeginNode.java
@@ -0,0 +1,31 @@
+package parser.ast.procedure;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ProcedureBeginNode extends ASTNode {
+ public ProcedureBeginNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public ProcedureBeginNode(ASTNode node) {
+ super(node);
+ }
+
+ public ProcedureBeginNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/procedure/ProcedureColumnNode.java b/sqlTranslate/src/main/java/parser/ast/procedure/ProcedureColumnNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..810e9ce69a35a528f6b904f7187e46e3fff05611
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/procedure/ProcedureColumnNode.java
@@ -0,0 +1,95 @@
+package parser.ast.procedure;
+
+import interfaces.DataType;
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ProcedureColumnNode extends ASTNode implements DataType {
+ private Token name;
+ private Token type;
+ private List constraint;
+ private List InOut;
+ public ProcedureColumnNode() {
+ super();
+ setTokens(new ArrayList<>());
+ setInOut(new ArrayList<>());
+ }
+
+ public ProcedureColumnNode(ASTNode node)
+ {
+ super(node);
+ }
+
+ public ProcedureColumnNode(List tokens)
+ {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString)
+ {
+ if (node.hasChild() && (node.getChildren().get(0) instanceof ProcedureColumnNode) )
+ queryString.append(toString() + ", ");
+ else if (node.hasChild() && !(node.getChildren().get(0) instanceof ProcedureColumnNode))
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+
+ public Token getName() {
+ return name;
+ }
+
+ public void setName(Token name) {
+ this.name = name;
+ }
+
+ @Override
+ public Token getType() {
+ return type;
+ }
+
+ @Override
+ public void setType(Token type) {
+ this.type = type;
+ }
+
+ public List getConstraint() {
+ return constraint;
+ }
+
+ public void setConstraint(List constraint) {
+ this.constraint = constraint;
+ }
+
+ public List getInOut() {
+ return InOut;
+ }
+
+ public void setInOut(List InOut) {
+ this.InOut = InOut;
+ }
+
+ public void addInOut(Token InOut) {
+ this.InOut.add(InOut);
+ }
+
+ @Override
+ public void ResetTokensbyType() {
+ List tokens = new ArrayList<>();
+ tokens.add(name);
+ for (Token token : InOut) {
+ tokens.add(token);
+ }
+ tokens.add(type);
+ for (Token token : constraint) {
+ tokens.add(token);
+ }
+ setTokens(tokens);
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/procedure/ProcedureDeclareContentNode.java b/sqlTranslate/src/main/java/parser/ast/procedure/ProcedureDeclareContentNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..cffec7364324b81e49bf32089d2eccd10bb892ed
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/procedure/ProcedureDeclareContentNode.java
@@ -0,0 +1,57 @@
+package parser.ast.procedure;
+
+import interfaces.DataType;
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ProcedureDeclareContentNode extends ASTNode implements DataType {
+ private Token type;
+ public ProcedureDeclareContentNode() {
+ super();
+ setTokens(new ArrayList<>());
+ setType(new Token(Token.TokenType.NULL, ""));
+ }
+
+ public ProcedureDeclareContentNode(ASTNode node) {
+ super(node);
+ }
+
+ public ProcedureDeclareContentNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : node.getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+
+ @Override
+ public Token getType() {
+ return type;
+ }
+
+ @Override
+ public void setType(Token type) {
+ this.type = type;
+ }
+
+ @Override
+ public void ResetTokensbyType() {
+ List tokens = new ArrayList<>();
+ for (Token token : getTokens()) {
+ if (token.hasType(Token.TokenType.KEYWORD) && !token.getValue().equalsIgnoreCase(":=")) {
+ tokens.add(getType());
+ }
+ else {
+ tokens.add(token);
+ }
+ }
+ setTokens(tokens);
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/procedure/ProcedureDeclareNode.java b/sqlTranslate/src/main/java/parser/ast/procedure/ProcedureDeclareNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..c215c952f08b2b5e5db58b5a625c92b17cf054eb
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/procedure/ProcedureDeclareNode.java
@@ -0,0 +1,30 @@
+package parser.ast.procedure;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ProcedureDeclareNode extends ASTNode {
+ public ProcedureDeclareNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public ProcedureDeclareNode(ASTNode node) {
+ super(node);
+ }
+
+ public ProcedureDeclareNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : node.getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/procedure/ProcedureEndNode.java b/sqlTranslate/src/main/java/parser/ast/procedure/ProcedureEndNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..44b0b48085c211bc055201c4bb721d30c21ecb8d
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/procedure/ProcedureEndNode.java
@@ -0,0 +1,31 @@
+package parser.ast.procedure;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ProcedureEndNode extends ASTNode {
+ public ProcedureEndNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public ProcedureEndNode(ASTNode node) {
+ super(node);
+ }
+
+ public ProcedureEndNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString());
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/procedure/ProcedureNode.java b/sqlTranslate/src/main/java/parser/ast/procedure/ProcedureNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..d7c127e5495c7f5b4cb063cbe3834ab0ff05d54c
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/procedure/ProcedureNode.java
@@ -0,0 +1,31 @@
+package parser.ast.procedure;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ProcedureNode extends ASTNode {
+ public ProcedureNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public ProcedureNode(ASTNode node) {
+ super(node);
+ }
+
+ public ProcedureNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/procedure/ProcedureObjNode.java b/sqlTranslate/src/main/java/parser/ast/procedure/ProcedureObjNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..7f434c2b4d27c70f30894b9395e93ca566b3bbd1
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/procedure/ProcedureObjNode.java
@@ -0,0 +1,32 @@
+package parser.ast.procedure;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ProcedureObjNode extends ASTNode {
+ public ProcedureObjNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public ProcedureObjNode(ASTNode node) {
+ super(node);
+ }
+
+ public ProcedureObjNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " (");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/procedure/ProcedurePLStatementNode.java b/sqlTranslate/src/main/java/parser/ast/procedure/ProcedurePLStatementNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..468052a5c8ff8c1def2c84ea2640f97615ffbf31
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/procedure/ProcedurePLStatementNode.java
@@ -0,0 +1,28 @@
+package parser.ast.procedure;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ProcedurePLStatementNode extends ASTNode {
+ public ProcedurePLStatementNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+ public ProcedurePLStatementNode(ASTNode node) {
+ super(node);
+ }
+ public ProcedurePLStatementNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : node.getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/procedure/ProcedureRetDefNode.java b/sqlTranslate/src/main/java/parser/ast/procedure/ProcedureRetDefNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..ed31a5d9baa12c62df316670cdd33eb08ef617cc
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/procedure/ProcedureRetDefNode.java
@@ -0,0 +1,58 @@
+package parser.ast.procedure;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+import interfaces.DataType;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ProcedureRetDefNode extends ASTNode implements DataType {
+ private Token type;
+ public ProcedureRetDefNode() {
+ super();
+ setTokens(new ArrayList<>());
+ setType(new Token(Token.TokenType.NULL, ""));
+ }
+
+ public ProcedureRetDefNode(ASTNode node) {
+ super(node);
+ }
+
+ public ProcedureRetDefNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(") " + toString() + " ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+
+ @Override
+ public Token getType() {
+ return type;
+ }
+
+ @Override
+ public void setType(Token type) {
+ this.type = type;
+ }
+
+ @Override
+ public void ResetTokensbyType() {
+ List tokens = new ArrayList<>();
+ for (Token token: getTokens()) {
+ if (token.hasType(Token.TokenType.KEYWORD) && !token.getValue().equalsIgnoreCase("IS")) {
+ tokens.add(getType());
+ }
+ else {
+ tokens.add(token);
+ }
+ }
+ setTokens(tokens);
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/select/SelectContentNode.java b/sqlTranslate/src/main/java/parser/ast/select/SelectContentNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..ee93ddcad02dd0a7581c2f78f4552dbbaf47423a
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/select/SelectContentNode.java
@@ -0,0 +1,45 @@
+package parser.ast.select;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.List;
+
+public class SelectContentNode extends ASTNode {
+ public SelectContentNode(List tokens)
+ {
+ super(tokens);
+ this.isDistinct = "";
+ }
+
+ public SelectContentNode(ASTNode node)
+ {
+ super(node);
+ this.isDistinct = "";
+ }
+
+ private String isDistinct;
+
+ public SelectContentNode() {
+ super();
+ }
+
+ public String getIsDistinct()
+ {
+ return isDistinct;
+ }
+
+ public void setIsDistinct(String isDistinct) {
+ this.isDistinct = isDistinct + " ";
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString)
+ {
+ queryString.append(isDistinct + toString() + " FROM ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/select/SelectEndNode.java b/sqlTranslate/src/main/java/parser/ast/select/SelectEndNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..514f965acbea038999a780e80fed16c5657ff9e4
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/select/SelectEndNode.java
@@ -0,0 +1,28 @@
+package parser.ast.select;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.List;
+
+public class SelectEndNode extends ASTNode {
+ public SelectEndNode(List tokens)
+ {
+ super(tokens);
+ }
+
+ public SelectEndNode(ASTNode node)
+ {
+ super(node);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString)
+ {
+ queryString.append(toString());
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/select/SelectNode.java b/sqlTranslate/src/main/java/parser/ast/select/SelectNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..d3d4d1cdd7faf831c56c53518b3f654853944fd7
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/select/SelectNode.java
@@ -0,0 +1,29 @@
+package parser.ast.select;
+
+import parser.ast.ASTNode;
+import lexer.Token;
+
+import java.util.List;
+
+public class SelectNode extends ASTNode {
+ public SelectNode(List tokens)
+ {
+ super(tokens);
+ }
+
+ public SelectNode(ASTNode node)
+ {
+ super(node);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString)
+ {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/select/SelectObjNode.java b/sqlTranslate/src/main/java/parser/ast/select/SelectObjNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..40d591f4f31d21a6f092843bf54cc9387ecf0276
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/select/SelectObjNode.java
@@ -0,0 +1,27 @@
+package parser.ast.select;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.List;
+
+public class SelectObjNode extends ASTNode {
+ public SelectObjNode(List tokens)
+ {
+ super(tokens);
+ }
+
+ public SelectObjNode(ASTNode node)
+ {
+ super(node);
+ }
+
+ public void visit(ASTNode node, StringBuilder queryString)
+ {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/select/SelectOptionNode.java b/sqlTranslate/src/main/java/parser/ast/select/SelectOptionNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..870f975c984c4efa5e3305657c0cb465b7049df0
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/select/SelectOptionNode.java
@@ -0,0 +1,28 @@
+package parser.ast.select;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.List;
+
+public class SelectOptionNode extends ASTNode {
+ public SelectOptionNode(List tokens)
+ {
+ super(tokens);
+ }
+
+ public SelectOptionNode(ASTNode node)
+ {
+ super(node);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString)
+ {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/select/SelectUnionNode.java b/sqlTranslate/src/main/java/parser/ast/select/SelectUnionNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..f7bede2dd30dd08c3cdcec5ecd207353d01ed715
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/select/SelectUnionNode.java
@@ -0,0 +1,28 @@
+package parser.ast.select;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.List;
+
+public class SelectUnionNode extends ASTNode {
+ public SelectUnionNode(List tokens)
+ {
+ super(tokens);
+ }
+
+ public SelectUnionNode(ASTNode node)
+ {
+ super(node);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString)
+ {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/select/SelectWhereClauseNode.java b/sqlTranslate/src/main/java/parser/ast/select/SelectWhereClauseNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..95f43d64a0840411db704efcfe9966760ab03303
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/select/SelectWhereClauseNode.java
@@ -0,0 +1,28 @@
+package parser.ast.select;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.List;
+
+public class SelectWhereClauseNode extends ASTNode {
+ public SelectWhereClauseNode(List tokens)
+ {
+ super(tokens);
+ }
+
+ public SelectWhereClauseNode(ASTNode node)
+ {
+ super(node);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString)
+ {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren())
+ {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/trigger/TriggerBeginNode.java b/sqlTranslate/src/main/java/parser/ast/trigger/TriggerBeginNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..f58fce5d6ad4ce6960c06dd600bde9cdfc99524d
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/trigger/TriggerBeginNode.java
@@ -0,0 +1,31 @@
+package parser.ast.trigger;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TriggerBeginNode extends ASTNode {
+ public TriggerBeginNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public TriggerBeginNode(ASTNode node) {
+ super(node);
+ }
+
+ public TriggerBeginNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/trigger/TriggerBodyNode.java b/sqlTranslate/src/main/java/parser/ast/trigger/TriggerBodyNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..ca8fcb8909fafc32e519883610e25a12fdaf5f6e
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/trigger/TriggerBodyNode.java
@@ -0,0 +1,30 @@
+package parser.ast.trigger;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TriggerBodyNode extends ASTNode {
+ public TriggerBodyNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public TriggerBodyNode(ASTNode node) {
+ super(node);
+ }
+
+ public TriggerBodyNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/trigger/TriggerConditionNode.java b/sqlTranslate/src/main/java/parser/ast/trigger/TriggerConditionNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..44bb32e9c1dadffc562bd4c2b01152e8241becab
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/trigger/TriggerConditionNode.java
@@ -0,0 +1,55 @@
+package parser.ast.trigger;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TriggerConditionNode extends ASTNode {
+ private Token condition;
+ private Token action;
+ public TriggerConditionNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public TriggerConditionNode(List tokens) {
+ super(tokens);
+ }
+
+ public TriggerConditionNode(ASTNode node) {
+ super(node);
+ }
+
+ public void setCondition(Token condition) {
+ this.condition = condition;
+ }
+
+ public void setAction(Token action) {
+ this.action = action;
+ }
+
+ public Token getCondition() {
+ return condition;
+ }
+
+ public Token getAction() {
+ return action;
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(getCondition().getValue() + " " + getAction().getValue() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+
+ @Override
+ public String toString() {
+ String str = "";
+ str = getCondition().getValue() + " " + getAction().getValue();
+ return str;
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/trigger/TriggerDeclareContentNode.java b/sqlTranslate/src/main/java/parser/ast/trigger/TriggerDeclareContentNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..a5d41205c0d3edb929c03b3384076d6a14b4467e
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/trigger/TriggerDeclareContentNode.java
@@ -0,0 +1,57 @@
+package parser.ast.trigger;
+
+import interfaces.DataType;
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TriggerDeclareContentNode extends ASTNode implements DataType {
+ private Token type;
+ public TriggerDeclareContentNode() {
+ super();
+ setTokens(new ArrayList<>());
+ setType(new Token(Token.TokenType.NULL, ""));
+ }
+
+ public TriggerDeclareContentNode(ASTNode node) {
+ super(node);
+ }
+
+ public TriggerDeclareContentNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+
+ @Override
+ public Token getType() {
+ return type;
+ }
+
+ @Override
+ public void setType(Token type) {
+ this.type = type;
+ }
+
+ @Override
+ public void ResetTokensbyType() {
+ List tokens = new ArrayList<>();
+ for (Token token : getTokens()) {
+ if (token.hasType(Token.TokenType.KEYWORD) && !token.getValue().equalsIgnoreCase(":=")) {
+ tokens.add(getType());
+ }
+ else {
+ tokens.add(token);
+ }
+ }
+ setTokens(tokens);
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/trigger/TriggerDeclareNode.java b/sqlTranslate/src/main/java/parser/ast/trigger/TriggerDeclareNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..2576e067b17e88eea74dc3ef22d2b50e382d3737
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/trigger/TriggerDeclareNode.java
@@ -0,0 +1,30 @@
+package parser.ast.trigger;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TriggerDeclareNode extends ASTNode {
+ public TriggerDeclareNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public TriggerDeclareNode(ASTNode node) {
+ super(node);
+ }
+
+ public TriggerDeclareNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/trigger/TriggerEndNode.java b/sqlTranslate/src/main/java/parser/ast/trigger/TriggerEndNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..27ce119cf5c920d8c2a6bc1784dbc01166848389
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/trigger/TriggerEndNode.java
@@ -0,0 +1,30 @@
+package parser.ast.trigger;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TriggerEndNode extends ASTNode {
+ public TriggerEndNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public TriggerEndNode(ASTNode node) {
+ super(node);
+ }
+
+ public TriggerEndNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString());
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/trigger/TriggerForEachRowNode.java b/sqlTranslate/src/main/java/parser/ast/trigger/TriggerForEachRowNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..6c6bb635f7657aefb0c9462becbfcd856b0c4b06
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/trigger/TriggerForEachRowNode.java
@@ -0,0 +1,30 @@
+package parser.ast.trigger;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TriggerForEachRowNode extends ASTNode {
+ public TriggerForEachRowNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public TriggerForEachRowNode(ASTNode node) {
+ super(node);
+ }
+
+ public TriggerForEachRowNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/trigger/TriggerNameNode.java b/sqlTranslate/src/main/java/parser/ast/trigger/TriggerNameNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..ce0f0245aba200e11c369647ab3df51f51bc7bfa
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/trigger/TriggerNameNode.java
@@ -0,0 +1,30 @@
+package parser.ast.trigger;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TriggerNameNode extends ASTNode {
+ public TriggerNameNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public TriggerNameNode(ASTNode node) {
+ super(node);
+ }
+
+ public TriggerNameNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/trigger/TriggerNode.java b/sqlTranslate/src/main/java/parser/ast/trigger/TriggerNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..6f4a8c05c0696be73a05ae1631f8eab4d9834b6e
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/trigger/TriggerNode.java
@@ -0,0 +1,30 @@
+package parser.ast.trigger;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TriggerNode extends ASTNode {
+ public TriggerNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public TriggerNode(ASTNode node) {
+ super(node);
+ }
+
+ public TriggerNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/trigger/TriggerObjNode.java b/sqlTranslate/src/main/java/parser/ast/trigger/TriggerObjNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..0898ba6cdfebf8495b361e963877e46a96d2f552
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/trigger/TriggerObjNode.java
@@ -0,0 +1,30 @@
+package parser.ast.trigger;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TriggerObjNode extends ASTNode {
+ public TriggerObjNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public TriggerObjNode(List tokens) {
+ super(tokens);
+ }
+
+ public TriggerObjNode(ASTNode node) {
+ super(node);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/trigger/TriggerOptionNode.java b/sqlTranslate/src/main/java/parser/ast/trigger/TriggerOptionNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..287006ac592b411829c692713fa2f98a07c787da
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/trigger/TriggerOptionNode.java
@@ -0,0 +1,30 @@
+package parser.ast.trigger;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TriggerOptionNode extends ASTNode {
+ public TriggerOptionNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public TriggerOptionNode(ASTNode node) {
+ super(node);
+ }
+
+ public TriggerOptionNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/trigger/TriggerWhenNode.java b/sqlTranslate/src/main/java/parser/ast/trigger/TriggerWhenNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..94b5a8687b33706fb74334077c30c8cdcc1efa4a
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/trigger/TriggerWhenNode.java
@@ -0,0 +1,30 @@
+package parser.ast.trigger;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TriggerWhenNode extends ASTNode {
+ public TriggerWhenNode() {
+ super();
+ setTokens(new ArrayList<>());
+ }
+
+ public TriggerWhenNode(ASTNode node) {
+ super(node);
+ }
+
+ public TriggerWhenNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/update/UpdateEndNode.java b/sqlTranslate/src/main/java/parser/ast/update/UpdateEndNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..83db81dc587b5403d3d1e3e4c09a7e9a6f2d14e8
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/update/UpdateEndNode.java
@@ -0,0 +1,24 @@
+package parser.ast.update;
+
+import parser.ast.ASTNode;
+import lexer.Token;
+
+import java.util.List;
+
+public class UpdateEndNode extends ASTNode {
+ public UpdateEndNode(ASTNode node) {
+ super(node);
+ }
+
+ public UpdateEndNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString());
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/update/UpdateNode.java b/sqlTranslate/src/main/java/parser/ast/update/UpdateNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..18b546a0c0df39ae15b10bded384932841c07e03
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/update/UpdateNode.java
@@ -0,0 +1,24 @@
+package parser.ast.update;
+
+import parser.ast.ASTNode;
+import lexer.Token;
+
+import java.util.List;
+
+public class UpdateNode extends ASTNode {
+ public UpdateNode(ASTNode node) {
+ super(node);
+ }
+
+ public UpdateNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/update/UpdateObjNode.java b/sqlTranslate/src/main/java/parser/ast/update/UpdateObjNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..7df2d854ae51719eaa613f38fe4214cc17c25cbb
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/update/UpdateObjNode.java
@@ -0,0 +1,24 @@
+package parser.ast.update;
+
+import parser.ast.ASTNode;
+import lexer.Token;
+
+import java.util.List;
+
+public class UpdateObjNode extends ASTNode {
+ public UpdateObjNode(ASTNode node) {
+ super(node);
+ }
+
+ public UpdateObjNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/update/UpdateSetNode.java b/sqlTranslate/src/main/java/parser/ast/update/UpdateSetNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..55b05a98bafc4ce769bb6414eee9e648461a0243
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/update/UpdateSetNode.java
@@ -0,0 +1,24 @@
+package parser.ast.update;
+
+import parser.ast.ASTNode;
+import lexer.Token;
+
+import java.util.List;
+
+public class UpdateSetNode extends ASTNode {
+ public UpdateSetNode(ASTNode node) {
+ super(node);
+ }
+
+ public UpdateSetNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/update/UpdateWhereNode.java b/sqlTranslate/src/main/java/parser/ast/update/UpdateWhereNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..2c41ad105862331de80441c35438608ec5303335
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/update/UpdateWhereNode.java
@@ -0,0 +1,24 @@
+package parser.ast.update;
+
+import parser.ast.ASTNode;
+import lexer.Token;
+
+import java.util.List;
+
+public class UpdateWhereNode extends ASTNode {
+ public UpdateWhereNode(ASTNode node) {
+ super(node);
+ }
+
+ public UpdateWhereNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/view/ViewCreateNode.java b/sqlTranslate/src/main/java/parser/ast/view/ViewCreateNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..db47fb9832bdf96d91266b90395428a914ef9f8e
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/view/ViewCreateNode.java
@@ -0,0 +1,29 @@
+package parser.ast.view;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.List;
+
+public class ViewCreateNode extends ASTNode {
+
+ public ViewCreateNode() {
+ super();
+ }
+
+ public ViewCreateNode(ASTNode node) {
+ super(node);
+ }
+
+ public ViewCreateNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/view/ViewEndNode.java b/sqlTranslate/src/main/java/parser/ast/view/ViewEndNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..e165677e9938700851716057dda346757f9795d2
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/view/ViewEndNode.java
@@ -0,0 +1,28 @@
+package parser.ast.view;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.List;
+
+public class ViewEndNode extends ASTNode {
+ public ViewEndNode() {
+ super();
+ }
+
+ public ViewEndNode(ASTNode node) {
+ super(node);
+ }
+
+ public ViewEndNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString());
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/view/ViewNameNode.java b/sqlTranslate/src/main/java/parser/ast/view/ViewNameNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..a2c5c4e5500a89a8b9bfcf6e4fa82a7dc13d6134
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/view/ViewNameNode.java
@@ -0,0 +1,24 @@
+package parser.ast.view;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.List;
+
+public class ViewNameNode extends ASTNode {
+ public ViewNameNode(ASTNode node) {
+ super(node);
+ }
+
+ public ViewNameNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/main/java/parser/ast/view/ViewTargetNode.java b/sqlTranslate/src/main/java/parser/ast/view/ViewTargetNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..d5a3d325ca62a08d89fbad8b85a9c11f876069f5
--- /dev/null
+++ b/sqlTranslate/src/main/java/parser/ast/view/ViewTargetNode.java
@@ -0,0 +1,24 @@
+package parser.ast.view;
+
+import lexer.Token;
+import parser.ast.ASTNode;
+
+import java.util.List;
+
+public class ViewTargetNode extends ASTNode {
+ public ViewTargetNode(ASTNode node) {
+ super(node);
+ }
+
+ public ViewTargetNode(List tokens) {
+ super(tokens);
+ }
+
+ @Override
+ public void visit(ASTNode node, StringBuilder queryString) {
+ queryString.append(toString() + " ");
+ for (ASTNode child : getChildren()) {
+ child.visit(child, queryString);
+ }
+ }
+}
diff --git a/sqlTranslate/src/test/java/TestAlterTable.java b/sqlTranslate/src/test/java/TestAlterTable.java
new file mode 100644
index 0000000000000000000000000000000000000000..66f6b507b486a8eb469bcc7d0fabc6bb8ddfd181
--- /dev/null
+++ b/sqlTranslate/src/test/java/TestAlterTable.java
@@ -0,0 +1,54 @@
+import config.CommonConfig;
+import generator.OpenGaussGenerator;
+import lexer.OracleLexer;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import parser.OracleParser;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TestAlterTable {
+ List testSQL = new ArrayList<>();
+ @BeforeEach
+ public void loadData()
+ {
+ testSQL.add("ALTER TABLE employees ADD email VARCHAR2(100);");
+ testSQL.add("ALTER TABLE employees ADD email LONG RAW;");
+ testSQL.add("ALTER TABLE employees DROP COLUMN middle_name;");
+ testSQL.add("ALTER TABLE employees MODIFY salary NUMBER(10,2);");
+ testSQL.add("ALTER TABLE employees MODIFY salary ROWID;");
+ testSQL.add("ALTER TABLE employees RENAME COLUMN first_name TO given_name;");
+ testSQL.add("ALTER TABLE employees ADD CONSTRAINT emp_pk PRIMARY KEY (employee_id);");
+ testSQL.add("ALTER TABLE employees DROP CONSTRAINT emp_pk;");
+ testSQL.add("ALTER TABLE employees RENAME TO staff;");
+ System.out.println("===== test of alter table =====");
+ System.out.println("The source DBMS is: " + CommonConfig.getSourceDB());
+ System.out.println("The target DBMS is: " + CommonConfig.getTargetDB());
+ System.out.println();
+ }
+
+ @Test
+ public void test()
+ {
+ int num = 1;
+ for (String sql : testSQL) {
+ System.out.println("===== test the SQL" + num++ + " =====");
+ System.out.println("Input SQL: " + sql);
+ OracleLexer lexer = new OracleLexer(sql);
+ lexer.printTokens();
+ OracleParser parser = new OracleParser(lexer);
+ ASTNode root = parser.parse();
+ System.out.println("The AST of the input SQL: ");
+ System.out.println(root.getASTString());
+ System.out.println("The query String of the AST parsed from the input SQL: ");
+ System.out.println(root.toQueryString());
+ OpenGaussGenerator generator = new OpenGaussGenerator(root);
+ System.out.println("The converted query String: ");
+ System.out.println(generator.generate());
+
+ System.out.println();
+ }
+ }
+}
diff --git a/sqlTranslate/src/test/java/TestCaseWhen.java b/sqlTranslate/src/test/java/TestCaseWhen.java
new file mode 100644
index 0000000000000000000000000000000000000000..fbdca0eb77093674d949affbf56ca54cf8163a42
--- /dev/null
+++ b/sqlTranslate/src/test/java/TestCaseWhen.java
@@ -0,0 +1,45 @@
+import config.CommonConfig;
+import generator.OpenGaussGenerator;
+import lexer.OracleLexer;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import parser.OracleParser;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TestCaseWhen {
+ List testSQL = new ArrayList<>();
+ @BeforeEach
+ public void loadData()
+ {
+ testSQL.add("CASE WHEN column2 > 0 THEN 'Positive' ELSE 'Non-positive' END");
+ System.out.println("===== test of CaseWhen =====");
+ System.out.println("The source DBMS is: " + CommonConfig.getSourceDB());
+ System.out.println("The target DBMS is: " + CommonConfig.getTargetDB());
+ System.out.println();
+ }
+
+ @Test
+ public void test()
+ {
+ int num = 1;
+ for (String sql : testSQL) {
+ System.out.println("===== test the SQL" + num++ + " =====");
+ System.out.println("Input SQL: " + sql);
+ OracleLexer lexer = new OracleLexer(sql);
+ lexer.printTokens();
+ ASTNode root = OracleParser.parseCaseWhen(lexer.getTokens());
+ System.out.println("The AST of the input SQL: ");
+ System.out.println(root.getASTString());
+ System.out.println("The query String of the AST parsed from the input SQL: ");
+ System.out.println(root.toQueryString());
+ OpenGaussGenerator generator = new OpenGaussGenerator(root);
+ System.out.println("The converted query String: ");
+ System.out.println(generator.generate());
+
+ System.out.println();
+ }
+ }
+}
diff --git a/sqlTranslate/src/test/java/TestCommitRollbackExec.java b/sqlTranslate/src/test/java/TestCommitRollbackExec.java
new file mode 100644
index 0000000000000000000000000000000000000000..f6b3ac8ae9c9ffc1369a6e2b1c4855ad7e883d38
--- /dev/null
+++ b/sqlTranslate/src/test/java/TestCommitRollbackExec.java
@@ -0,0 +1,55 @@
+import config.CommonConfig;
+import generator.OpenGaussGenerator;
+import lexer.OracleLexer;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import parser.OracleParser;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TestCommitRollbackExec {
+ List testSQL = new ArrayList<>();
+ @BeforeEach
+ public void loadData()
+ {
+ testSQL.add("DECLARE\n" +
+ "BEGIN\n" +
+ " INSERT INTO my_table (id, value) VALUES (1, 'test');\n" +
+ " ROLLBACK;\n" +
+ "END;");
+ testSQL.add("DECLARE\n" +
+ "BEGIN\n" +
+ " INSERT INTO my_table (id, value) VALUES (1, 'test');\n" +
+ " COMMIT;\n" +
+ "END;");
+ System.out.println("===== test of Commit, Rollback,Exec =====");
+ System.out.println("The source DBMS is: " + CommonConfig.getSourceDB());
+ System.out.println("The target DBMS is: " + CommonConfig.getTargetDB());
+ System.out.println();
+ }
+
+ @Test
+ public void test()
+ {
+ int num = 1;
+ for (String sql : testSQL) {
+ System.out.println("===== test the SQL" + num++ + " =====");
+ System.out.println("Input SQL: " + sql);
+ OracleLexer lexer = new OracleLexer(sql);
+ lexer.printTokens();
+ OracleParser parser = new OracleParser(lexer);
+ ASTNode root = parser.parse();
+ System.out.println("The AST of the input SQL: ");
+ System.out.println(root.getASTString());
+ System.out.println("The query String of the AST parsed from the input SQL: ");
+ System.out.println(root.toQueryString());
+ OpenGaussGenerator generator = new OpenGaussGenerator(root);
+ System.out.println("The converted query String: ");
+ System.out.println(generator.generate());
+
+ System.out.println();
+ }
+ }
+}
diff --git a/sqlTranslate/src/test/java/TestCreateTable.java b/sqlTranslate/src/test/java/TestCreateTable.java
new file mode 100644
index 0000000000000000000000000000000000000000..4dba8f0ba38a0832794c9759f337a25f1db33c4d
--- /dev/null
+++ b/sqlTranslate/src/test/java/TestCreateTable.java
@@ -0,0 +1,53 @@
+import config.CommonConfig;
+import generator.OpenGaussGenerator;
+import lexer.OracleLexer;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import parser.OracleParser;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TestCreateTable {
+ List testSQL = new ArrayList<>();
+ @BeforeEach
+ public void loadData()
+ {
+ testSQL.add("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)" +
+ ");");
+ System.out.println("===== test of Create table =====");
+ System.out.println("The source DBMS is: " + CommonConfig.getSourceDB());
+ System.out.println("The target DBMS is: " + CommonConfig.getTargetDB());
+ System.out.println();
+ }
+
+ @Test
+ public void test()
+ {
+ int num = 1;
+ for (String sql : testSQL) {
+ System.out.println("===== test the SQL" + num++ + " =====");
+ System.out.println("Input SQL: " + sql);
+ OracleLexer lexer = new OracleLexer(sql);
+ lexer.printTokens();
+ OracleParser parser = new OracleParser(lexer);
+ ASTNode root = parser.parse();
+ System.out.println("The AST of the input SQL: ");
+ System.out.println(root.getASTString());
+ System.out.println("The query String of the AST parsed from the input SQL: ");
+ System.out.println(root.toQueryString());
+ OpenGaussGenerator generator = new OpenGaussGenerator(root);
+ System.out.println("The converted query String: ");
+ System.out.println(generator.generate());
+
+ System.out.println();
+ }
+ }
+}
diff --git a/sqlTranslate/src/test/java/TestDelete.java b/sqlTranslate/src/test/java/TestDelete.java
new file mode 100644
index 0000000000000000000000000000000000000000..1a7b8487fbd23f0fc35c726774429bef2247d83c
--- /dev/null
+++ b/sqlTranslate/src/test/java/TestDelete.java
@@ -0,0 +1,51 @@
+import config.CommonConfig;
+import generator.OpenGaussGenerator;
+import lexer.OracleLexer;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import parser.OracleParser;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TestDelete {
+ List testSQL = new ArrayList<>();
+ @BeforeEach
+ public void loadData()
+ {
+ testSQL.add("DELETE FROM employees e\n" +
+ "WHERE e.department_id IN (\n" +
+ " SELECT d.department_id\n" +
+ " FROM departments d\n" +
+ " WHERE d.department_name = 'Sales'\n" +
+ ");");
+ System.out.println("===== test of Delete =====");
+ System.out.println("The source DBMS is: " + CommonConfig.getSourceDB());
+ System.out.println("The target DBMS is: " + CommonConfig.getTargetDB());
+ System.out.println();
+ }
+
+ @Test
+ public void test()
+ {
+ int num = 1;
+ for (String sql : testSQL) {
+ System.out.println("===== test the SQL" + num++ + " =====");
+ System.out.println("Input SQL: " + sql);
+ OracleLexer lexer = new OracleLexer(sql);
+ lexer.printTokens();
+ OracleParser parser = new OracleParser(lexer);
+ ASTNode root = parser.parse();
+ System.out.println("The AST of the input SQL: ");
+ System.out.println(root.getASTString());
+ System.out.println("The query String of the AST parsed from the input SQL: ");
+ System.out.println(root.toQueryString());
+ OpenGaussGenerator generator = new OpenGaussGenerator(root);
+ System.out.println("The converted query String: ");
+ System.out.println(generator.generate());
+
+ System.out.println();
+ }
+ }
+}
diff --git a/sqlTranslate/src/test/java/TestDropTable.java b/sqlTranslate/src/test/java/TestDropTable.java
new file mode 100644
index 0000000000000000000000000000000000000000..40c6cfbbc22e5ba9063985bf68d40e022d737e81
--- /dev/null
+++ b/sqlTranslate/src/test/java/TestDropTable.java
@@ -0,0 +1,47 @@
+import config.CommonConfig;
+import generator.OpenGaussGenerator;
+import lexer.OracleLexer;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import parser.OracleParser;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TestDropTable {
+ List testSQL = new ArrayList<>();
+ @BeforeEach
+ public void loadData()
+ {
+ testSQL.add("DROP TABLE employees CASCADE CONSTRAINTS;");
+ testSQL.add("DROP TABLE employees;");
+ System.out.println("===== test of Drop table =====");
+ System.out.println("The source DBMS is: " + CommonConfig.getSourceDB());
+ System.out.println("The target DBMS is: " + CommonConfig.getTargetDB());
+ System.out.println();
+ }
+
+ @Test
+ public void test()
+ {
+ int num = 1;
+ for (String sql : testSQL) {
+ System.out.println("===== test the SQL" + num++ + " =====");
+ System.out.println("Input SQL: " + sql);
+ OracleLexer lexer = new OracleLexer(sql);
+ lexer.printTokens();
+ OracleParser parser = new OracleParser(lexer);
+ ASTNode root = parser.parse();
+ System.out.println("The AST of the input SQL: ");
+ System.out.println(root.getASTString());
+ System.out.println("The query String of the AST parsed from the input SQL: ");
+ System.out.println(root.toQueryString());
+ OpenGaussGenerator generator = new OpenGaussGenerator(root);
+ System.out.println("The converted query String: ");
+ System.out.println(generator.generate());
+
+ System.out.println();
+ }
+ }
+}
diff --git a/sqlTranslate/src/test/java/TestException.java b/sqlTranslate/src/test/java/TestException.java
new file mode 100644
index 0000000000000000000000000000000000000000..c19bda7e05b91f2467a21f5d81df15c9bd8b563b
--- /dev/null
+++ b/sqlTranslate/src/test/java/TestException.java
@@ -0,0 +1,53 @@
+import config.CommonConfig;
+import generator.OpenGaussGenerator;
+import lexer.OracleLexer;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import parser.OracleParser;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TestException {
+ List testSQL = new ArrayList<>();
+ @BeforeEach
+ public void loadData()
+ {
+ testSQL.add("EXCEPTION\n" +
+ " WHEN e_custom_exception THEN\n" +
+ " DBMS_OUTPUT.PUT_LINE('Caught an exception: Custom exception raised');\n" +
+ " WHEN ZERO_DIVIDE THEN\n" +
+ " DBMS_OUTPUT.PUT_LINE('Caught an exception: Division by zero');\n" +
+ " WHEN INVALID_NUMBER THEN\n" +
+ " DBMS_OUTPUT.PUT_LINE('Caught an exception: Invalid number');\n" +
+ " WHEN OTHERS THEN\n" +
+ " DBMS_OUTPUT.PUT_LINE('Caught an exception: ' || SQLERRM);");
+ System.out.println("===== test of EXCEPTION =====");
+ System.out.println("The source DBMS is: " + CommonConfig.getSourceDB());
+ System.out.println("The target DBMS is: " + CommonConfig.getTargetDB());
+ System.out.println();
+ }
+
+ @Test
+ public void test()
+ {
+ int num = 1;
+ for (String sql : testSQL) {
+ System.out.println("===== test the SQL" + num++ + " =====");
+ System.out.println("Input SQL: " + sql);
+ OracleLexer lexer = new OracleLexer(sql);
+ lexer.printTokens();
+ ASTNode root = OracleParser.parseException(lexer.getTokens());
+ System.out.println("The AST of the input SQL: ");
+ System.out.println(root.getASTString());
+ System.out.println("The query String of the AST parsed from the input SQL: ");
+ System.out.println(root.toQueryString());
+ OpenGaussGenerator generator = new OpenGaussGenerator(root);
+ System.out.println("The converted query String: ");
+ System.out.println(generator.generate());
+
+ System.out.println();
+ }
+ }
+}
diff --git a/sqlTranslate/src/test/java/TestFunction.java b/sqlTranslate/src/test/java/TestFunction.java
new file mode 100644
index 0000000000000000000000000000000000000000..001e1a076e296ce6501e6dc7d7b8ea41784b80fc
--- /dev/null
+++ b/sqlTranslate/src/test/java/TestFunction.java
@@ -0,0 +1,55 @@
+import config.CommonConfig;
+import generator.OpenGaussGenerator;
+import lexer.OracleLexer;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import parser.OracleParser;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TestFunction {
+ List testSQL = new ArrayList<>();
+ @BeforeEach
+ public void loadData()
+ {
+ testSQL.add("CREATE OR REPLACE FUNCTION string_length (\n" +
+ " input_string VARCHAR2\n" +
+ " ) RETURN NUMBER IS\n" +
+ " BEGIN\n" +
+ " SELECT name, salary INTO v_name, v_salary FROM employees WHERE employee_id = 100;\n" +
+ " RETURN LENGTH(input_string);\n" +
+ " EXCEPTION\n" +
+ " WHEN OTHERS THEN\n" +
+ " DBMS_OUTPUT.PUT_LINE('An error occurred: ' || SQLERRM);\n" +
+ " END;");
+ System.out.println("===== test of Function =====");
+ System.out.println("The source DBMS is: " + CommonConfig.getSourceDB());
+ System.out.println("The target DBMS is: " + CommonConfig.getTargetDB());
+ System.out.println();
+ }
+
+ @Test
+ public void test()
+ {
+ int num = 1;
+ for (String sql : testSQL) {
+ System.out.println("===== test the SQL" + num++ + " =====");
+ System.out.println("Input SQL: " + sql);
+ OracleLexer lexer = new OracleLexer(sql);
+ lexer.printTokens();
+ OracleParser parser = new OracleParser(lexer);
+ ASTNode root = parser.parse();
+ System.out.println("The AST of the input SQL: ");
+ System.out.println(root.getASTString());
+ System.out.println("The query String of the AST parsed from the input SQL: ");
+ System.out.println(root.toQueryString());
+ OpenGaussGenerator generator = new OpenGaussGenerator(root);
+ System.out.println("The converted query String: ");
+ System.out.println(generator.generate());
+
+ System.out.println();
+ }
+ }
+}
diff --git a/sqlTranslate/src/test/java/TestIfElse.java b/sqlTranslate/src/test/java/TestIfElse.java
new file mode 100644
index 0000000000000000000000000000000000000000..4948c7d0b0c593a445375a4a5108e3e28d07ff4f
--- /dev/null
+++ b/sqlTranslate/src/test/java/TestIfElse.java
@@ -0,0 +1,53 @@
+import config.CommonConfig;
+import generator.OpenGaussGenerator;
+import lexer.OracleLexer;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import parser.OracleParser;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TestIfElse {
+ List testSQL = new ArrayList<>();
+ @BeforeEach
+ public void loadData()
+ {
+ testSQL.add("IF v_salary >= 100000 THEN\n" +
+ " v_bonus := v_salary * 0.1;\n" +
+ " ELSIF v_salary >= 50000 THEN\n" +
+ " v_bonus := v_salary * 0.08;\n" +
+ " ELSIF v_salary >= 30000 THEN\n" +
+ " v_bonus := v_salary * 0.05;\n" +
+ " ELSE\n" +
+ " v_bonus := v_salary * 0.03;\n" +
+ " END IF;");
+ System.out.println("===== test of IfElse =====");
+ System.out.println("The source DBMS is: " + CommonConfig.getSourceDB());
+ System.out.println("The target DBMS is: " + CommonConfig.getTargetDB());
+ System.out.println();
+ }
+
+ @Test
+ public void test()
+ {
+ int num = 1;
+ for (String sql : testSQL) {
+ System.out.println("===== test the SQL" + num++ + " =====");
+ System.out.println("Input SQL: " + sql);
+ OracleLexer lexer = new OracleLexer(sql);
+ lexer.printTokens();
+ ASTNode root = OracleParser.parseIFELSE(lexer.getTokens());
+ System.out.println("The AST of the input SQL: ");
+ System.out.println(root.getASTString());
+ System.out.println("The query String of the AST parsed from the input SQL: ");
+ System.out.println(root.toQueryString());
+ OpenGaussGenerator generator = new OpenGaussGenerator(root);
+ System.out.println("The converted query String: ");
+ System.out.println(generator.generate());
+
+ System.out.println();
+ }
+ }
+}
diff --git a/sqlTranslate/src/test/java/TestInsert.java b/sqlTranslate/src/test/java/TestInsert.java
new file mode 100644
index 0000000000000000000000000000000000000000..9abd7f8d5a932abc938b86185ce5f13c1d17b878
--- /dev/null
+++ b/sqlTranslate/src/test/java/TestInsert.java
@@ -0,0 +1,47 @@
+import config.CommonConfig;
+import generator.OpenGaussGenerator;
+import lexer.OracleLexer;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import parser.OracleParser;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TestInsert {
+ List testSQL = new ArrayList<>();
+ @BeforeEach
+ public void loadData()
+ {
+ testSQL.add("INSERT INTO employees (first_name, last_name, email) VALUES ('Jane', 'Smith', 'janesm@example.com');");
+ testSQL.add("INSERT INTO employees VALUES ('Jane', 'Smith', 'janesm@example.com');");
+ System.out.println("===== test of Insert =====");
+ System.out.println("The source DBMS is: " + CommonConfig.getSourceDB());
+ System.out.println("The target DBMS is: " + CommonConfig.getTargetDB());
+ System.out.println();
+ }
+
+ @Test
+ public void test()
+ {
+ int num = 1;
+ for (String sql : testSQL) {
+ System.out.println("===== test the SQL" + num++ + " =====");
+ System.out.println("Input SQL: " + sql);
+ OracleLexer lexer = new OracleLexer(sql);
+ lexer.printTokens();
+ OracleParser parser = new OracleParser(lexer);
+ ASTNode root = parser.parse();
+ System.out.println("The AST of the input SQL: ");
+ System.out.println(root.getASTString());
+ System.out.println("The query String of the AST parsed from the input SQL: ");
+ System.out.println(root.toQueryString());
+ OpenGaussGenerator generator = new OpenGaussGenerator(root);
+ System.out.println("The converted query String: ");
+ System.out.println(generator.generate());
+
+ System.out.println();
+ }
+ }
+}
diff --git a/sqlTranslate/src/test/java/TestJoin.java b/sqlTranslate/src/test/java/TestJoin.java
new file mode 100644
index 0000000000000000000000000000000000000000..c3de0fefe608495889fc6af38724b9f743cf43ae
--- /dev/null
+++ b/sqlTranslate/src/test/java/TestJoin.java
@@ -0,0 +1,46 @@
+import config.CommonConfig;
+import generator.OpenGaussGenerator;
+import lexer.OracleLexer;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import parser.OracleParser;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TestJoin {
+ List testSQL = new ArrayList<>();
+ @BeforeEach
+ public void loadData()
+ {
+ testSQL.add("employees e JOIN departments d using e.department_id = d.department_id;");
+ testSQL.add("employees JOIN departments on employees.department_id = departments.department_id;");
+ System.out.println("===== test of Join =====");
+ System.out.println("The source DBMS is: " + CommonConfig.getSourceDB());
+ System.out.println("The target DBMS is: " + CommonConfig.getTargetDB());
+ System.out.println();
+ }
+
+ @Test
+ public void test()
+ {
+ int num = 1;
+ for (String sql : testSQL) {
+ System.out.println("===== test the SQL" + num++ + " =====");
+ System.out.println("Input SQL: " + sql);
+ OracleLexer lexer = new OracleLexer(sql);
+ lexer.printTokens();
+ ASTNode root = OracleParser.parseJoin(lexer.getTokens());
+ System.out.println("The AST of the input SQL: ");
+ System.out.println(root.getASTString());
+ System.out.println("The query String of the AST parsed from the input SQL: ");
+ System.out.println(root.toQueryString());
+ OpenGaussGenerator generator = new OpenGaussGenerator(root);
+ System.out.println("The converted query String: ");
+ System.out.println(generator.generate());
+
+ System.out.println();
+ }
+ }
+}
diff --git a/sqlTranslate/src/test/java/TestLoop.java b/sqlTranslate/src/test/java/TestLoop.java
new file mode 100644
index 0000000000000000000000000000000000000000..f34f5eb653d20e077768abff4eaca674da04cbcc
--- /dev/null
+++ b/sqlTranslate/src/test/java/TestLoop.java
@@ -0,0 +1,56 @@
+import config.CommonConfig;
+import generator.OpenGaussGenerator;
+import lexer.OracleLexer;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import parser.OracleParser;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TestLoop {
+ List testSQL = new ArrayList<>();
+ @BeforeEach
+ public void loadData()
+ {
+ testSQL.add("LOOP\n" +
+ " DBMS_OUTPUT.PUT_LINE(v_counter);\n" +
+ " v_counter := v_counter + 1;\n" +
+ " EXIT WHEN v_counter > 10;\n" +
+ " END LOOP;");
+ testSQL.add("WHILE v_counter <= 10 LOOP\n" +
+ " DBMS_OUTPUT.PUT_LINE(v_counter);\n" +
+ " v_counter := v_counter + 1;\n" +
+ " END LOOP;");
+ testSQL.add("FOR i IN 1..10 LOOP\n" +
+ " DBMS_OUTPUT.PUT_LINE(i);\n" +
+ " END LOOP;");
+ System.out.println("===== test of Loop =====");
+ System.out.println("The source DBMS is: " + CommonConfig.getSourceDB());
+ System.out.println("The target DBMS is: " + CommonConfig.getTargetDB());
+ System.out.println();
+ }
+
+ @Test
+ public void test()
+ {
+ int num = 1;
+ for (String sql : testSQL) {
+ System.out.println("===== test the SQL" + num++ + " =====");
+ System.out.println("Input SQL: " + sql);
+ OracleLexer lexer = new OracleLexer(sql);
+ lexer.printTokens();
+ ASTNode root = OracleParser.parseLoop(lexer.getTokens());
+ System.out.println("The AST of the input SQL: ");
+ System.out.println(root.getASTString());
+ System.out.println("The query String of the AST parsed from the input SQL: ");
+ System.out.println(root.toQueryString());
+ OpenGaussGenerator generator = new OpenGaussGenerator(root);
+ System.out.println("The converted query String: ");
+ System.out.println(generator.generate());
+
+ System.out.println();
+ }
+ }
+}
diff --git a/sqlTranslate/src/test/java/TestPL.java b/sqlTranslate/src/test/java/TestPL.java
new file mode 100644
index 0000000000000000000000000000000000000000..11cb562d8906cea91617d42213770028333593ce
--- /dev/null
+++ b/sqlTranslate/src/test/java/TestPL.java
@@ -0,0 +1,55 @@
+import config.CommonConfig;
+import generator.OpenGaussGenerator;
+import lexer.OracleLexer;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import parser.OracleParser;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TestPL {
+ List testSQL = new ArrayList<>();
+ @BeforeEach
+ public void loadData()
+ {
+ testSQL.add("DECLARE\n" +
+ " v_name Varchar2(20);\n" +
+ " v_salary employees.salary%TYPE;\n" +
+ " BEGIN\n" +
+ " SELECT name, salary INTO v_name, v_salary FROM employees WHERE employee_id = 100;\n" +
+ " DBMS_OUTPUT.PUT_LINE('Name: ' || v_name || ', Salary: ' || v_salary);\n" +
+ " EXCEPTION\n" +
+ " WHEN NO_DATA_FOUND THEN\n" +
+ " DBMS_OUTPUT.PUT_LINE('No data found.');\n" +
+ " END;");
+ System.out.println("===== test of PL =====");
+ System.out.println("The source DBMS is: " + CommonConfig.getSourceDB());
+ System.out.println("The target DBMS is: " + CommonConfig.getTargetDB());
+ System.out.println();
+ }
+
+ @Test
+ public void test()
+ {
+ int num = 1;
+ for (String sql : testSQL) {
+ System.out.println("===== test the SQL" + num++ + " =====");
+ System.out.println("Input SQL: " + sql);
+ OracleLexer lexer = new OracleLexer(sql);
+ lexer.printTokens();
+ OracleParser parser = new OracleParser(lexer);
+ ASTNode root = parser.parse();
+ System.out.println("The AST of the input SQL: ");
+ System.out.println(root.getASTString());
+ System.out.println("The query String of the AST parsed from the input SQL: ");
+ System.out.println(root.toQueryString());
+ OpenGaussGenerator generator = new OpenGaussGenerator(root);
+ System.out.println("The converted query String: ");
+ System.out.println(generator.generate());
+
+ System.out.println();
+ }
+ }
+}
diff --git a/sqlTranslate/src/test/java/TestProcedure.java b/sqlTranslate/src/test/java/TestProcedure.java
new file mode 100644
index 0000000000000000000000000000000000000000..25d623dd320df53df50ce70d519f8f54d4191225
--- /dev/null
+++ b/sqlTranslate/src/test/java/TestProcedure.java
@@ -0,0 +1,68 @@
+import config.CommonConfig;
+import generator.OpenGaussGenerator;
+import lexer.OracleLexer;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import parser.OracleParser;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TestProcedure {
+ List testSQL = new ArrayList<>();
+ @BeforeEach
+ public void loadData()
+ {
+ testSQL.add("CREATE OR REPLACE PROCEDURE update_salary (\n" +
+ " employee_id IN NUMBER,\n" +
+ " new_salary IN OUT NUMBER\n" +
+ " ) IS\n" +
+ " v_employee employees%ROWTYPE;\n" +
+ " BEGIN\n" +
+ " SELECT * FROM employees WHERE employee_id = employee_id;\n" +
+ " IF new_salary < 3000 THEN\n" +
+ " new_salary := new_salary * 1.1;\n" +
+ " ELSE\n" +
+ " new_salary := new_salary * 1.05;\n" +
+ " END IF;\n" +
+ " UPDATE employees SET salary = new_salary WHERE employee_id = employee_id;\n" +
+ " COMMIT;\n" +
+ " DBMS_OUTPUT.PUT_LINE('Updated Salary: ' || new_salary);\n" +
+ " EXCEPTION\n" +
+ " WHEN NO_DATA_FOUND THEN\n" +
+ " DBMS_OUTPUT.PUT_LINE('Employee not found.');\n" +
+ " WHEN TOO_MANY_ROWS THEN\n" +
+ " DBMS_OUTPUT.PUT_LINE('Multiple employees found.');\n" +
+ " WHEN OTHERS THEN\n" +
+ " DBMS_OUTPUT.PUT_LINE('An error occurred: ' || SQLERRM);\n" +
+ " END update_salary;");
+ System.out.println("===== test of Procedure =====");
+ System.out.println("The source DBMS is: " + CommonConfig.getSourceDB());
+ System.out.println("The target DBMS is: " + CommonConfig.getTargetDB());
+ System.out.println();
+ }
+
+ @Test
+ public void test()
+ {
+ int num = 1;
+ for (String sql : testSQL) {
+ System.out.println("===== test the SQL" + num++ + " =====");
+ System.out.println("Input SQL: " + sql);
+ OracleLexer lexer = new OracleLexer(sql);
+ lexer.printTokens();
+ OracleParser parser = new OracleParser(lexer);
+ ASTNode root = parser.parse();
+ System.out.println("The AST of the input SQL: ");
+ System.out.println(root.getASTString());
+ System.out.println("The query String of the AST parsed from the input SQL: ");
+ System.out.println(root.toQueryString());
+ OpenGaussGenerator generator = new OpenGaussGenerator(root);
+ System.out.println("The converted query String: ");
+ System.out.println(generator.generate());
+
+ System.out.println();
+ }
+ }
+}
diff --git a/sqlTranslate/src/test/java/TestSelect.java b/sqlTranslate/src/test/java/TestSelect.java
new file mode 100644
index 0000000000000000000000000000000000000000..d300b038d5cf4a96c00538d39facb0132a712232
--- /dev/null
+++ b/sqlTranslate/src/test/java/TestSelect.java
@@ -0,0 +1,57 @@
+import config.CommonConfig;
+import generator.OpenGaussGenerator;
+import lexer.OracleLexer;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import parser.OracleParser;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TestSelect {
+ List testSQL = new ArrayList<>();
+ @BeforeEach
+ public void loadData()
+ {
+ testSQL.add("SELECT * FROM employees Union SELECT employee_id, first_name, last_name FROM employees;");
+ testSQL.add("SELECT * FROM employees WHERE department_id = 10;");
+ testSQL.add("SELECT * FROM employees ORDER BY hire_date DESC;");
+ testSQL.add("SELECT COUNT(*), AVG(salary) FROM employees;");
+ testSQL.add("SELECT department_id, COUNT(*) FROM employees GROUP BY department_id;");
+ testSQL.add("SELECT e.first_name, d.department_name FROM employees e JOIN departments d ON e.department_id = d.department_id;");
+ testSQL.add("SELECT\n" +
+ " column1,\n" +
+ " CASE WHEN column2 > 0 THEN 'Positive' ELSE 'Non-positive' END as status,\n" +
+ " SUBSTR(column3, 1, 5) as substring_column3\n" +
+ " FROM table_name;");
+ testSQL.add("SELECT column1, COUNT(column2) FROM table_name GROUP BY column1 HAVING COUNT(column2) > 10;");
+ System.out.println("===== test of Select =====");
+ System.out.println("The source DBMS is: " + CommonConfig.getSourceDB());
+ System.out.println("The target DBMS is: " + CommonConfig.getTargetDB());
+ System.out.println();
+ }
+
+ @Test
+ public void test()
+ {
+ int num = 1;
+ for (String sql : testSQL) {
+ System.out.println("===== test the SQL" + num++ + " =====");
+ System.out.println("Input SQL: " + sql);
+ OracleLexer lexer = new OracleLexer(sql);
+ lexer.printTokens();
+ OracleParser parser = new OracleParser(lexer);
+ ASTNode root = parser.parse();
+ System.out.println("The AST of the input SQL: ");
+ System.out.println(root.getASTString());
+ System.out.println("The query String of the AST parsed from the input SQL: ");
+ System.out.println(root.toQueryString());
+ OpenGaussGenerator generator = new OpenGaussGenerator(root);
+ System.out.println("The converted query String: ");
+ System.out.println(generator.generate());
+
+ System.out.println();
+ }
+ }
+}
diff --git a/sqlTranslate/src/test/java/TestTrigger.java b/sqlTranslate/src/test/java/TestTrigger.java
new file mode 100644
index 0000000000000000000000000000000000000000..a8f2e90c94e4408dacd6712c54af89d59ec2eecb
--- /dev/null
+++ b/sqlTranslate/src/test/java/TestTrigger.java
@@ -0,0 +1,57 @@
+import config.CommonConfig;
+import generator.OpenGaussGenerator;
+import lexer.OracleLexer;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import parser.OracleParser;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TestTrigger {
+ List testSQL = new ArrayList<>();
+ @BeforeEach
+ public void loadData()
+ {
+ testSQL.add("CREATE OR REPLACE TRIGGER log_insert_trigger\n" +
+ " AFTER INSERT ON employees\n" +
+ " FOR EACH ROW\n" +
+ " DECLARE\n" +
+ " l_action VARCHAR2(10) := 'INSERT';\n" +
+ " BEGIN\n" +
+ " INSERT INTO audit_log (action, employee_id) VALUES (l_action, 11);\n" +
+ " DBMS_OUTPUT.PUT_LINE('Inserted record with ID: ' || 11);\n" +
+ " EXCEPTION\n" +
+ " WHEN OTHERS THEN\n" +
+ " DBMS_OUTPUT.PUT_LINE('An error occurred: ' || SQLERRM);\n" +
+ " END;");
+ System.out.println("===== test of Trigger =====");
+ System.out.println("The source DBMS is: " + CommonConfig.getSourceDB());
+ System.out.println("The target DBMS is: " + CommonConfig.getTargetDB());
+ System.out.println();
+ }
+
+ @Test
+ public void test()
+ {
+ int num = 1;
+ for (String sql : testSQL) {
+ System.out.println("===== test the SQL" + num++ + " =====");
+ System.out.println("Input SQL: " + sql);
+ OracleLexer lexer = new OracleLexer(sql);
+ lexer.printTokens();
+ OracleParser parser = new OracleParser(lexer);
+ ASTNode root = parser.parse();
+ System.out.println("The AST of the input SQL: ");
+ System.out.println(root.getASTString());
+ System.out.println("The query String of the AST parsed from the input SQL: ");
+ System.out.println(root.toQueryString());
+ OpenGaussGenerator generator = new OpenGaussGenerator(root);
+ System.out.println("The converted query String: ");
+ System.out.println(generator.generate());
+
+ System.out.println();
+ }
+ }
+}
diff --git a/sqlTranslate/src/test/java/TestUpdate.java b/sqlTranslate/src/test/java/TestUpdate.java
new file mode 100644
index 0000000000000000000000000000000000000000..17ada6166110691b1cfbc57016e5090e643decd3
--- /dev/null
+++ b/sqlTranslate/src/test/java/TestUpdate.java
@@ -0,0 +1,47 @@
+import config.CommonConfig;
+import generator.OpenGaussGenerator;
+import lexer.OracleLexer;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import parser.OracleParser;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TestUpdate {
+ List testSQL = new ArrayList<>();
+ @BeforeEach
+ public void loadData()
+ {
+ testSQL.add("UPDATE employees e JOIN departments d using e.department_id = d.department_id\n" +
+ " SET e.salary = e.salary * 1.10, d.budget = d.budget * 1.10 WHERE d.department_name = 'Sales';");
+ System.out.println("===== test of Update =====");
+ System.out.println("The source DBMS is: " + CommonConfig.getSourceDB());
+ System.out.println("The target DBMS is: " + CommonConfig.getTargetDB());
+ System.out.println();
+ }
+
+ @Test
+ public void test()
+ {
+ int num = 1;
+ for (String sql : testSQL) {
+ System.out.println("===== test the SQL" + num++ + " =====");
+ System.out.println("Input SQL: " + sql);
+ OracleLexer lexer = new OracleLexer(sql);
+ lexer.printTokens();
+ OracleParser parser = new OracleParser(lexer);
+ ASTNode root = parser.parse();
+ System.out.println("The AST of the input SQL: ");
+ System.out.println(root.getASTString());
+ System.out.println("The query String of the AST parsed from the input SQL: ");
+ System.out.println(root.toQueryString());
+ OpenGaussGenerator generator = new OpenGaussGenerator(root);
+ System.out.println("The converted query String: ");
+ System.out.println(generator.generate());
+
+ System.out.println();
+ }
+ }
+}
diff --git a/sqlTranslate/src/test/java/TestView.java b/sqlTranslate/src/test/java/TestView.java
new file mode 100644
index 0000000000000000000000000000000000000000..ecae338a7192421d61cdfb7d531f5af6e710cbeb
--- /dev/null
+++ b/sqlTranslate/src/test/java/TestView.java
@@ -0,0 +1,49 @@
+import config.CommonConfig;
+import generator.OpenGaussGenerator;
+import lexer.OracleLexer;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import parser.OracleParser;
+import parser.ast.ASTNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TestView {
+ List testSQL = new ArrayList<>();
+ @BeforeEach
+ public void loadData()
+ {
+ testSQL.add("CREATE OR REPLACE VIEW employee_details AS SELECT first_name, last_name, salary FROM employees;");
+ testSQL.add("CREATE OR REPLACE VIEW emp_info (full_name, pay) AS SELECT first_name || ' ' || last_name AS full_name, salary AS pay FROM employees;");
+ testSQL.add("CREATE OR REPLACE VIEW emp_dept_info AS SELECT e.first_name, e.last_name, d.department_name FROM employees e JOIN departments d ON e.department_id = d.department_id;");
+ testSQL.add("CREATE OR REPLACE VIEW high_salary_employees AS SELECT first_name, last_name, salary FROM employees WHERE salary > 50000;");
+ System.out.println("===== test of View =====");
+ System.out.println("The source DBMS is: " + CommonConfig.getSourceDB());
+ System.out.println("The target DBMS is: " + CommonConfig.getTargetDB());
+ System.out.println();
+ }
+
+ @Test
+ public void test()
+ {
+ int num = 1;
+ for (String sql : testSQL) {
+ System.out.println("===== test the SQL" + num++ + " =====");
+ System.out.println("Input SQL: " + sql);
+ OracleLexer lexer = new OracleLexer(sql);
+ lexer.printTokens();
+ OracleParser parser = new OracleParser(lexer);
+ ASTNode root = parser.parse();
+ System.out.println("The AST of the input SQL: ");
+ System.out.println(root.getASTString());
+ System.out.println("The query String of the AST parsed from the input SQL: ");
+ System.out.println(root.toQueryString());
+ OpenGaussGenerator generator = new OpenGaussGenerator(root);
+ System.out.println("The converted query String: ");
+ System.out.println(generator.generate());
+
+ System.out.println();
+ }
+ }
+}