From 8a6bd52078bf10186ae864946979800aa635aaf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=A9=E5=B0=91?= Date: Sat, 31 Mar 2012 22:44:05 +0800 Subject: [PATCH] bug fixed for sql parser && enhance mock driver --- .../alibaba/druid/mock/MockConnection.java | 14 ++++ .../com/alibaba/druid/mock/MockDriver.java | 21 ++---- .../druid/mock/MockPreparedStatement.java | 12 ++++ .../com/alibaba/druid/mock/MockStatement.java | 15 +++- .../druid/sql/parser/SQLExprParser.java | 22 +++--- .../ParameterizedOutputVisitorUtils.java | 4 -- .../bvt/sql/oracle/OracleSelectTest36.java | 69 +++++++++++++++++++ 7 files changed, 126 insertions(+), 31 deletions(-) create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest36.java diff --git a/src/main/java/com/alibaba/druid/mock/MockConnection.java b/src/main/java/com/alibaba/druid/mock/MockConnection.java index 75600031eb..d66a49ac16 100644 --- a/src/main/java/com/alibaba/druid/mock/MockConnection.java +++ b/src/main/java/com/alibaba/druid/mock/MockConnection.java @@ -507,4 +507,18 @@ public class MockConnection implements Connection { throw new SQLFeatureNotSupportedException(); } + public void handleSleep() { + if (getConnectProperties() != null) { + Object propertyValue = getConnectProperties().get("executeSleep"); + + if (propertyValue != null) { + long millis = Long.parseLong(propertyValue.toString()); + try { + Thread.sleep(millis); + } catch (InterruptedException e) { + // skip + } + } + } + } } diff --git a/src/main/java/com/alibaba/druid/mock/MockDriver.java b/src/main/java/com/alibaba/druid/mock/MockDriver.java index c75cb72bd3..2e35d67f41 100644 --- a/src/main/java/com/alibaba/druid/mock/MockDriver.java +++ b/src/main/java/com/alibaba/druid/mock/MockDriver.java @@ -249,20 +249,7 @@ public class MockDriver implements Driver, MockDriverMBean { conn.setLastActiveTimeMillis(System.currentTimeMillis()); - if (conn != null) { - if (conn.getConnectProperties() != null) { - Object propertyValue = conn.getConnectProperties().get("executeSleep"); - - if (propertyValue != null) { - long millis = Long.parseLong(propertyValue.toString()); - try { - Thread.sleep(millis); - } catch (InterruptedException e) { - // skip - } - } - } - } + handleSleep(conn); if ("SELECT value FROM _int_1000_".equalsIgnoreCase(sql)) { MockResultSet rs = new MockResultSet(stmt); @@ -277,6 +264,12 @@ public class MockDriver implements Driver, MockDriverMBean { return this.executeHandler.executeQuery(stmt, sql); } + public void handleSleep(MockConnection conn) { + if (conn != null) { + conn.handleSleep(); + } + } + protected ResultSet createResultSet(MockPreparedStatement stmt) { MockResultSet rs = new MockResultSet(stmt); diff --git a/src/main/java/com/alibaba/druid/mock/MockPreparedStatement.java b/src/main/java/com/alibaba/druid/mock/MockPreparedStatement.java index c7982e12c5..2fef322084 100644 --- a/src/main/java/com/alibaba/druid/mock/MockPreparedStatement.java +++ b/src/main/java/com/alibaba/druid/mock/MockPreparedStatement.java @@ -65,6 +65,10 @@ public class MockPreparedStatement extends MockStatement implements PreparedStat if (mockConnection != null && mockConnection.getDriver() != null) { return mockConnection.getDriver().createResultSet(this); } + + if (mockConnection != null) { + mockConnection.handleSleep(); + } return new MockResultSet(this); } @@ -76,6 +80,10 @@ public class MockPreparedStatement extends MockStatement implements PreparedStat @Override public int executeUpdate() throws SQLException { checkOpen(); + + if (mockConnection != null) { + mockConnection.handleSleep(); + } return 0; } @@ -186,6 +194,10 @@ public class MockPreparedStatement extends MockStatement implements PreparedStat public boolean execute() throws SQLException { checkOpen(); + if (mockConnection != null) { + mockConnection.handleSleep(); + } + return false; } diff --git a/src/main/java/com/alibaba/druid/mock/MockStatement.java b/src/main/java/com/alibaba/druid/mock/MockStatement.java index ef2e9666c1..6e06db780f 100644 --- a/src/main/java/com/alibaba/druid/mock/MockStatement.java +++ b/src/main/java/com/alibaba/druid/mock/MockStatement.java @@ -127,7 +127,11 @@ public class MockStatement implements Statement { @Override public int executeUpdate(String sql) throws SQLException { checkOpen(); - + + if (mockConnection != null) { + mockConnection.handleSleep(); + } + return 0; } @@ -227,6 +231,10 @@ public class MockStatement implements Statement { if (ERROR_SQL.equals(sql)) { throw new SQLException(); } + + if (mockConnection != null) { + mockConnection.handleSleep(); + } return false; } @@ -300,6 +308,11 @@ public class MockStatement implements Statement { @Override public int[] executeBatch() throws SQLException { checkOpen(); + + if (mockConnection != null) { + mockConnection.handleSleep(); + } + return new int[0]; } 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 125102d77d..a6988ec5ff 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java @@ -728,7 +728,7 @@ public class SQLExprParser extends SQLParser { public final SQLExpr bitAnd() throws ParserException { SQLExpr expr = shift(); - return orRest(expr); + return bitAndRest(expr); } public final SQLExpr bitAndRest(SQLExpr expr) throws ParserException { @@ -742,7 +742,7 @@ public class SQLExprParser extends SQLParser { public final SQLExpr bitOr() throws ParserException { SQLExpr expr = bitAnd(); - return orRest(expr); + return bitOrRest(expr); } public final SQLExpr bitOrRest(SQLExpr expr) throws ParserException { @@ -921,43 +921,41 @@ public class SQLExprParser extends SQLParser { if (lexer.token() == Token.LT) { lexer.nextToken(); rightExp = bitOr(); - - rightExp = relationalRest(rightExp); - expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.LessThan, rightExp); +// expr = relationalRest(expr); } else if (lexer.token() == Token.LTEQ) { lexer.nextToken(); rightExp = bitOr(); - rightExp = relationalRest(rightExp); +// rightExp = relationalRest(rightExp); expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.LessThanOrEqual, rightExp); } else if (lexer.token() == Token.LTEQGT) { lexer.nextToken(); rightExp = bitOr(); - rightExp = relationalRest(rightExp); +// rightExp = relationalRest(rightExp); expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.LessThanOrEqualOrGreaterThan, rightExp); } else if (lexer.token() == Token.GT) { lexer.nextToken(); rightExp = bitOr(); - rightExp = relationalRest(rightExp); +// rightExp = relationalRest(rightExp); expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.GreaterThan, rightExp); } else if (lexer.token() == Token.GTEQ) { lexer.nextToken(); rightExp = bitOr(); - rightExp = relationalRest(rightExp); +// rightExp = relationalRest(rightExp); expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.GreaterThanOrEqual, rightExp); } else if (lexer.token() == Token.BANGLT) { lexer.nextToken(); rightExp = bitOr(); - rightExp = relationalRest(rightExp); +// rightExp = relationalRest(rightExp); expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.NotLessThan, rightExp); } else if (lexer.token() == Token.BANGGT) { @@ -971,14 +969,14 @@ public class SQLExprParser extends SQLParser { lexer.nextToken(); rightExp = bitOr(); - rightExp = relationalRest(rightExp); +// rightExp = relationalRest(rightExp); expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.LessThanOrGreater, rightExp); } else if (lexer.token() == Token.LIKE) { lexer.nextToken(); rightExp = bitOr(); - rightExp = relationalRest(rightExp); +// rightExp = relationalRest(rightExp); expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.Like, rightExp); diff --git a/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedOutputVisitorUtils.java b/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedOutputVisitorUtils.java index c5cd686420..c5cb5c1f99 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedOutputVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedOutputVisitorUtils.java @@ -2,8 +2,6 @@ package com.alibaba.druid.sql.visitor; import java.util.List; -import junit.framework.Assert; - import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; @@ -27,8 +25,6 @@ public class ParameterizedOutputVisitorUtils { List statementList = parser.parseStatementList(); SQLStatement statemen = statementList.get(0); - Assert.assertEquals(1, statementList.size()); - StringBuilder out = new StringBuilder(); SQLASTOutputVisitor visitor = createParameterizedOutputVisitor(out, dbType); statemen.accept(visitor); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest36.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest36.java new file mode 100644 index 0000000000..347c3785f5 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleSelectTest36.java @@ -0,0 +1,69 @@ +package com.alibaba.druid.bvt.sql.oracle; + +import java.util.List; + +import junit.framework.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; +import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator; +import com.alibaba.druid.sql.ast.statement.SQLSelect; +import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; +import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +public class OracleSelectTest36 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "select ID,name from druid_test where (name>=? or name is null) and card_id statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + + { + SQLSelect select = ((SQLSelectStatement) statemen).getSelect(); + SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) select.getQuery(); + SQLBinaryOpExpr where = (SQLBinaryOpExpr) queryBlock.getWhere(); + Assert.assertEquals(SQLBinaryOperator.BooleanAnd, where.getOperator()); + + SQLBinaryOpExpr left = (SQLBinaryOpExpr) where.getLeft(); + Assert.assertEquals(SQLBinaryOperator.BooleanOr, left.getOperator()); + + SQLBinaryOpExpr nameGTEQ = (SQLBinaryOpExpr) left.getLeft(); + Assert.assertEquals(SQLBinaryOperator.GreaterThanOrEqual, nameGTEQ.getOperator()); + + SQLBinaryOpExpr nameIS = (SQLBinaryOpExpr) left.getRight(); + Assert.assertEquals(SQLBinaryOperator.Is, nameIS.getOperator()); + } + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.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(1, visitor.getTables().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("druid_test"))); + + Assert.assertEquals(3, visitor.getColumns().size()); + + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("druid_test", "ID"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("druid_test", "name"))); + Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("druid_test", "card_id"))); + + // Assert.assertTrue(visitor.getOrderByColumns().contains(new TableStat.Column("employees", "last_name"))); + } +}