From 34685651aae57485995d981f7b8bc9a7dcc3a63f Mon Sep 17 00:00:00 2001 From: wenshao Date: Fri, 15 Jul 2011 05:36:19 +0000 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=85=85=E6=B5=8B=E8=AF=95?= 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@444 b9813039-fb51-4c41-a8b9-e21c2acb5095 --- .../oracle/parser/OracleExprParser.java | 86 +++++++++--------- .../druid/sql/parser/SQLExprParser.java | 90 ++++++++++--------- .../alibaba/druid/pool/benckmark/Case3.java | 2 +- .../bvt/OracleSQLParserResourceTest.java | 10 +-- src/test/resources/bvt/parser/oracle-54.txt | 39 ++++++++ 5 files changed, 135 insertions(+), 92 deletions(-) create mode 100644 src/test/resources/bvt/parser/oracle-54.txt diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java index 4ad2f1166c..f63d820b46 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java @@ -21,7 +21,9 @@ import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLOrderingSpecification; import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr; +import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; import com.alibaba.druid.sql.ast.expr.SQLNumberExpr; +import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr; import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; import com.alibaba.druid.sql.dialect.oracle.ast.OracleOrderBy; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleAggregateExpr; @@ -45,26 +47,13 @@ import com.alibaba.druid.sql.parser.Token; public class OracleExprParser extends SQLExprParser { - - - - - public boolean allowStringAdditive = false; /** * @formatter:off */ - private static final String[] _aggregateFunctions = { - "AVG", "CORR", "COVAR_POP", "COVAR_SAMP", "COUNT" - , "CUME_DIST", "DENSE_RANK", "FIRST", "FIRST_VALUE" - , "LAG", "LAST", "LAST_VALUE", "LEAD", "MAX" - , "MIN", "NTILE", "PERCENT_RANK", "PERCENTILE_CONT", "PERCENTILE_DISC" - , "RANK", "RATIO_TO_REPORT", "REGR_SLOPE", "REGR_INTERCEPT", "REGR_COUNT" - , "REGR_R2", "REGR_AVGX", "REGR_AVGY", "REGR_SXX", "REGR_SYY" - , "REGR_SXY", "ROW_NUMBER", "STDDEV", "STDDEV_POP", "STDDEV_SAMP" - , "SUM", "VAR_POP", "VAR_SAMP", "VARIANCE" - }; + private static final String[] _aggregateFunctions = { "AVG", "CORR", "COVAR_POP", "COVAR_SAMP", "COUNT", "CUME_DIST", "DENSE_RANK", "FIRST", "FIRST_VALUE", "LAG", "LAST", "LAST_VALUE", "LEAD", "MAX", "MIN", "NTILE", "PERCENT_RANK", "PERCENTILE_CONT", "PERCENTILE_DISC", "RANK", "RATIO_TO_REPORT", "REGR_SLOPE", "REGR_INTERCEPT", "REGR_COUNT", "REGR_R2", "REGR_AVGX", + "REGR_AVGY", "REGR_SXX", "REGR_SYY", "REGR_SXY", "ROW_NUMBER", "STDDEV", "STDDEV_POP", "STDDEV_SAMP", "SUM", "VAR_POP", "VAR_SAMP", "VARIANCE" }; public OracleExprParser(Lexer lexer){ super(lexer); @@ -115,18 +104,18 @@ public class OracleExprParser extends SQLExprParser { case EXTRACT: lexer.nextToken(); OracleExtractExpr extract = new OracleExtractExpr(); - + accept(Token.LPAREN); - + extract.setUnit(OracleDateTimeUnit.valueOf(lexer.stringVal())); lexer.nextToken(); - + accept(Token.FROM); - + extract.setFrom(expr()); - + accept(Token.RPAREN); - + return primaryRest(extract); case TIMESTAMP: return primaryRest(parseTimestamp()); @@ -140,7 +129,7 @@ public class OracleExprParser extends SQLExprParser { case BINARY_DOUBLE: OracleBinaryDoubleExpr doubleExpr = new OracleBinaryDoubleExpr(); doubleExpr.setValue(Double.parseDouble(lexer.numberString())); - + lexer.nextToken(); return primaryRest(doubleExpr); case TABLE: @@ -214,57 +203,68 @@ public class OracleExprParser extends SQLExprParser { return super.primary(); } } - - + public SQLExpr primaryRest(SQLExpr expr) throws ParserException { if (lexer.token() == Token.MONKEYS_AT) { lexer.nextToken(); - + OracleDbLinkExpr dblink = new OracleDbLinkExpr(); dblink.setExpr(expr); - + String link = lexer.stringVal(); accept(Token.IDENTIFIER); dblink.setDbLink(link); - + expr = dblink; } - + return super.primaryRest(expr); } - + + protected SQLExpr dotRest(SQLExpr expr) { + if (lexer.token() == Token.LITERAL_ALIAS) { + String name = '"' + lexer.stringVal() + '"'; + lexer.nextToken(); + expr = new SQLPropertyExpr(expr, name); + expr = primaryRest(expr); + + return expr; + } + + return super.dotRest(expr); + } + public OracleDateExpr parseDate() { accept(Token.DATE); - + OracleDateExpr timestamp = new OracleDateExpr(); - + String literal = lexer.stringVal(); timestamp.setLiteral(literal); accept(Token.LITERAL_CHARS); - - + return timestamp; } - + public OracleTimestampExpr parseTimestamp() { accept(Token.TIMESTAMP); - + OracleTimestampExpr timestamp = new OracleTimestampExpr(); - + String literal = lexer.stringVal(); timestamp.setLiteral(literal); accept(Token.LITERAL_CHARS); - + if (identifierEquals("AT")) { lexer.nextToken(); acceptIdentifier("TIME"); acceptIdentifier("ZONE"); - + String timezone = lexer.stringVal(); timestamp.setTimeZone(timezone); accept(Token.LITERAL_CHARS); } - + return timestamp; } @@ -428,24 +428,24 @@ public class OracleExprParser extends SQLExprParser { return item; } - + protected SQLExpr parseInterval() { accept(Token.INTERVAL); - + OracleIntervalExpr interval = new OracleIntervalExpr(); if (lexer.token() != Token.LITERAL_CHARS) { throw new ParserException("syntax error : " + lexer.token()); } interval.setValue(lexer.stringVal()); lexer.nextToken(); - + if (lexer.token() != Token.IDENTIFIER) { throw new ParserException("syntax error : " + lexer.token()); } OracleIntervalType type = OracleIntervalType.valueOf(lexer.stringVal()); interval.setType(type); lexer.nextToken(); - + return interval; } } 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 ddd502a61b..3da6ed0b16 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java @@ -155,7 +155,7 @@ public class SQLExprParser extends SQLParser { lexer.nextToken(); listExpr.getItems().add(expr()); } while (lexer.token() == Token.COMMA); - + sqlExpr = listExpr; } accept(Token.RPAREN); @@ -425,45 +425,7 @@ public class SQLExprParser extends SQLParser { if (lexer.token() == Token.DOT) { lexer.nextToken(); - - if (lexer.token() == Token.STAR) { - lexer.nextToken(); - expr = new SQLPropertyExpr(expr, "*"); - } else { - String name; - - if (lexer.token() == Token.KEY) { - name = "KEY"; - lexer.nextToken(); - } else if (lexer.token() != Token.IDENTIFIER) { - throw new ParserException("error : " + lexer.stringVal()); - } else { - name = lexer.stringVal(); - lexer.nextToken(); - } - - if (lexer.token() == Token.LPAREN) { - lexer.nextToken(); - - SQLMethodInvokeExpr methodInvokeExpr = new SQLMethodInvokeExpr(name); - if (lexer.token() == Token.RPAREN) { - lexer.nextToken(); - } else { - if (lexer.token() == Token.PLUS) { - methodInvokeExpr.getParameters().add(new SQLIdentifierExpr("+")); - lexer.nextToken(); - } else { - exprList(methodInvokeExpr.getParameters()); - } - accept(Token.RPAREN); - } - expr = methodInvokeExpr; - } else { - expr = new SQLPropertyExpr(expr, name); - } - } - - expr = primaryRest(expr); + expr = dotRest(expr); } else if (lexer.token() == Token.COLONEQ) { lexer.nextToken(); SQLExpr rightExp = primary(); @@ -498,6 +460,48 @@ public class SQLExprParser extends SQLParser { return expr; } + protected SQLExpr dotRest(SQLExpr expr) { + if (lexer.token() == Token.STAR) { + lexer.nextToken(); + expr = new SQLPropertyExpr(expr, "*"); + } else { + String name; + + if (lexer.token() == Token.KEY) { + name = "KEY"; + lexer.nextToken(); + } else if (lexer.token() != Token.IDENTIFIER) { + throw new ParserException("error : " + lexer.stringVal()); + } else { + name = lexer.stringVal(); + lexer.nextToken(); + } + + if (lexer.token() == Token.LPAREN) { + lexer.nextToken(); + + SQLMethodInvokeExpr methodInvokeExpr = new SQLMethodInvokeExpr(name); + if (lexer.token() == Token.RPAREN) { + lexer.nextToken(); + } else { + if (lexer.token() == Token.PLUS) { + methodInvokeExpr.getParameters().add(new SQLIdentifierExpr("+")); + lexer.nextToken(); + } else { + exprList(methodInvokeExpr.getParameters()); + } + accept(Token.RPAREN); + } + expr = methodInvokeExpr; + } else { + expr = new SQLPropertyExpr(expr, name); + } + } + + expr = primaryRest(expr); + return expr; + } + public final SQLExpr groupComparisionRest(SQLExpr expr) throws ParserException { return expr; } @@ -802,14 +806,14 @@ public class SQLExprParser extends SQLParser { expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BooleanOr, rightExp); expr = orRest(expr); - } else if (lexer.token() == Token.XOR) { + } else if (lexer.token() == Token.XOR) { lexer.nextToken(); SQLExpr rightExp = and(); expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BooleanXor, rightExp); expr = orRest(expr); } - + return expr; } @@ -821,7 +825,7 @@ public class SQLExprParser extends SQLParser { public SQLExpr relationalRest(SQLExpr expr) throws ParserException { SQLExpr rightExp; - + if (lexer.token() == Token.LT) { lexer.nextToken(); rightExp = equality(); diff --git a/src/test/java/com/alibaba/druid/pool/benckmark/Case3.java b/src/test/java/com/alibaba/druid/pool/benckmark/Case3.java index 0c4edbc8b5..b9009c5173 100644 --- a/src/test/java/com/alibaba/druid/pool/benckmark/Case3.java +++ b/src/test/java/com/alibaba/druid/pool/benckmark/Case3.java @@ -33,7 +33,7 @@ public class Case3 extends TestCase { private String validationQuery = "SELECT 1"; // "SELECT 1"; private int threadCount = 10; private int TEST_COUNT = 3; - final int LOOP_COUNT = 1000 * 1000; + final int LOOP_COUNT = 1000 * 100; private boolean testOnBorrow = false; private String connectionProperties = ""; // "bigStringTryClob=true;clientEncoding=GBK;defaultRowPrefetch=50;serverEncoding=ISO-8859-1"; private String sql = "SELECT 1"; diff --git a/src/test/java/com/alibaba/druid/sql/oracle/bvt/OracleSQLParserResourceTest.java b/src/test/java/com/alibaba/druid/sql/oracle/bvt/OracleSQLParserResourceTest.java index b57c5982bf..0179553c4c 100644 --- a/src/test/java/com/alibaba/druid/sql/oracle/bvt/OracleSQLParserResourceTest.java +++ b/src/test/java/com/alibaba/druid/sql/oracle/bvt/OracleSQLParserResourceTest.java @@ -16,11 +16,11 @@ import com.alibaba.druid.util.JdbcUtils; public class OracleSQLParserResourceTest extends TestCase { public void test_0() throws Exception { - for (int i = 0; i <= 53; ++i) { - String resource = "bvt/parser/oracle-" + i + ".txt"; - exec_test(resource); - } - // exec_test("bvt/parser/oracle-0.txt"); +// for (int i = 0; i <= 53; ++i) { +// String resource = "bvt/parser/oracle-" + i + ".txt"; +// exec_test(resource); +// } + exec_test("bvt/parser/oracle-54.txt"); } public void exec_test(String resource) throws Exception { diff --git a/src/test/resources/bvt/parser/oracle-54.txt b/src/test/resources/bvt/parser/oracle-54.txt new file mode 100644 index 0000000000..2ecca5fded --- /dev/null +++ b/src/test/resources/bvt/parser/oracle-54.txt @@ -0,0 +1,39 @@ +select b.* from ( select * from (select row_.*, rownum rownum_ from ( select * from ( select '1' is_draft,a.IS_DISPLAY,a.score,a.type,a.repository_type,a.GMT_MODIFIED,ID from product_draft a where 1=1 and a.COMPANY_ID = ? and a.REPOSITORY_TYPE in ( ? , ? ) and upper(a.SUBJECT) like upper(?) and a.OWNER_MEMBER_ID in ( ? , ? , ? , ? , ? , ? , ? , ? , ? , ? ) and a.STATUS in ( ? , ? , ? , ? , ? , ? ) union all select '0' is_draft,a.IS_DISPLAY,a.score,a.type,a.repository_type,a.GMT_MODIFIED,ID from product a where a.draft_status = 'no_status' and a.COMPANY_ID = ? and a.REPOSITORY_TYPE in ( ? , ? ) and upper(a.SUBJECT) like upper(?) and a.OWNER_MEMBER_ID in ( ? , ? , ? , ? , ? , ? , ? , ? , ? , ? ) and a.STATUS in ( ? , ? , ? , ? , ? , ? ) ) order by type asc , "GMT_MODIFIED" desc , "ID" desc )row_ where rownum <= ? ) where rownum_ >= ? ) a, (select '1' as is_draft, id, m.ACTION_TRACE,m.TYPE,m.IMAGE_REPOSITORY_IDS,m.SUBJECT,m.MEMBER_ID,m.MEMBER_SEQ, m.REPOSITORY_TYPE,m.STATUS,m.GROUP_ID, m.GROUP_ID2,m.GROUP_ID3,m.GMT_MODIFIED,m.GMT_CREATE,m.COMPANY_ID, m.OWNER_MEMBER_ID,m.OWNER_MEMBER_SEQ,m.IND_BY_ALL,m.IND_BY_GROUP, m.IND_BY_GROUP2,m.IND_BY_GROUP3,m.HAVE_IMAGE,m.IMAGE_COUNT,m.IS_DISPLAY,m.RED_MODEL,m.KEYWORDS,m.EXPORT_TYPE, m.IMAGE_VERSION, m.SCORE from product_draft m union all select '0' as is_draft, id, NULL AS ACTION_TRACE,n.TYPE,n.IMAGE_REPOSITORY_IDS,n.SUBJECT,n.MEMBER_ID,n.MEMBER_SEQ,n.REPOSITORY_TYPE, n.STATUS,n.GROUP_ID,n.GROUP_ID2,n.GROUP_ID3,n.GMT_MODIFIED,n.GMT_CREATE,n.COMPANY_ID,n.OWNER_MEMBER_ID,n.OWNER_MEMBER_SEQ, n.IND_BY_ALL,n.IND_BY_GROUP,n.IND_BY_GROUP2,n.IND_BY_GROUP3,n.HAVE_IMAGE,n.IMAGE_COUNT,n.IS_DISPLAY,n.RED_MODEL,n.KEYWORDS, n.EXPORT_TYPE, n.IMAGE_VERSION, n.SCORE from product n) b where a.is_draft=b.is_draft and a.id=b.id order by b.type asc , b."GMT_MODIFIED" desc , b."ID" desc +--------------------------- +SELECT b.* +FROM (SELECT * + FROM (SELECT row_.*, rownum AS rownum_ + FROM (SELECT * + FROM (SELECT '1' AS is_draft, a.IS_DISPLAY, a.score, a.type, a.repository_type + , a.GMT_MODIFIED, ID + FROM product_draft a + WHERE 1 = 1 AND a.COMPANY_ID = ? AND (a.REPOSITORY_TYPE IN (?, ?) AND upper(a.SUBJECT) LIKE upper(?) AND (a.OWNER_MEMBER_ID IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) AND a.STATUS IN (?, ?, ?, ?, ?, ?))) + UNION ALL + SELECT '0' AS is_draft, a.IS_DISPLAY, a.score, a.type, a.repository_type + , a.GMT_MODIFIED, ID + FROM product a + WHERE a.draft_status = 'no_status' AND a.COMPANY_ID = ? AND (a.REPOSITORY_TYPE IN (?, ?) AND upper(a.SUBJECT) LIKE upper(?) AND (a.OWNER_MEMBER_ID IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) AND a.STATUS IN (?, ?, ?, ?, ?, ?))) + ) + ORDER BY type ASC, "GMT_MODIFIED" DESC, "ID" DESC + ) row_ + WHERE rownum <= ? + ) + WHERE rownum_ >= ? + ) a, (SELECT '1' AS is_draft, id, m.ACTION_TRACE, m.TYPE, m.IMAGE_REPOSITORY_IDS + , m.SUBJECT, m.MEMBER_ID, m.MEMBER_SEQ, m.REPOSITORY_TYPE, m.STATUS + , m.GROUP_ID, m.GROUP_ID2, m.GROUP_ID3, m.GMT_MODIFIED, m.GMT_CREATE + , m.COMPANY_ID, m.OWNER_MEMBER_ID, m.OWNER_MEMBER_SEQ, m.IND_BY_ALL, m.IND_BY_GROUP + , m.IND_BY_GROUP2, m.IND_BY_GROUP3, m.HAVE_IMAGE, m.IMAGE_COUNT, m.IS_DISPLAY + , m.RED_MODEL, m.KEYWORDS, m.EXPORT_TYPE, m.IMAGE_VERSION, m.SCORE + FROM product_draft m + UNION ALL + SELECT '0' AS is_draft, id, NULL AS ACTION_TRACE, n.TYPE, n.IMAGE_REPOSITORY_IDS + , n.SUBJECT, n.MEMBER_ID, n.MEMBER_SEQ, n.REPOSITORY_TYPE, n.STATUS + , n.GROUP_ID, n.GROUP_ID2, n.GROUP_ID3, n.GMT_MODIFIED, n.GMT_CREATE + , n.COMPANY_ID, n.OWNER_MEMBER_ID, n.OWNER_MEMBER_SEQ, n.IND_BY_ALL, n.IND_BY_GROUP + , n.IND_BY_GROUP2, n.IND_BY_GROUP3, n.HAVE_IMAGE, n.IMAGE_COUNT, n.IS_DISPLAY + , n.RED_MODEL, n.KEYWORDS, n.EXPORT_TYPE, n.IMAGE_VERSION, n.SCORE + FROM product n + ) b +WHERE a.is_draft = b.is_draft AND a.id = b.id +ORDER BY b.type ASC, b."GMT_MODIFIED" DESC, b."ID" DESC; \ No newline at end of file