mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improved sql parser.
This commit is contained in:
@@ -20,6 +20,7 @@ import com.alibaba.druid.sql.ast.SQLDataTypeImpl;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.*;
|
||||
import com.alibaba.druid.sql.ast.statement.*;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleWithSubqueryEntry;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleSysdateExpr;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.*;
|
||||
import com.alibaba.druid.util.FnvHash;
|
||||
@@ -762,6 +763,13 @@ public class SQLTransformUtils {
|
||||
return y;
|
||||
}
|
||||
|
||||
if (x instanceof OracleWithSubqueryEntry) {
|
||||
SQLWithSubqueryClause.Entry entry = new SQLWithSubqueryClause.Entry();
|
||||
((OracleWithSubqueryEntry) x).cloneTo(entry);
|
||||
entry.setParent(x.getParent());
|
||||
return entry;
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ public class SQLWithSubqueryClause extends SQLObjectImpl {
|
||||
protected SQLSelect subQuery;
|
||||
protected SQLStatement returningStatement;
|
||||
|
||||
protected void cloneTo(Entry x) {
|
||||
public void cloneTo(Entry x) {
|
||||
for (SQLName column : columns) {
|
||||
SQLName column2 = column.clone();
|
||||
column2.setParent(x);
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ public class OracleWithSubqueryEntry extends Entry implements OracleSQLObject {
|
||||
this.accept0((OracleASTVisitor) visitor);
|
||||
}
|
||||
|
||||
protected void cloneTo(OracleWithSubqueryEntry x) {
|
||||
public void cloneTo(OracleWithSubqueryEntry x) {
|
||||
super.cloneTo(x);
|
||||
|
||||
if (searchClause != null) {
|
||||
|
||||
@@ -885,17 +885,6 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(OracleCursorExpr x) {
|
||||
print0(ucase ? "CURSOR(" : "cursor(");
|
||||
this.indentCount++;
|
||||
println();
|
||||
x.getQuery().accept(this);
|
||||
this.indentCount--;
|
||||
println();
|
||||
print(')');
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleCursorExpr x) {
|
||||
|
||||
+1825
-18
File diff suppressed because it is too large
Load Diff
@@ -37,6 +37,8 @@ import com.alibaba.druid.sql.ast.statement.SQLMergeStatement.MergeUpdateClause;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLWhileStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleSegmentAttributes;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLDeclareStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleCursorExpr;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDatetimeExpr;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreatePackageStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleForStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.parser.OracleFunctionDataType;
|
||||
@@ -2668,7 +2670,8 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
|
||||
if (left instanceof SQLJoinTableSource
|
||||
&& ((SQLJoinTableSource) left).getJoinType() == JoinType.COMMA
|
||||
&& x.getJoinType() != JoinType.COMMA) {
|
||||
&& x.getJoinType() != JoinType.COMMA
|
||||
&& !JdbcConstants.POSTGRESQL.equals(dbType)) {
|
||||
print('(');
|
||||
printTableSource(left);
|
||||
print(')');
|
||||
@@ -5388,4 +5391,33 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
this.ucase = isEnabled(VisitorFeature.OutputUCase);
|
||||
this.parameterized = isEnabled(VisitorFeature.OutputParameterized);
|
||||
}
|
||||
|
||||
/////////////// for oracle
|
||||
public boolean visit(OracleCursorExpr x) {
|
||||
print0(ucase ? "CURSOR(" : "cursor(");
|
||||
this.indentCount++;
|
||||
println();
|
||||
x.getQuery().accept(this);
|
||||
this.indentCount--;
|
||||
println();
|
||||
print(')');
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(OracleDatetimeExpr x) {
|
||||
x.getExpr().accept(this);
|
||||
SQLExpr timeZone = x.getTimeZone();
|
||||
|
||||
if (timeZone instanceof SQLIdentifierExpr) {
|
||||
if (((SQLIdentifierExpr) timeZone).getName().equalsIgnoreCase("LOCAL")) {
|
||||
print0(ucase ? " AT LOCAL" : "alter session set ");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
print0(ucase ? " AT TIME ZONE " : " at time zone ");
|
||||
timeZone.accept(this);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
package com.alibaba.druid.bvt.sql.oracle;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class SQLSortTest extends TestCase {
|
||||
public void test_sort() throws Exception {
|
||||
String sql = "CREATE TABLE \"ECC_FND\".\"FORM_URL\" \n" +
|
||||
" (\t\"FORM_URL_ID\" NUMBER(10,0) NOT NULL ENABLE, \n" +
|
||||
"\t\"FORM_ID\" NUMBER(10,0) NOT NULL ENABLE, \n" +
|
||||
"\t\"URL\" VARCHAR2(1024) NOT NULL ENABLE, \n" +
|
||||
"\t\"OPR_TYPE\" VARCHAR2(16) DEFAULT 'ADD' NOT NULL ENABLE, \n" +
|
||||
"\t\"ENABLE_FLAG\" VARCHAR2(10) DEFAULT 'T' NOT NULL ENABLE, \n" +
|
||||
"\t CONSTRAINT \"PK_FORM_URL12\" PRIMARY KEY (\"FORM_URL_ID\")\n" +
|
||||
" USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS \n" +
|
||||
" STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645\n" +
|
||||
" PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)\n" +
|
||||
" TABLESPACE \"ECC_IDX_TSP\" ENABLE, \n" +
|
||||
"\t CONSTRAINT \"FK_REFERE83\" FOREIGN KEY (\"FORM_ID\")\n" +
|
||||
"\t REFERENCES \"ECC_FND\".\"FORM\" (\"FORM_ID\") ENABLE\n" +
|
||||
" ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING\n" +
|
||||
" STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645\n" +
|
||||
" PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)\n" +
|
||||
" TABLESPACE \"ECC_TSP\"; \n" +
|
||||
" \n" +
|
||||
" \n" +
|
||||
" \n" +
|
||||
" \n" +
|
||||
" \n" +
|
||||
" CREATE TABLE \"ECC_FND\".\"FORM\" \n" +
|
||||
" (\t\"FORM_ID\" NUMBER(10,0) NOT NULL ENABLE, \n" +
|
||||
"\t\"NAME\" VARCHAR2(32) NOT NULL ENABLE, \n" +
|
||||
"\t\"CODE\" VARCHAR2(128), \n" +
|
||||
"\t\"DESCRIPTION\" VARCHAR2(1024) NOT NULL ENABLE, \n" +
|
||||
"\t\"FORM_TYPE_ID\" NUMBER(10,0) NOT NULL ENABLE, \n" +
|
||||
"\t\"ENABLE_FLAG\" VARCHAR2(10) NOT NULL ENABLE, \n" +
|
||||
"\t CONSTRAINT \"PK_FORM7\" PRIMARY KEY (\"FORM_ID\")\n" +
|
||||
" USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS \n" +
|
||||
" STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645\n" +
|
||||
" PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)\n" +
|
||||
" TABLESPACE \"ECC_IDX_TSP\" ENABLE\n" +
|
||||
" ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING\n" +
|
||||
" STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645\n" +
|
||||
" PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)\n" +
|
||||
" TABLESPACE \"ECC_TSP\" ";
|
||||
|
||||
String sortedSql = SQLUtils.sort(sql, JdbcConstants.ORACLE);
|
||||
assertEquals("CREATE TABLE \"ECC_FND\".\"FORM\" (\n" +
|
||||
"\t\"FORM_ID\" NUMBER(10, 0) NOT NULL ENABLE,\n" +
|
||||
"\t\"NAME\" VARCHAR2(32) NOT NULL ENABLE,\n" +
|
||||
"\t\"CODE\" VARCHAR2(128),\n" +
|
||||
"\t\"DESCRIPTION\" VARCHAR2(1024) NOT NULL ENABLE,\n" +
|
||||
"\t\"FORM_TYPE_ID\" NUMBER(10, 0) NOT NULL ENABLE,\n" +
|
||||
"\t\"ENABLE_FLAG\" VARCHAR2(10) NOT NULL ENABLE,\n" +
|
||||
"\tCONSTRAINT \"PK_FORM7\" PRIMARY KEY (\"FORM_ID\")\n" +
|
||||
"\t\tUSING INDEX\n" +
|
||||
"\t\tPCTFREE 10\n" +
|
||||
"\t\tINITRANS 2\n" +
|
||||
"\t\tMAXTRANS 255\n" +
|
||||
"\t\tTABLESPACE \"ECC_IDX_TSP\"\n" +
|
||||
"\t\tSTORAGE (\n" +
|
||||
"\t\t\tINITIAL 65536\n" +
|
||||
"\t\t\tNEXT 1048576\n" +
|
||||
"\t\t\tMINEXTENTS 1\n" +
|
||||
"\t\t\tMAXEXTENTS 2147483645\n" +
|
||||
"\t\t\tPCTINCREASE 0\n" +
|
||||
"\t\t\tFREELISTS 1\n" +
|
||||
"\t\t\tFREELIST GROUPS 1\n" +
|
||||
"\t\t\tBUFFER_POOL DEFAULT\n" +
|
||||
"\t\t)\n" +
|
||||
"\t\tCOMPUTE STATISTICS\n" +
|
||||
"\t\tENABLE\n" +
|
||||
")\n" +
|
||||
"PCTFREE 10\n" +
|
||||
"PCTUSED 40\n" +
|
||||
"INITRANS 1\n" +
|
||||
"MAXTRANS 255\n" +
|
||||
"NOCOMPRESS\n" +
|
||||
"LOGGING\n" +
|
||||
"TABLESPACE \"ECC_TSP\"\n" +
|
||||
"STORAGE (\n" +
|
||||
"\tINITIAL 65536\n" +
|
||||
"\tNEXT 1048576\n" +
|
||||
"\tMINEXTENTS 1\n" +
|
||||
"\tMAXEXTENTS 2147483645\n" +
|
||||
"\tPCTINCREASE 0\n" +
|
||||
"\tFREELISTS 1\n" +
|
||||
"\tFREELIST GROUPS 1\n" +
|
||||
"\tBUFFER_POOL DEFAULT\n" +
|
||||
")\n" +
|
||||
"CREATE TABLE \"ECC_FND\".\"FORM_URL\" (\n" +
|
||||
"\t\"FORM_URL_ID\" NUMBER(10, 0) NOT NULL ENABLE,\n" +
|
||||
"\t\"FORM_ID\" NUMBER(10, 0) NOT NULL ENABLE,\n" +
|
||||
"\t\"URL\" VARCHAR2(1024) NOT NULL ENABLE,\n" +
|
||||
"\t\"OPR_TYPE\" VARCHAR2(16) DEFAULT 'ADD' NOT NULL ENABLE,\n" +
|
||||
"\t\"ENABLE_FLAG\" VARCHAR2(10) DEFAULT 'T' NOT NULL ENABLE,\n" +
|
||||
"\tCONSTRAINT \"PK_FORM_URL12\" PRIMARY KEY (\"FORM_URL_ID\")\n" +
|
||||
"\t\tUSING INDEX\n" +
|
||||
"\t\tPCTFREE 10\n" +
|
||||
"\t\tINITRANS 2\n" +
|
||||
"\t\tMAXTRANS 255\n" +
|
||||
"\t\tTABLESPACE \"ECC_IDX_TSP\"\n" +
|
||||
"\t\tSTORAGE (\n" +
|
||||
"\t\t\tINITIAL 65536\n" +
|
||||
"\t\t\tNEXT 1048576\n" +
|
||||
"\t\t\tMINEXTENTS 1\n" +
|
||||
"\t\t\tMAXEXTENTS 2147483645\n" +
|
||||
"\t\t\tPCTINCREASE 0\n" +
|
||||
"\t\t\tFREELISTS 1\n" +
|
||||
"\t\t\tFREELIST GROUPS 1\n" +
|
||||
"\t\t\tBUFFER_POOL DEFAULT\n" +
|
||||
"\t\t)\n" +
|
||||
"\t\tCOMPUTE STATISTICS\n" +
|
||||
"\t\tENABLE,\n" +
|
||||
"\tCONSTRAINT \"FK_REFERE83\" FOREIGN KEY (\"FORM_ID\")\n" +
|
||||
"\t\tREFERENCES \"ECC_FND\".\"FORM\" (\"FORM_ID\") ENABLE\n" +
|
||||
")\n" +
|
||||
"PCTFREE 10\n" +
|
||||
"PCTUSED 40\n" +
|
||||
"INITRANS 1\n" +
|
||||
"MAXTRANS 255\n" +
|
||||
"NOCOMPRESS\n" +
|
||||
"LOGGING\n" +
|
||||
"TABLESPACE \"ECC_TSP\"\n" +
|
||||
"STORAGE (\n" +
|
||||
"\tINITIAL 65536\n" +
|
||||
"\tNEXT 1048576\n" +
|
||||
"\tMINEXTENTS 1\n" +
|
||||
"\tMAXEXTENTS 2147483645\n" +
|
||||
"\tPCTINCREASE 0\n" +
|
||||
"\tFREELISTS 1\n" +
|
||||
"\tFREELIST GROUPS 1\n" +
|
||||
"\tBUFFER_POOL DEFAULT\n" +
|
||||
");", sortedSql);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.alibaba.druid.bvt.sql.oracle;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class SQLSortTest_1 extends TestCase {
|
||||
public void test_sort() throws Exception {
|
||||
String sql = "create view v1 as select * from v0; create view v0 as select * from t;";
|
||||
|
||||
String sortedSql = SQLUtils.sort(sql, JdbcConstants.ORACLE);
|
||||
assertEquals("CREATE VIEW v0\n" +
|
||||
"AS\n" +
|
||||
"SELECT *\n" +
|
||||
"FROM t;\n" +
|
||||
"CREATE VIEW v1\n" +
|
||||
"AS\n" +
|
||||
"SELECT *\n" +
|
||||
"FROM v0;", sortedSql);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.alibaba.druid.demo.sql;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitorAdapter;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectTableReference;
|
||||
import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitorAdapter;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class MySqlVisitorDemo extends TestCase {
|
||||
public void test_for_demo() throws Exception {
|
||||
String sql = "select * from mytable a where a.id = 3";
|
||||
List<SQLStatement> stmtList = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
|
||||
|
||||
ExportTableAliasVisitor visitor = new ExportTableAliasVisitor();
|
||||
for (SQLStatement stmt : stmtList) {
|
||||
stmt.accept(visitor);
|
||||
}
|
||||
|
||||
SQLTableSource tableSource = visitor.getAliasMap().get("a");
|
||||
System.out.println(tableSource);
|
||||
}
|
||||
|
||||
public static class ExportTableAliasVisitor extends MySqlASTVisitorAdapter {
|
||||
private Map<String, SQLTableSource> aliasMap = new HashMap<String, SQLTableSource>();
|
||||
public boolean visit(SQLExprTableSource x) {
|
||||
String alias = x.getAlias();
|
||||
aliasMap.put(alias, x);
|
||||
return true;
|
||||
}
|
||||
|
||||
public Map<String, SQLTableSource> getAliasMap() {
|
||||
return aliasMap;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.alibaba.druid.demo.sql;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectTableReference;
|
||||
@@ -18,7 +17,7 @@ public class OracleVisitorDemo extends TestCase {
|
||||
String sql = "select * from mytable a where a.id = 3";
|
||||
List<SQLStatement> stmtList = SQLUtils.parseStatements(sql, JdbcConstants.ORACLE);
|
||||
|
||||
MyOracleVisitor visitor = new MyOracleVisitor();
|
||||
ExportTableAliasVisitor visitor = new ExportTableAliasVisitor();
|
||||
for (SQLStatement stmt : stmtList) {
|
||||
stmt.accept(visitor);
|
||||
}
|
||||
@@ -27,7 +26,7 @@ public class OracleVisitorDemo extends TestCase {
|
||||
System.out.println(tableSource);
|
||||
}
|
||||
|
||||
public static class MyOracleVisitor extends OracleASTVisitorAdapter {
|
||||
public static class ExportTableAliasVisitor extends OracleASTVisitorAdapter {
|
||||
private Map<String, SQLTableSource> aliasMap = new HashMap<String, SQLTableSource>();
|
||||
public boolean visit(OracleSelectTableReference x) {
|
||||
String alias = x.getAlias();
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.alibaba.druid.demo.sql;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitorAdapter;
|
||||
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGASTVisitorAdapter;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class PGVisitorDemo extends TestCase {
|
||||
public void test_for_demo() throws Exception {
|
||||
String sql = "select * from mytable a where a.id = 3";
|
||||
List<SQLStatement> stmtList = SQLUtils.parseStatements(sql, JdbcConstants.POSTGRESQL);
|
||||
|
||||
ExportTableAliasVisitor visitor = new ExportTableAliasVisitor();
|
||||
for (SQLStatement stmt : stmtList) {
|
||||
stmt.accept(visitor);
|
||||
}
|
||||
|
||||
SQLTableSource tableSource = visitor.getAliasMap().get("a");
|
||||
System.out.println(tableSource);
|
||||
}
|
||||
|
||||
public static class ExportTableAliasVisitor extends PGASTVisitorAdapter {
|
||||
private Map<String, SQLTableSource> aliasMap = new HashMap<String, SQLTableSource>();
|
||||
public boolean visit(SQLExprTableSource x) {
|
||||
String alias = x.getAlias();
|
||||
aliasMap.put(alias, x);
|
||||
return true;
|
||||
}
|
||||
|
||||
public Map<String, SQLTableSource> getAliasMap() {
|
||||
return aliasMap;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user