From 0b1387b9ea0dacbea1dc43adce2e1b695cde2763 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=A9=E5=B0=91?= Date: Sun, 6 May 2012 17:55:16 +0800 Subject: [PATCH] add demo --- .../ast/statement/MySqlSelectQueryBlock.java | 25 +- .../alibaba/druid/sql/oracle/demo/Demo2.java | 37 ++- .../alibaba/druid/sql/oracle/demo/Demo3.java | 226 ++++++++++++++++++ 3 files changed, 274 insertions(+), 14 deletions(-) create mode 100644 src/test/java/com/alibaba/druid/sql/oracle/demo/Demo3.java diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSelectQueryBlock.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSelectQueryBlock.java index a08dfa2e22..c34e49abec 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSelectQueryBlock.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlSelectQueryBlock.java @@ -23,11 +23,12 @@ import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.SQLObjectImpl; import com.alibaba.druid.sql.ast.SQLOrderBy; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; +import com.alibaba.druid.sql.dialect.mysql.ast.MySqlObject; import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor; import com.alibaba.druid.sql.visitor.SQLASTVisitor; @SuppressWarnings("serial") -public class MySqlSelectQueryBlock extends SQLSelectQueryBlock { +public class MySqlSelectQueryBlock extends SQLSelectQueryBlock implements MySqlObject { private boolean hignPriority; private boolean straightJoin; @@ -158,6 +159,28 @@ public class MySqlSelectQueryBlock extends SQLSelectQueryBlock { @Override protected void accept0(SQLASTVisitor visitor) { + if (visitor instanceof MySqlASTVisitor) { + accept0((MySqlASTVisitor) visitor); + return; + } + + if (visitor.visit(this)) { + acceptChild(visitor, this.selectList); + acceptChild(visitor, this.from); + acceptChild(visitor, this.where); + acceptChild(visitor, this.groupBy); + acceptChild(visitor, this.orderBy); + acceptChild(visitor, this.limit); + acceptChild(visitor, this.procedureName); + acceptChild(visitor, this.procedureArgumentList); + acceptChild(visitor, this.into); + } + + visitor.endVisit(this); + } + + @Override + public void accept0(MySqlASTVisitor visitor) { if (visitor.visit(this)) { acceptChild(visitor, this.selectList); acceptChild(visitor, this.from); diff --git a/src/test/java/com/alibaba/druid/sql/oracle/demo/Demo2.java b/src/test/java/com/alibaba/druid/sql/oracle/demo/Demo2.java index 069d1e125d..fab8c81c9b 100644 --- a/src/test/java/com/alibaba/druid/sql/oracle/demo/Demo2.java +++ b/src/test/java/com/alibaba/druid/sql/oracle/demo/Demo2.java @@ -10,6 +10,7 @@ import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; +import com.alibaba.druid.sql.ast.expr.SQLNumericLiteralExpr; import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr; import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; @@ -20,7 +21,7 @@ import com.alibaba.druid.sql.parser.SQLStatementParser; public class Demo2 extends TestCase { public void test_0() throws Exception { - String sql = "select * from user where uid = ? and uname = ?"; + String sql = "select * from user where uid = 2 and uname = ?"; List parameters = new ArrayList(); parameters.add(1); parameters.add("wenshao"); @@ -33,13 +34,19 @@ public class Demo2 extends TestCase { MyVisitor visitor = new MyVisitor(); first.accept(visitor); - SQLVariantRefExpr firstVar = visitor.getVariantList().get(0); - int varIndex = (Integer) firstVar.getAttribute("varIndex"); - Integer param = (Integer) parameters.get(varIndex); + SQLExpr firstVar = visitor.getVariantList().get(0); - final String tableName; - if (param.intValue() == 1) { + int userId; + if (firstVar instanceof SQLVariantRefExpr) { + int varIndex = (Integer) firstVar.getAttribute("varIndex"); + userId = (Integer) parameters.get(varIndex); + } else { + userId = ((SQLNumericLiteralExpr) firstVar).getNumber().intValue(); + } + + String tableName; + if (userId == 1) { tableName = "user_1"; } else { tableName = "user_x"; @@ -71,7 +78,7 @@ public class Demo2 extends TestCase { private static class MyVisitor extends MySqlASTVisitorAdapter { private int varIndex = 0; - private List variantList = new ArrayList(); + private List variantList = new ArrayList(); private List tableSourceList = new ArrayList(); public boolean visit(SQLVariantRefExpr x) { @@ -80,11 +87,15 @@ public class Demo2 extends TestCase { } public boolean visit(SQLBinaryOpExpr x) { - if (x.getLeft() instanceof SQLIdentifierExpr && x.getRight() instanceof SQLVariantRefExpr) { - SQLIdentifierExpr identExpr = (SQLIdentifierExpr) x.getLeft(); - String ident = identExpr.getName(); - if (ident.equals("uid")) { - variantList.add((SQLVariantRefExpr) x.getRight()); + if (x.getLeft() instanceof SQLIdentifierExpr) { + if (x.getRight() instanceof SQLVariantRefExpr) { + SQLIdentifierExpr identExpr = (SQLIdentifierExpr) x.getLeft(); + String ident = identExpr.getName(); + if (ident.equals("uid")) { + variantList.add(x.getRight()); + } + } else if (x.getRight() instanceof SQLNumericLiteralExpr) { + variantList.add(x.getRight()); } } @@ -104,7 +115,7 @@ public class Demo2 extends TestCase { this.varIndex = varIndex; } - public List getVariantList() { + public List getVariantList() { return variantList; } diff --git a/src/test/java/com/alibaba/druid/sql/oracle/demo/Demo3.java b/src/test/java/com/alibaba/druid/sql/oracle/demo/Demo3.java new file mode 100644 index 0000000000..0b67f4388a --- /dev/null +++ b/src/test/java/com/alibaba/druid/sql/oracle/demo/Demo3.java @@ -0,0 +1,226 @@ +package com.alibaba.druid.sql.oracle.demo; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import junit.framework.TestCase; + +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.expr.SQLBinaryOpExpr; +import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; +import com.alibaba.druid.sql.ast.expr.SQLNumericLiteralExpr; +import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr; +import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; +import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; +import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock; +import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitorAdapter; +import com.alibaba.druid.sql.parser.SQLStatementParser; + +public class Demo3 extends TestCase { + + public void test_0() throws Exception { + String sql = "select * from user u where u.uid = 2 and uname = ?"; + List parameters = new ArrayList(); + parameters.add(1); + parameters.add("wenshao"); + + String realSql = convert(sql, parameters); + System.out.println(realSql); + } + + public void test_1() throws Exception { + String sql = "select * from user where uid = ? and uname = ?"; + List parameters = new ArrayList(); + parameters.add(1); + parameters.add("wenshao"); + + String realSql = convert(sql, parameters); + System.out.println(realSql); + } + + public void test_2() throws Exception { + String sql = "select * from (select * from user where uid = ? and uname = ?) t"; + List parameters = new ArrayList(); + parameters.add(1); + parameters.add("wenshao"); + + String realSql = convert(sql, parameters); + System.out.println(realSql); + } + + public void test_3() throws Exception { + String sql = "select * from groups where uid = ? and uname = ?"; + List parameters = new ArrayList(); + parameters.add(1); + parameters.add("wenshao"); + + String realSql = convert(sql, parameters); + System.out.println(realSql); + } + + private String convert(String sql, List parameters) { + SQLStatementParser parser = new MySqlStatementParser(sql); + List stmtList = parser.parseStatementList(); // + + SQLStatement first = (SQLStatement) stmtList.get(0); + + MyVisitor visitor = new MyVisitor(); + first.accept(visitor); + + if (visitor.getVariantList().size() > 0) { + SQLExpr firstVar = visitor.getVariantList().get(0); + + int userId; + if (firstVar instanceof SQLVariantRefExpr) { + int varIndex = (Integer) firstVar.getAttribute("varIndex"); + userId = (Integer) parameters.get(varIndex); + } else { + userId = ((SQLNumericLiteralExpr) firstVar).getNumber().intValue(); + } + + String tableName; + if (userId == 1) { + tableName = "user_1"; + } else { + tableName = "user_x"; + } + + for (SQLExprTableSource tableSource : visitor.getTableSourceList()) { + SQLExpr expr = tableSource.getExpr(); + if (expr instanceof SQLIdentifierExpr) { + SQLIdentifierExpr identExpr = (SQLIdentifierExpr) expr; + String ident = identExpr.getName(); + + if (ident.equals("user")) { + identExpr.setName(tableName); + } + } else if (expr instanceof SQLPropertyExpr) { + SQLPropertyExpr proExpr = (SQLPropertyExpr) expr; + String ident = proExpr.getName(); + + if (ident.equals("user")) { + proExpr.setName(tableName); + } + } + } + } + + String realSql = SQLUtils.toOracleString(first); + return realSql; + } + + private static class MyVisitor extends MySqlASTVisitorAdapter { + + private int varIndex = 0; + private List variantList = new ArrayList(); + private List tableSourceList = new ArrayList(); + + private Map tableAlias = new HashMap(); + private String defaultTableName; + + public boolean visit(SQLVariantRefExpr x) { + x.getAttributes().put("varIndex", varIndex++); + return true; + } + + public boolean visit(SQLBinaryOpExpr x) { + if (isUserId(x.getLeft())) { + if (x.getRight() instanceof SQLVariantRefExpr) { + SQLIdentifierExpr identExpr = (SQLIdentifierExpr) x.getLeft(); + String ident = identExpr.getName(); + if (ident.equals("uid")) { + variantList.add(x.getRight()); + } + } else if (x.getRight() instanceof SQLNumericLiteralExpr) { + variantList.add(x.getRight()); + } + } + + return true; + } + + private boolean isUserId(SQLExpr x) { + if (x instanceof SQLIdentifierExpr) { + if ("user".equals(defaultTableName) && "uid".equals(((SQLIdentifierExpr) x).getName())) { + return true; + } + + return false; + } + + if (x instanceof SQLPropertyExpr) { + SQLPropertyExpr propExpr = (SQLPropertyExpr) x; + + String columnName = propExpr.getName(); + + if (!"uid".equals(columnName)) { + return false; + } + + if (propExpr.getOwner() instanceof SQLIdentifierExpr) { + String ownerName = ((SQLIdentifierExpr) propExpr.getOwner()).getName(); + if ("user".equals(ownerName) || "user".equals(tableAlias.get(ownerName))) { + return true; + } + } + } + return false; + } + + public boolean visit(SQLExprTableSource x) { + recordTableSource(x); + + return true; + } + + private String recordTableSource(SQLExprTableSource x) { + if (x.getExpr() instanceof SQLIdentifierExpr) { + String tableName = ((SQLIdentifierExpr) x.getExpr()).getName(); + + if (x.getAlias() != null) { + tableAlias.put(x.getAlias(), tableName); + } + + if ("user".equals(tableName)) { + if (!tableSourceList.contains(x)) { + tableSourceList.add(x); + } + } + + return tableName; + } + + return null; + } + + public boolean visit(SQLSelectQueryBlock queryBlock) { + if (queryBlock.getFrom() instanceof SQLExprTableSource) { + defaultTableName = recordTableSource((SQLExprTableSource) queryBlock.getFrom()); + } + return true; + } + + public boolean visit(MySqlSelectQueryBlock queryBlock) { + if (queryBlock.getFrom() instanceof SQLExprTableSource) { + defaultTableName = recordTableSource((SQLExprTableSource) queryBlock.getFrom()); + } + return true; + } + + public List getVariantList() { + return variantList; + } + + public List getTableSourceList() { + return tableSourceList; + } + + } + +}