From 9722e3aeea5f7974a1dbd767663fc3ba0ecc9f1f Mon Sep 17 00:00:00 2001 From: wenshao Date: Fri, 26 Jul 2013 01:01:58 +0800 Subject: [PATCH] add db2 PageUtils support --- pom.xml | 7 -- .../com/alibaba/druid/sql/PagerUtils.java | 55 +++++++++++++++- .../java/com/alibaba/druid/sql/SQLUtils.java | 12 ++++ .../com/alibaba/druid/sql/ast/SQLOver.java | 11 ++++ .../druid/sql/dialect/db2/ast/DB2Object.java | 24 +++++++ .../db2/ast/stmt/DB2SelectQueryBlock.java | 39 ++++++++++- .../sql/dialect/db2/parser/DB2ExprParser.java | 15 +++++ .../sql/dialect/db2/parser/DB2Lexer.java | 19 ++++++ .../dialect/db2/parser/DB2SelectParser.java | 16 ++++- .../db2/parser/DB2StatementParser.java | 15 +++++ .../dialect/db2/visitor/DB2ASTVisitor.java | 20 +++++- .../db2/visitor/DB2ASTVisitorAdapter.java | 26 ++++++++ .../dialect/db2/visitor/DB2OutputVisitor.java | 38 ++++++++++- .../db2/visitor/DB2SchemaStatVisitor.java | 12 ++++ .../druid/wall/spi/DB2WallVisitor.java | 15 +++++ .../bvt/sql/PagerUtilsTest_Limit_db2_0.java | 53 +++++++++++++++ .../druid/bvt/sql/db2/DB2SelectTest_0.java | 65 +++++++++++++++++++ .../druid/bvt/sql/db2/DB2SelectTest_1.java | 65 +++++++++++++++++++ .../java/com/alibaba/druid/sql/DB2Test.java | 45 +++++++++++++ 19 files changed, 538 insertions(+), 14 deletions(-) create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/db2/ast/DB2Object.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/PagerUtilsTest_Limit_db2_0.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/db2/DB2SelectTest_0.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/db2/DB2SelectTest_1.java create mode 100644 src/test/java/com/alibaba/druid/sql/DB2Test.java diff --git a/pom.xml b/pom.xml index 6af37599b3..8bb15ad0e6 100644 --- a/pom.xml +++ b/pom.xml @@ -527,12 +527,5 @@ 2.0.2 test - - - com.yammer.metrics - metrics-core - 2.2.0 - test - diff --git a/src/main/java/com/alibaba/druid/sql/PagerUtils.java b/src/main/java/com/alibaba/druid/sql/PagerUtils.java index 8457e27ced..3e441c5429 100644 --- a/src/main/java/com/alibaba/druid/sql/PagerUtils.java +++ b/src/main/java/com/alibaba/druid/sql/PagerUtils.java @@ -18,6 +18,8 @@ package com.alibaba.druid.sql; import java.util.List; import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.SQLOrderBy; +import com.alibaba.druid.sql.ast.SQLOver; import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.expr.SQLAggregateExpr; import com.alibaba.druid.sql.ast.expr.SQLAllColumnExpr; @@ -86,6 +88,10 @@ public class PagerUtils { return limitOracle(select, dbType, offset, count); } + if (JdbcConstants.DB2.equals(dbType)) { + return limitDB2(select, dbType, offset, count); + } + if (query instanceof SQLSelectQueryBlock) { return limitQueryBlock(select, dbType, offset, count); } @@ -104,6 +110,53 @@ public class PagerUtils { throw new UnsupportedOperationException(); } + private static String limitDB2(SQLSelect select, String dbType, int offset, int count) { + SQLSelectQuery query = select.getQuery(); + + if (query instanceof SQLSelectQueryBlock) { + DB2SelectQueryBlock queryBlock = (DB2SelectQueryBlock) query; + if (offset <= 0) { + queryBlock.setFirst(new SQLNumberExpr(count)); + return SQLUtils.toSQLString(select, dbType); + } + + SQLAggregateExpr aggregateExpr = new SQLAggregateExpr("ROW_NUMBER"); + SQLOrderBy orderBy = select.getOrderBy(); + if (orderBy != null) { + aggregateExpr.setOver(new SQLOver(orderBy)); + select.setOrderBy(null); + } + + queryBlock.getSelectList().add(new SQLSelectItem(aggregateExpr, "ROWNUM")); + + DB2SelectQueryBlock countQueryBlock = new DB2SelectQueryBlock(); + countQueryBlock.getSelectList().add(new SQLSelectItem(new SQLAllColumnExpr())); + + countQueryBlock.setFrom(new SQLSubqueryTableSource(select, "XX")); + + SQLBinaryOpExpr gt = new SQLBinaryOpExpr(new SQLIdentifierExpr("ROWNUM"), // + SQLBinaryOperator.GreaterThan, // + new SQLNumberExpr(offset)); + SQLBinaryOpExpr lteq = new SQLBinaryOpExpr(new SQLIdentifierExpr("ROWNUM"), // + SQLBinaryOperator.LessThanOrEqual, // + new SQLNumberExpr(count + offset)); + SQLBinaryOpExpr pageCondition = new SQLBinaryOpExpr(gt, SQLBinaryOperator.BooleanAnd, lteq); + + countQueryBlock.setWhere(pageCondition); + + // DB2SelectQueryBlock offsetQueryBlock = new DB2SelectQueryBlock(); + // offsetQueryBlock.getSelectList().add(new SQLSelectItem(new SQLAllColumnExpr())); + // offsetQueryBlock.setFrom(new SQLSubqueryTableSource(new SQLSelect(countQueryBlock), "XXX")); + // offsetQueryBlock.setWhere(new SQLBinaryOpExpr(new SQLIdentifierExpr("RN"), // + // SQLBinaryOperator.GreaterThan, // + // new SQLNumberExpr(offset))); + + return SQLUtils.toSQLString(countQueryBlock, dbType); + } + + return SQLUtils.toSQLString(select, dbType); + } + private static String limitOracle(SQLSelect select, String dbType, int offset, int count) { SQLSelectQuery query = select.getQuery(); @@ -227,7 +280,7 @@ public class PagerUtils { if (JdbcConstants.SQL_SERVER.equals(dbType)) { return new SQLServerSelectQueryBlock(); } - + if (JdbcConstants.DB2.equals(dbType)) { return new DB2SelectQueryBlock(); } diff --git a/src/main/java/com/alibaba/druid/sql/SQLUtils.java b/src/main/java/com/alibaba/druid/sql/SQLUtils.java index 4cd4b91f0f..a327234a88 100644 --- a/src/main/java/com/alibaba/druid/sql/SQLUtils.java +++ b/src/main/java/com/alibaba/druid/sql/SQLUtils.java @@ -63,6 +63,10 @@ public class SQLUtils { if (JdbcUtils.POSTGRESQL.equals(dbType)) { return toPGString(sqlObject); } + + if (JdbcUtils.DB2.equals(dbType)) { + return toDB2String(sqlObject); + } return toSQLServerString(sqlObject); } @@ -110,6 +114,14 @@ public class SQLUtils { String sql = out.toString(); return sql; } + + public static String toDB2String(SQLObject sqlObject) { + StringBuilder out = new StringBuilder(); + sqlObject.accept(new DB2OutputVisitor(out)); + + String sql = out.toString(); + return sql; + } public static String toSQLServerString(SQLObject sqlObject) { StringBuilder out = new StringBuilder(); diff --git a/src/main/java/com/alibaba/druid/sql/ast/SQLOver.java b/src/main/java/com/alibaba/druid/sql/ast/SQLOver.java index e2d1822ab3..f793cc05ac 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/SQLOver.java +++ b/src/main/java/com/alibaba/druid/sql/ast/SQLOver.java @@ -26,6 +26,14 @@ public class SQLOver extends SQLObjectImpl { protected final List partitionBy = new ArrayList(); protected SQLOrderBy orderBy; + + public SQLOver() { + + } + + public SQLOver(SQLOrderBy orderBy) { + this.setOrderBy(orderBy); + } @Override protected void accept0(SQLASTVisitor visitor) { @@ -41,6 +49,9 @@ public class SQLOver extends SQLObjectImpl { } public void setOrderBy(SQLOrderBy orderBy) { + if (orderBy != null) { + orderBy.setParent(this); + } this.orderBy = orderBy; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/ast/DB2Object.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/ast/DB2Object.java new file mode 100644 index 0000000000..fe2a660f70 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/ast/DB2Object.java @@ -0,0 +1,24 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.druid.sql.dialect.db2.ast; + +import com.alibaba.druid.sql.ast.SQLObject; +import com.alibaba.druid.sql.dialect.db2.visitor.DB2ASTVisitor; + + +public interface DB2Object extends SQLObject { + void accept0(DB2ASTVisitor visitor); +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/ast/stmt/DB2SelectQueryBlock.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/ast/stmt/DB2SelectQueryBlock.java index 24ead6662c..cdcab5d47b 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/db2/ast/stmt/DB2SelectQueryBlock.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/ast/stmt/DB2SelectQueryBlock.java @@ -15,11 +15,46 @@ */ package com.alibaba.druid.sql.dialect.db2.ast.stmt; +import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; +import com.alibaba.druid.sql.dialect.db2.ast.DB2Object; +import com.alibaba.druid.sql.dialect.db2.visitor.DB2ASTVisitor; +import com.alibaba.druid.sql.visitor.SQLASTVisitor; -public class DB2SelectQueryBlock extends SQLSelectQueryBlock { +public class DB2SelectQueryBlock extends SQLSelectQueryBlock implements DB2Object { + + private SQLExpr first; private static final long serialVersionUID = 1L; - + public SQLExpr getFirst() { + return first; + } + + public void setFirst(SQLExpr first) { + this.first = first; + } + + + @Override + protected void accept0(SQLASTVisitor visitor) { + if (visitor instanceof DB2ASTVisitor) { + accept0((DB2ASTVisitor) visitor); + return; + } + + super.accept0(visitor); + } + + @Override + public void accept0(DB2ASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, this.selectList); + acceptChild(visitor, this.from); + acceptChild(visitor, this.where); + acceptChild(visitor, this.groupBy); + acceptChild(visitor, this.first); + } + visitor.endVisit(this); + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2ExprParser.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2ExprParser.java index eaeadf00e9..86c8d68b51 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2ExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2ExprParser.java @@ -1,3 +1,18 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.alibaba.druid.sql.dialect.db2.parser; import com.alibaba.druid.sql.parser.Lexer; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2Lexer.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2Lexer.java index 66cfc0604d..cf7a7444a0 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2Lexer.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2Lexer.java @@ -1,3 +1,18 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.alibaba.druid.sql.dialect.db2.parser; import java.util.HashMap; @@ -17,6 +32,10 @@ public class DB2Lexer extends Lexer { map.putAll(Keywords.DEFAULT_KEYWORDS.getKeywords()); + map.put("FETCH", Token.FETCH); + map.put("FIRST", Token.FIRST); + map.put("ONLY", Token.ONLY); + DEFAULT_DB2_KEYWORDS = new Keywords(map); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2SelectParser.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2SelectParser.java index f7c9ad9491..13abc8d994 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2SelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2SelectParser.java @@ -15,10 +15,11 @@ */ package com.alibaba.druid.sql.dialect.db2.parser; +import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLSetQuantifier; import com.alibaba.druid.sql.ast.statement.SQLSelectQuery; -import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2SelectQueryBlock; +import com.alibaba.druid.sql.parser.ParserException; import com.alibaba.druid.sql.parser.SQLExprParser; import com.alibaba.druid.sql.parser.SQLSelectParser; import com.alibaba.druid.sql.parser.Token; @@ -49,7 +50,7 @@ public class DB2SelectParser extends SQLSelectParser { } accept(Token.SELECT); - + if (lexer.token() == Token.COMMENT) { lexer.nextToken(); } @@ -74,6 +75,17 @@ public class DB2SelectParser extends SQLSelectParser { parseWhere(queryBlock); parseGroupBy(queryBlock); + + if (lexer.token() == Token.FETCH) { + lexer.nextToken(); + accept(Token.FIRST); + SQLExpr first = this.exprParser.primary(); + queryBlock.setFirst(first); + if (identifierEquals("ROW") || identifierEquals("ROWS")) { + lexer.nextToken(); + } + accept(Token.ONLY); + } return queryRest(queryBlock); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2StatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2StatementParser.java index 6f81d7ffc0..92f71a291c 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2StatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/parser/DB2StatementParser.java @@ -1,3 +1,18 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.alibaba.druid.sql.dialect.db2.parser; import com.alibaba.druid.sql.parser.Lexer; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ASTVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ASTVisitor.java index b7ce9438bf..439442e7fd 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ASTVisitor.java @@ -1,8 +1,26 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.alibaba.druid.sql.dialect.db2.visitor; +import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2SelectQueryBlock; import com.alibaba.druid.sql.visitor.SQLASTVisitor; - public interface DB2ASTVisitor extends SQLASTVisitor { + boolean visit(DB2SelectQueryBlock x); + + void endVisit(DB2SelectQueryBlock x); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ASTVisitorAdapter.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ASTVisitorAdapter.java index 0ad9ec85ed..9e6a9bbedc 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ASTVisitorAdapter.java @@ -1,7 +1,33 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.alibaba.druid.sql.dialect.db2.visitor; +import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2SelectQueryBlock; import com.alibaba.druid.sql.visitor.SQLASTVisitorAdapter; public class DB2ASTVisitorAdapter extends SQLASTVisitorAdapter implements DB2ASTVisitor { + @Override + public boolean visit(DB2SelectQueryBlock x) { + return true; + } + + @Override + public void endVisit(DB2SelectQueryBlock x) { + + } + } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2OutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2OutputVisitor.java index 9e2adb0f91..a1c4ee79b4 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2OutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2OutputVisitor.java @@ -1,10 +1,46 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.alibaba.druid.sql.dialect.db2.visitor; +import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; +import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2SelectQueryBlock; import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; - public class DB2OutputVisitor extends SQLASTOutputVisitor implements DB2ASTVisitor { + public DB2OutputVisitor(Appendable appender){ super(appender); } + + @Override + public boolean visit(DB2SelectQueryBlock x) { + this.visit((SQLSelectQueryBlock) x); + + if (x.getFirst() != null) { + println(); + print("FETCH FIRST "); + x.getFirst().accept(this); + print(" ROWS ONLY"); + } + + return false; + } + + @Override + public void endVisit(DB2SelectQueryBlock x) { + + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2SchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2SchemaStatVisitor.java index 5ae94a43c0..c444b0a879 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2SchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2SchemaStatVisitor.java @@ -15,6 +15,8 @@ */ package com.alibaba.druid.sql.dialect.db2.visitor; +import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; +import com.alibaba.druid.sql.dialect.db2.ast.stmt.DB2SelectQueryBlock; import com.alibaba.druid.sql.visitor.SchemaStatVisitor; import com.alibaba.druid.util.JdbcUtils; @@ -25,4 +27,14 @@ public class DB2SchemaStatVisitor extends SchemaStatVisitor implements DB2ASTVis return JdbcUtils.DB2; } + @Override + public boolean visit(DB2SelectQueryBlock x) { + return this.visit((SQLSelectQueryBlock) x); + } + + @Override + public void endVisit(DB2SelectQueryBlock x) { + + } + } diff --git a/src/main/java/com/alibaba/druid/wall/spi/DB2WallVisitor.java b/src/main/java/com/alibaba/druid/wall/spi/DB2WallVisitor.java index f6b69567f8..c928312ec1 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/DB2WallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/DB2WallVisitor.java @@ -1,3 +1,18 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.alibaba.druid.wall.spi; import java.util.ArrayList; diff --git a/src/test/java/com/alibaba/druid/bvt/sql/PagerUtilsTest_Limit_db2_0.java b/src/test/java/com/alibaba/druid/bvt/sql/PagerUtilsTest_Limit_db2_0.java new file mode 100644 index 0000000000..d59158a1fa --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/PagerUtilsTest_Limit_db2_0.java @@ -0,0 +1,53 @@ +package com.alibaba.druid.bvt.sql; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.sql.PagerUtils; +import com.alibaba.druid.util.JdbcConstants; + +public class PagerUtilsTest_Limit_db2_0 extends TestCase { + + public void test_mysql_0() throws Exception { + String sql = "select * from t"; + String result = PagerUtils.limit(sql, JdbcConstants.DB2, 0, 10); + Assert.assertEquals("SELECT *" + // + "\nFROM t" + // + "\nFETCH FIRST 10 ROWS ONLY", result); + } + + public void test_mysql_1() throws Exception { + String sql = "select * from t"; + String result = PagerUtils.limit(sql, JdbcConstants.DB2, 10, 10); + Assert.assertEquals("SELECT *"// + + "\nFROM (SELECT *, ROW_NUMBER() AS ROWNUM"// + + "\n\tFROM t"// + + "\n\t) XX"// + + "\nWHERE ROWNUM > 10"// + + "\n\tAND ROWNUM <= 20", result); + } + + public void test_mysql_2() throws Exception { + String sql = "select * from t where age > 100"; + String result = PagerUtils.limit(sql, JdbcConstants.DB2, 20, 10); + Assert.assertEquals("SELECT *"// + + "\nFROM (SELECT *, ROW_NUMBER() AS ROWNUM"// + + "\n\tFROM t"// + + "\n\tWHERE age > 100"// + + "\n\t) XX"// + + "\nWHERE ROWNUM > 20"// + + "\n\tAND ROWNUM <= 30", result); + } + + public void test_mysql_3() throws Exception { + String sql = "select id, name, salary from t order by id, name"; + String result = PagerUtils.limit(sql, JdbcConstants.DB2, 20, 10); + Assert.assertEquals("SELECT *"// + + "\nFROM (SELECT id, name, salary, ROW_NUMBER() OVER (ORDER BY id, name) AS ROWNUM"// + + "\n\tFROM t"// + + "\n\t) XX"// + + "\nWHERE ROWNUM > 20"// + + "\n\tAND ROWNUM <= 30", result); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/db2/DB2SelectTest_0.java b/src/test/java/com/alibaba/druid/bvt/sql/db2/DB2SelectTest_0.java new file mode 100644 index 0000000000..67c0d888d4 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/db2/DB2SelectTest_0.java @@ -0,0 +1,65 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.druid.bvt.sql.db2; + +import java.util.List; + +import org.junit.Assert; + +import com.alibaba.druid.sql.DB2Test; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.db2.parser.DB2StatementParser; +import com.alibaba.druid.sql.dialect.db2.visitor.DB2SchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; +import com.alibaba.druid.util.JdbcConstants; + +public class DB2SelectTest_0 extends DB2Test { + + public void test_0() throws Exception { + String sql = "SELECT * FROM DSN81010.EMP;"; + + DB2StatementParser parser = new DB2StatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + DB2SchemaStatVisitor visitor = new DB2SchemaStatVisitor(); + stmt.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(1, visitor.getTables().size()); + Assert.assertEquals(1, visitor.getColumns().size()); + Assert.assertEquals(0, visitor.getConditions().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("DSN81010.EMP"))); + + // Assert.assertTrue(visitor.getColumns().contains(new Column("mytable", "last_name"))); + // Assert.assertTrue(visitor.getColumns().contains(new Column("mytable", "first_name"))); + // Assert.assertTrue(visitor.getColumns().contains(new Column("mytable", "full_name"))); + + String output = SQLUtils.toSQLString(stmt, JdbcConstants.DB2); + Assert.assertEquals("SELECT *" // + + "\nFROM DSN81010.EMP", // + output); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/db2/DB2SelectTest_1.java b/src/test/java/com/alibaba/druid/bvt/sql/db2/DB2SelectTest_1.java new file mode 100644 index 0000000000..a1e85a86cc --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/db2/DB2SelectTest_1.java @@ -0,0 +1,65 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.druid.bvt.sql.db2; + +import java.util.List; + +import org.junit.Assert; + +import com.alibaba.druid.sql.DB2Test; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.db2.parser.DB2StatementParser; +import com.alibaba.druid.sql.dialect.db2.visitor.DB2SchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; +import com.alibaba.druid.util.JdbcConstants; + +public class DB2SelectTest_1 extends DB2Test { + + public void test_0() throws Exception { + String sql = "SELECT * FROM DSN81010.EMP FETCH FIRST 5 ROWS ONLY;"; + + DB2StatementParser parser = new DB2StatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + DB2SchemaStatVisitor visitor = new DB2SchemaStatVisitor(); + stmt.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(1, visitor.getTables().size()); + Assert.assertEquals(1, visitor.getColumns().size()); + Assert.assertEquals(0, visitor.getConditions().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("DSN81010.EMP"))); + + // Assert.assertTrue(visitor.getColumns().contains(new Column("mytable", "last_name"))); + // Assert.assertTrue(visitor.getColumns().contains(new Column("mytable", "first_name"))); + // Assert.assertTrue(visitor.getColumns().contains(new Column("mytable", "full_name"))); + + String output = SQLUtils.toSQLString(stmt, JdbcConstants.DB2); + Assert.assertEquals("SELECT *" // + + "\nFROM DSN81010.EMP", // + output); + } +} diff --git a/src/test/java/com/alibaba/druid/sql/DB2Test.java b/src/test/java/com/alibaba/druid/sql/DB2Test.java new file mode 100644 index 0000000000..c4971a99cc --- /dev/null +++ b/src/test/java/com/alibaba/druid/sql/DB2Test.java @@ -0,0 +1,45 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.druid.sql; + +import java.util.List; + +import junit.framework.TestCase; + +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.db2.visitor.DB2OutputVisitor; + +public class DB2Test extends TestCase { + protected String output(List stmtList) { + StringBuilder out = new StringBuilder(); + DB2OutputVisitor visitor = new DB2OutputVisitor(out); + + for (SQLStatement stmt : stmtList) { + stmt.accept(visitor); + } + + return out.toString(); + } + + protected void print(List stmtList) { + String text = output(stmtList); + String outputProperty = System.getProperty("druid.output"); + if ("false".equals(outputProperty)) { + return; + } + System.out.println(text); + } +}