From 856f0e6011b0e057f4cd0570643a4b40f8badcf7 Mon Sep 17 00:00:00 2001 From: wenshao Date: Fri, 20 May 2011 07:15:47 +0000 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E8=BF=90=E7=AE=97=E7=AC=A6?= =?UTF-8?q?=E4=BC=98=E5=85=88=E7=BA=A7=E5=88=AB=E5=A4=84=E7=90=86=E4=B8=8D?= =?UTF-8?q?=E5=BD=93=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://code.alibabatech.com/svn/druid/trunk@157 b9813039-fb51-4c41-a8b9-e21c2acb5095 --- .../dialect/mysql/parser/MySqlExprParser.java | 6 +-- .../druid/sql/parser/SQLExprParser.java | 42 +++++++---------- .../com/alibaba/druid/sql/OnlineSQLTest.java | 46 +++++++++++++++---- .../mysql/bvt/AssignmentOperatorsTest.java | 2 +- .../MySqlParameterizedOutputVisitorTest.java | 4 +- src/test/resources/bvt/parser/oracle-14.txt | 2 +- 6 files changed, 62 insertions(+), 40 deletions(-) diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlExprParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlExprParser.java index 23984daa6c..cfb0440bfb 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlExprParser.java @@ -52,7 +52,7 @@ public class MySqlExprParser extends SQLExprParser { public SQLExpr relationalRest(SQLExpr expr) throws ParserException { if (lexer.token() == Token.IDENTIFIER && "REGEXP".equalsIgnoreCase(lexer.stringVal())) { lexer.nextToken(); - SQLExpr rightExp = bitOr(); + SQLExpr rightExp = equality(); rightExp = relationalRest(rightExp); @@ -65,7 +65,7 @@ public class MySqlExprParser extends SQLExprParser { public SQLExpr multiplicativeRest(SQLExpr expr) throws ParserException { if (lexer.token() == Token.IDENTIFIER && "MOD".equalsIgnoreCase(lexer.stringVal())) { lexer.nextToken(); - SQLExpr rightExp = bitOr(); + SQLExpr rightExp = primary(); rightExp = relationalRest(rightExp); @@ -78,7 +78,7 @@ public class MySqlExprParser extends SQLExprParser { public SQLExpr notRationalRest(SQLExpr expr) { if (lexer.token() == Token.IDENTIFIER && "REGEXP".equalsIgnoreCase(lexer.stringVal())) { lexer.nextToken(); - SQLExpr rightExp = bitOr(); + SQLExpr rightExp = primary(); rightExp = relationalRest(rightExp); diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java index 1656892f44..17ecd20811 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java @@ -93,7 +93,6 @@ public class SQLExprParser extends SQLParser { expr = relationalRest(expr); expr = equalityRest(expr); expr = andRest(expr); - expr = xorRest(expr); expr = orRest(expr); return expr; @@ -642,7 +641,7 @@ public class SQLExprParser extends SQLParser { } public final SQLExpr equality() throws ParserException { - SQLExpr expr = relational(); + SQLExpr expr = multiplicative(); return equalityRest(expr); } @@ -650,14 +649,14 @@ public class SQLExprParser extends SQLParser { SQLExpr rightExp; if (lexer.token() == Token.EQ) { lexer.nextToken(); - rightExp = relational(); + rightExp = additive(); rightExp = equalityRest(rightExp); expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Equality, rightExp); } else if (lexer.token() == Token.BANGEQ) { lexer.nextToken(); - rightExp = relational(); + rightExp = additive(); rightExp = equalityRest(rightExp); @@ -754,7 +753,7 @@ public class SQLExprParser extends SQLParser { public final SQLExpr andRest(SQLExpr expr) throws ParserException { if (lexer.token() == Token.AND || lexer.token() == Token.AMPAMP) { lexer.nextToken(); - SQLExpr rightExp = equality(); + SQLExpr rightExp = relational(); expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BooleanAnd, rightExp); expr = andRest(expr); @@ -763,38 +762,31 @@ public class SQLExprParser extends SQLParser { return expr; } - public final SQLExpr xor() throws ParserException { - SQLExpr expr = relational(); - return xorRest(expr); - } - - public final SQLExpr xorRest(SQLExpr expr) throws ParserException { - if (lexer.token() == Token.XOR) { - lexer.nextToken(); - SQLExpr rightExp = equality(); - - expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BooleanAnd, rightExp); - expr = xorRest(expr); - } - return expr; - } - public final SQLExpr or() throws ParserException { SQLExpr expr = and(); return orRest(expr); } public final SQLExpr orRest(SQLExpr expr) throws ParserException { - while (lexer.token() == Token.OR) { + if (lexer.token() == Token.OR) { lexer.nextToken(); - SQLExpr rightExp = and(); + SQLExpr rightExp = relational(); + expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BooleanOr, rightExp); + expr = orRest(expr); + } else if (lexer.token() == Token.XOR) { + lexer.nextToken(); + SQLExpr rightExp = relational(); + + expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BooleanXor, rightExp); + expr = orRest(expr); } + return expr; } public final SQLExpr relational() throws ParserException { - SQLExpr expr = bitOr(); + SQLExpr expr = equality(); return relationalRest(expr); } @@ -804,7 +796,7 @@ public class SQLExprParser extends SQLParser { if (lexer.token() == Token.LT) { lexer.nextToken(); - rightExp = bitOr(); + rightExp = equality(); rightExp = relationalRest(rightExp); diff --git a/src/test/java/com/alibaba/druid/sql/OnlineSQLTest.java b/src/test/java/com/alibaba/druid/sql/OnlineSQLTest.java index cbf9b2a7fb..27499c6121 100644 --- a/src/test/java/com/alibaba/druid/sql/OnlineSQLTest.java +++ b/src/test/java/com/alibaba/druid/sql/OnlineSQLTest.java @@ -4,19 +4,24 @@ import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; +import java.util.List; +import junit.framework.Assert; import junit.framework.TestCase; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlParameterizedOutputVisitor; + public class OnlineSQLTest extends TestCase { - private String url = "jdbc:mysql://10.20.129.146/dragoon_v25monitordb_online"; - private String user = "dragoon"; + + private String url = "jdbc:mysql://10.20.129.146/dragoon_v25monitordb_online"; + private String user = "dragoon"; private String password = "dragoon"; - - - + public void test_list_sql() throws Exception { Connection conn = DriverManager.getConnection(url, user, password); - + int count = 0; String sql = "SELECT id, value FROM m_sql_const"; Statement stmt = conn.createStatement(); @@ -25,13 +30,38 @@ public class OnlineSQLTest extends TestCase { String value = rs.getString(2); System.out.println(value); System.out.println(); + try { + validate(value); + } catch (Exception e) { + e.printStackTrace(); + } count++; } rs.close(); stmt.close(); - + System.out.println("COUNT : " + count); - + conn.close(); } + + void validate(String sql) throws Exception { + + try { + MySqlStatementParser parser = new MySqlStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + + Assert.assertEquals(1, statementList.size()); + + StringBuilder out = new StringBuilder(); + MySqlParameterizedOutputVisitor visitor = new MySqlParameterizedOutputVisitor(out); + statemen.accept(visitor); + + System.out.println(sql); + System.out.println(out.toString()); + } catch (Exception e) { + throw e; + } + } } diff --git a/src/test/java/com/alibaba/druid/sql/mysql/bvt/AssignmentOperatorsTest.java b/src/test/java/com/alibaba/druid/sql/mysql/bvt/AssignmentOperatorsTest.java index 45f1ea22b2..b8207492f5 100644 --- a/src/test/java/com/alibaba/druid/sql/mysql/bvt/AssignmentOperatorsTest.java +++ b/src/test/java/com/alibaba/druid/sql/mysql/bvt/AssignmentOperatorsTest.java @@ -79,7 +79,7 @@ public class AssignmentOperatorsTest extends TestCase { String text = output(stmtList); - Assert.assertEquals("UPDATE t1 SET c1 = 2 WHERE c1 = @var1 := 1;", text); + Assert.assertEquals("UPDATE t1 SET c1 = 2 WHERE c1 = (@var1 := 1);", text); } private String output(List stmtList) { diff --git a/src/test/java/com/alibaba/druid/sql/mysql/bvt/MySqlParameterizedOutputVisitorTest.java b/src/test/java/com/alibaba/druid/sql/mysql/bvt/MySqlParameterizedOutputVisitorTest.java index b807577e46..4d1713f0ff 100644 --- a/src/test/java/com/alibaba/druid/sql/mysql/bvt/MySqlParameterizedOutputVisitorTest.java +++ b/src/test/java/com/alibaba/druid/sql/mysql/bvt/MySqlParameterizedOutputVisitorTest.java @@ -12,8 +12,8 @@ import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlParameterizedOutputVisit public class MySqlParameterizedOutputVisitorTest extends TestCase { public void test_0() throws Exception { - //validate("SELECT * FROM T WHERE ID IN (?, ?, ?)", "SELECT * FROM T WHERE ID IN (##)"); - //validate("SELECT * FROM T WHERE ID = 5", "SELECT * FROM T WHERE ID = ?"); + validate("SELECT * FROM T WHERE ID IN (?, ?, ?)", "SELECT * FROM T WHERE ID IN (##)"); + validate("SELECT * FROM T WHERE ID = 5", "SELECT * FROM T WHERE ID = ?"); validate("SELECT * FROM T WHERE 1 = 0 AND ID = 5", "SELECT * FROM T WHERE 1 = 0 AND ID = ?"); } diff --git a/src/test/resources/bvt/parser/oracle-14.txt b/src/test/resources/bvt/parser/oracle-14.txt index d0055a0b6a..5efa2904aa 100644 --- a/src/test/resources/bvt/parser/oracle-14.txt +++ b/src/test/resources/bvt/parser/oracle-14.txt @@ -15,7 +15,7 @@ SELECT channel_desc, calendar_month_desc, co.country_id, --------------------------- SELECT channel_desc, calendar_month_desc, co.country_id, TO_CHAR(sum(amount_sold), '9,999,999,999') AS SALES$ FROM sales , customers , times , channels , countries co -WHERE sales.time_id = times.time_id AND (sales.cust_id = customers.cust_id AND (sales.channel_id = channels.channel_id AND (customers.country_id = co.country_id AND (channels.channel_desc IN ('Direct Sales', 'Internet') AND (times.calendar_month_desc IN ('2000-09', '2000-10') AND co.country_iso_code IN ('UK', 'US')))))) +WHERE sales.time_id = times.time_id AND sales.cust_id = customers.cust_id AND sales.channel_id = channels.channel_id AND customers.country_id = co.country_id AND (channels.channel_desc IN ('Direct Sales', 'Internet') AND (times.calendar_month_desc IN ('2000-09', '2000-10') AND co.country_iso_code IN ('UK', 'US'))) GROUP BY GROUPING SETS ((channel_desc, calendar_month_desc, co.country_id), (channel_desc, co.country_id), (calendar_month_desc, co.country_id));