improved sql parser.

This commit is contained in:
wenshao
2017-05-23 15:58:39 +08:00
parent c3f84859da
commit 465b7b34b9
35 changed files with 1205 additions and 260 deletions
@@ -103,7 +103,7 @@ public class DALParserTest extends TestCase {
SQLSetStatement set = (SQLSetStatement) parser.parseStatementList().get(0);
parser.match(Token.EOF);
String output = SQLUtils.toMySqlString(set);
Assert.assertEquals("SET @@sysVar1 = ?", output);
Assert.assertEquals("SET sysVar1 = ?", output);
}
public void testSet_2() throws Exception {
@@ -112,7 +112,7 @@ public class DALParserTest extends TestCase {
SQLSetStatement set = (SQLSetStatement) parser.parseStatementList().get(0);
parser.match(Token.EOF);
String output = SQLUtils.toMySqlString(set);
Assert.assertEquals("SET @@`sysVar1` = ?, @@global.`var2` = 1", output);
Assert.assertEquals("SET `sysVar1` = ?, @@global.`var2` = 1", output);
}
public void testSet_3() throws Exception {
@@ -130,7 +130,7 @@ public class DALParserTest extends TestCase {
SQLSetStatement set = (SQLSetStatement) parser.parseStatementList().get(0);
parser.match(Token.EOF);
String output = SQLUtils.toMySqlString(set);
Assert.assertEquals("SET @@global.var1 = 1, @@var2 = 2", output);
Assert.assertEquals("SET @@global.var1 = 1, var2 = 2", output);
}
public void testSet_5() throws Exception {
@@ -139,7 +139,7 @@ public class DALParserTest extends TestCase {
SQLSetStatement set = (SQLSetStatement) parser.parseStatementList().get(0);
parser.match(Token.EOF);
String output = SQLUtils.toMySqlString(set);
Assert.assertEquals("SET @@global.var1 = 1, @@var2 = 2", output);
Assert.assertEquals("SET @@global.var1 = 1, var2 = 2", output);
}
public void testSetTxn_0() throws Exception {
@@ -112,7 +112,7 @@ public class START_TRANSACTION_Test extends TestCase {
String text = output(stmtList);
Assert.assertEquals("SET @@autocommit = 0;", text);
Assert.assertEquals("SET autocommit = 0;", text);
}
private String output(List<SQLStatement> stmtList) {
@@ -0,0 +1,79 @@
/*
* Copyright 1999-2017 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.bvt.sql.mysql.create;
import com.alibaba.druid.sql.MysqlTest;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
import com.alibaba.druid.util.JdbcConstants;
import java.util.List;
public class MySqlCreateProcedureTest11 extends MysqlTest {
public void test_0() throws Exception {
String sql = "CREATE PROCEDURE curdemo()\n" +
"BEGIN\n" +
" DECLARE done INT DEFAULT FALSE;\n" +
" DECLARE a CHAR(16);\n" +
" DECLARE b, c INT;\n" +
" DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;\n" +
" DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;\n" +
" DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;\n" +
"\n" +
" OPEN cur1;\n" +
" OPEN cur2;\n" +
"\n" +
" read_loop: LOOP\n" +
" FETCH cur1 INTO a, b;\n" +
" FETCH cur2 INTO c;\n" +
" IF done THEN\n" +
" LEAVE read_loop;\n" +
" END IF;\n" +
" IF b < c THEN\n" +
" INSERT INTO test.t3 VALUES (a,b);\n" +
" ELSE\n" +
" INSERT INTO test.t3 VALUES (a,c);\n" +
" END IF;\n" +
" END LOOP;\n" +
"\n" +
" CLOSE cur1;\n" +
" CLOSE cur2;\n" +
"END;";
List<SQLStatement> statementList = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
SQLStatement stmt = statementList.get(0);
// print(statementList);
// assertEquals(1, statementList.size());
System.out.println(SQLUtils.toMySqlString(stmt));
SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(JdbcConstants.MYSQL);
stmt.accept(visitor);
// System.out.println("Tables : " + visitor.getTables());
// System.out.println("fields : " + visitor.getColumns());
// System.out.println("coditions : " + visitor.getConditions());
// System.out.println("orderBy : " + visitor.getOrderByColumns());
assertEquals(3, visitor.getTables().size());
assertEquals(3, visitor.getColumns().size());
assertEquals(2, visitor.getConditions().size());
}
}
@@ -26,13 +26,13 @@ public class MySqlParameterizedOutputVisitorTest_6 extends TestCase {
public void test_0() throws Exception {
String sql = "SET autocommit=1";
String paramSql = "SET @@autocommit = ?";
String paramSql = "SET autocommit = ?";
Assert.assertEquals(ParameterizedOutputVisitorUtils.parameterize(sql, JdbcConstants.MYSQL), paramSql);
}
public void test_1() throws Exception {
String sql = "SET GLOBAL sort_buffer_size=1000000, SESSION sort_buffer_size=1000000;";
String paramSql = "SET @@global.sort_buffer_size = ?, @@sort_buffer_size = ?";
Assert.assertEquals(ParameterizedOutputVisitorUtils.parameterize(sql, JdbcConstants.MYSQL), paramSql);
String paramSql = "SET @@global.sort_buffer_size = ?, sort_buffer_size = ?";
Assert.assertEquals(paramSql, ParameterizedOutputVisitorUtils.parameterize(sql, JdbcConstants.MYSQL));
}
}
@@ -0,0 +1,231 @@
/*
* Copyright 1999-2017 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.bvt.sql.oracle.create;
import com.alibaba.druid.sql.OracleTest;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser;
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor;
import com.alibaba.druid.stat.TableStat;
import com.alibaba.druid.util.JdbcConstants;
import org.junit.Assert;
import java.util.List;
public class OracleCreatePackageTest0 extends OracleTest {
public void test_types() throws Exception {
String sql = //
" CREATE OR REPLACE PACKAGE BODY emp_mgmt AS \n" +
" tot_emps NUMBER; \n" +
" tot_depts NUMBER; \n" +
"FUNCTION hire \n" +
" (last_name VARCHAR2, job_id VARCHAR2, \n" +
" manager_id NUMBER, salary NUMBER, \n" +
" commission_pct NUMBER, department_id NUMBER) \n" +
" RETURN NUMBER IS new_empno NUMBER; \n" +
"BEGIN \n" +
" SELECT employees_seq.NEXTVAL \n" +
" INTO new_empno \n" +
" FROM DUAL; \n" +
" INSERT INTO employees \n" +
" VALUES (new_empno, 'First', 'Last','first.last@oracle.com', \n" +
" '(123)123-1234','18-JUN-02','IT_PROG',90000000,00, \n" +
" 100,110); \n" +
" tot_emps := tot_emps + 1; \n" +
" RETURN(new_empno); \n" +
"END; \n" +
"FUNCTION create_dept(department_id NUMBER, location_id NUMBER) \n" +
" RETURN NUMBER IS \n" +
" new_deptno NUMBER; \n" +
" BEGIN \n" +
" SELECT departments_seq.NEXTVAL \n" +
" INTO new_deptno \n" +
" FROM dual; \n" +
" INSERT INTO departments \n" +
" VALUES (new_deptno, 'department name', 100, 1700); \n" +
" tot_depts := tot_depts + 1; \n" +
" RETURN(new_deptno); \n" +
" END; \n" +
"PROCEDURE remove_emp (employee_id NUMBER) IS \n" +
" BEGIN \n" +
" DELETE FROM employees \n" +
" WHERE employees.employee_id = remove_emp.employee_id; \n" +
" tot_emps := tot_emps - 1; \n" +
" END; \n" +
"PROCEDURE remove_dept(department_id NUMBER) IS \n" +
" BEGIN \n" +
" DELETE FROM departments \n" +
" WHERE departments.department_id = remove_dept.department_id; \n" +
" tot_depts := tot_depts - 1; \n" +
" SELECT COUNT(*) INTO tot_emps FROM employees; \n" +
" END; \n" +
"PROCEDURE increase_sal(employee_id NUMBER, salary_incr NUMBER) IS \n" +
" curr_sal NUMBER; \n" +
" BEGIN \n" +
" SELECT salary INTO curr_sal FROM employees \n" +
" WHERE employees.employee_id = increase_sal.employee_id; \n" +
" IF curr_sal IS NULL \n" +
" THEN RAISE no_sal; \n" +
" ELSE \n" +
" UPDATE employees \n" +
" SET salary = salary + salary_incr \n" +
" WHERE employee_id = employee_id; \n" +
" END IF; \n" +
" END; \n" +
"PROCEDURE increase_comm(employee_id NUMBER, comm_incr NUMBER) IS \n" +
" curr_comm NUMBER; \n" +
" BEGIN \n" +
" SELECT commission_pct \n" +
" INTO curr_comm \n" +
" FROM employees \n" +
" WHERE employees.employee_id = increase_comm.employee_id; \n" +
" IF curr_comm IS NULL \n" +
" THEN RAISE no_comm; \n" +
" ELSE \n" +
" UPDATE employees \n" +
" SET commission_pct = commission_pct + comm_incr; \n" +
" END IF; \n" +
" END; \n" +
"END emp_mgmt; ";
OracleStatementParser parser = new OracleStatementParser(sql);
List<SQLStatement> statementList = parser.parseStatementList();
SQLStatement stmt = statementList.get(0);
print(statementList);
Assert.assertEquals(1, statementList.size());
Assert.assertEquals("CREATE OR REPLACE PACKAGE BODY emp_mgmt\n" +
"BEGIN\n" +
"\ttot_emps NUMBER\n" +
"\ttot_depts NUMBER\n" +
"\tFUNCTION hire (\n" +
"\t\tlast_name VARCHAR2, \n" +
"\t\tjob_id VARCHAR2, \n" +
"\t\tmanager_id NUMBER, \n" +
"\t\tsalary NUMBER, \n" +
"\t\tcommission_pct NUMBER, \n" +
"\t\tdepartment_id NUMBER\n" +
"\t)\n" +
"\tRETURN NUMBER\n" +
"\tIS\n" +
"\tnew_empno NUMBER;\n" +
"\tBEGIN\n" +
"\t\tSELECT employees_seq.NEXTVAL\n" +
"\t\tINTO new_empno\n" +
"\t\tFROM DUAL;\n" +
"\t\tINSERT INTO employees\n" +
"\t\tVALUES (new_empno, 'First', 'Last', 'first.last@oracle.com', '(123)123-1234'\n" +
"\t\t\t, '18-JUN-02', 'IT_PROG', 90000000, 0, 100\n" +
"\t\t\t, 110);\n" +
"\t\ttot_emps := tot_emps + 1;\n" +
"\t\tRETURN(new_empno);\n" +
"\tEND\n" +
"\tFUNCTION create_dept (\n" +
"\t\tdepartment_id NUMBER, \n" +
"\t\tlocation_id NUMBER\n" +
"\t)\n" +
"\tRETURN NUMBER\n" +
"\tIS\n" +
"\tnew_deptno NUMBER;\n" +
"\tBEGIN\n" +
"\t\tSELECT departments_seq.NEXTVAL\n" +
"\t\tINTO new_deptno\n" +
"\t\tFROM dual;\n" +
"\t\tINSERT INTO departments\n" +
"\t\tVALUES (new_deptno, 'department name', 100, 1700);\n" +
"\t\ttot_depts := tot_depts + 1;\n" +
"\t\tRETURN(new_deptno);\n" +
"\tEND\n" +
"\tPROCEDURE remove_emp (\n" +
"\t\temployee_id NUMBER\n" +
"\t)\n" +
"\tIS\n" +
"\tBEGIN\n" +
"\t\tDELETE FROM employees\n" +
"\t\tWHERE employees.employee_id = remove_emp.employee_id;\n" +
"\t\ttot_emps := tot_emps - 1;\n" +
"\tEND\n" +
"\tPROCEDURE remove_dept (\n" +
"\t\tdepartment_id NUMBER\n" +
"\t)\n" +
"\tIS\n" +
"\tBEGIN\n" +
"\t\tDELETE FROM departments\n" +
"\t\tWHERE departments.department_id = remove_dept.department_id;\n" +
"\t\ttot_depts := tot_depts - 1;\n" +
"\t\tSELECT COUNT(*)\n" +
"\t\tINTO tot_emps\n" +
"\t\tFROM employees;\n" +
"\tEND\n" +
"\tPROCEDURE increase_sal (\n" +
"\t\temployee_id NUMBER, \n" +
"\t\tsalary_incr NUMBER\n" +
"\t)\n" +
"\tIS\n" +
"\tcurr_sal NUMBER;\n" +
"\tBEGIN\n" +
"\t\tSELECT salary\n" +
"\t\tINTO curr_sal\n" +
"\t\tFROM employees\n" +
"\t\tWHERE employees.employee_id = increase_sal.employee_id;\n" +
"\t\tIF curr_sal IS NULL THEN\n" +
"\t\t\tRAISE no_sal;\n" +
"\t\tELSE\n" +
"\t\t\tUPDATE employees\n" +
"\t\t\tSET salary = salary + salary_incr\n" +
"\t\t\tWHERE employee_id = employee_id;\n" +
"\t\tEND IF;\n" +
"\tEND\n" +
"\tPROCEDURE increase_comm (\n" +
"\t\temployee_id NUMBER, \n" +
"\t\tcomm_incr NUMBER\n" +
"\t)\n" +
"\tIS\n" +
"\tcurr_comm NUMBER;\n" +
"\tBEGIN\n" +
"\t\tSELECT commission_pct\n" +
"\t\tINTO curr_comm\n" +
"\t\tFROM employees\n" +
"\t\tWHERE employees.employee_id = increase_comm.employee_id;\n" +
"\t\tIF curr_comm IS NULL THEN\n" +
"\t\t\tRAISE no_comm;\n" +
"\t\tELSE\n" +
"\t\t\tUPDATE employees\n" +
"\t\t\tSET commission_pct = commission_pct + comm_incr;\n" +
"\t\tEND IF;\n" +
"\tEND\n" +
"END emp_mgmt;",//
SQLUtils.toSQLString(stmt, JdbcConstants.ORACLE));
OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor();
stmt.accept(visitor);
System.out.println("Tables : " + visitor.getTables());
System.out.println("fields : " + visitor.getColumns());
System.out.println("coditions : " + visitor.getConditions());
System.out.println("relationships : " + visitor.getRelationships());
System.out.println("orderBy : " + visitor.getOrderByColumns());
Assert.assertEquals(2, visitor.getTables().size());
Assert.assertEquals(11, visitor.getColumns().size());
Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "employee_id")));
}
}
@@ -142,7 +142,6 @@ public class Oracle_pl_exception_8 extends OracleTest {
"\t\t\t\tsuffix := suffix + 1;\n" +
"\t\t\t\tname := name || TO_CHAR(suffix);\n" +
"\t\tEND;\n" +
"\t\t;\n" +
"\tEND LOOP;\n" +
"END;\n", //
output);
@@ -189,7 +188,6 @@ public class Oracle_pl_exception_8 extends OracleTest {
"\t\t\t\tsuffix := suffix + 1;\n" +
"\t\t\t\tname := name || TO_CHAR(suffix);\n" +
"\t\tend;\n" +
"\t\t;\n" +
"\tend loop;\n" +
"end;\n", //
output);
@@ -86,7 +86,6 @@ public class Oracle_pl_for_2 extends OracleTest {
"\tLOOP\n" +
"\t\tDELETE FROM employees_temp\n" +
"\t\tWHERE department_id = depts(i);\n" +
"\t\t;\n" +
"\tEND LOOP;\n" +
"END;\n", //
output);
@@ -108,7 +107,6 @@ public class Oracle_pl_for_2 extends OracleTest {
"\tloop\n" +
"\t\tdelete from employees_temp\n" +
"\t\twhere department_id = depts(i);\n" +
"\t\t;\n" +
"\tend loop;\n" +
"end;\n", //
output);