From dc45cd0a9227b6faee0ccfba7d8037a34c2ab628 Mon Sep 17 00:00:00 2001 From: zhujunxxxxx <455910092@qq.com> Date: Sun, 20 Sep 2015 19:37:17 +0800 Subject: [PATCH 1/8] =?UTF-8?q?=E5=A2=9E=E5=8A=A0mysql=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E5=AD=98=E5=82=A8=E8=BF=87=E7=A8=8B=E6=97=B6=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E5=8F=AF=E9=80=89=E7=B1=BB=E5=9E=8BIN|OUT|INOUT?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mysql/ast/clause/MySqlParameter.java | 21 ++- .../mysql/parser/MySqlStatementParser.java | 22 +++ .../mysql/visitor/MySqlOutputVisitor.java | 14 ++ .../alibaba/druid/sql/parser/Keywords.java | 4 +- .../com/alibaba/druid/sql/parser/Token.java | 4 +- .../sql/mysql/MySqlCreateProcedureTest6.java | 155 ++++++++++++++++++ 6 files changed, 217 insertions(+), 3 deletions(-) create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest6.java diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlParameter.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlParameter.java index a2e88da6d7..df9f3e1621 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlParameter.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/clause/MySqlParameter.java @@ -32,8 +32,17 @@ public class MySqlParameter extends MySqlObjectImpl { private SQLExpr name; private SQLDataType dataType; private SQLExpr defaultValue; + private ParameterType paramType; - public SQLExpr getDefaultValue() { + public ParameterType getParamType() { + return paramType; + } + + public void setParamType(ParameterType paramType) { + this.paramType = paramType; + } + + public SQLExpr getDefaultValue() { return defaultValue; } @@ -66,5 +75,15 @@ public class MySqlParameter extends MySqlObjectImpl { } visitor.endVisit(this); } + /** + * mysql procedure parameter type + */ + public static enum ParameterType + { + DEFAULT, + IN,//in + OUT,//out + INOUT//inout + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java index 05d54819e6..c096f330b5 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java @@ -73,6 +73,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlIterateStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlLeaveStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlLoopStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlParameter; +import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlParameter.ParameterType; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlRepeatStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlSelectIntoStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlWhileStatement; @@ -2785,7 +2786,28 @@ public class MySqlStatementParser extends SQLStatementParser { parameter.setDataType(dataType); parameter.setDefaultValue(new SQLQueryExpr(select)); + + } else if (lexer.token() == Token.IN || lexer.token() == Token.OUT || lexer.token() == Token.INOUT) { + + if(lexer.token()==Token.IN) + { + parameter.setParamType(ParameterType.IN); + } + else if(lexer.token()==Token.OUT) + { + parameter.setParamType(ParameterType.OUT); + } + else if(lexer.token()==Token.INOUT) + { + parameter.setParamType(ParameterType.INOUT); + } + lexer.nextToken(); + + parameter.setName(this.exprParser.name()); + + parameter.setDataType(this.exprParser.parseDataType()); } else { + parameter.setParamType(ParameterType.DEFAULT);//default parameter type is in parameter.setName(this.exprParser.name()); parameter.setDataType(this.exprParser.parseDataType()); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java index 5ef99443f0..12e0b106ab 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java @@ -59,6 +59,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlIterateStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlLeaveStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlLoopStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlParameter; +import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlParameter.ParameterType; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlRepeatStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlSelectIntoStatement; import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlWhileStatement; @@ -3277,6 +3278,19 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV decrementIndent(); } else { + + if(x.getParamType()==ParameterType.IN) + { + print("IN "); + } + else if(x.getParamType()==ParameterType.OUT) + { + print("OUT "); + } + else if(x.getParamType()==ParameterType.INOUT) + { + print("INOUT "); + } x.getName().accept(this); print(" "); diff --git a/src/main/java/com/alibaba/druid/sql/parser/Keywords.java b/src/main/java/com/alibaba/druid/sql/parser/Keywords.java index 5b0eb2f6cd..5bcc6f3dab 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Keywords.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Keywords.java @@ -135,7 +135,7 @@ public class Keywords { map.put("GRANT", Token.GRANT); map.put("REVOKE", Token.REVOKE); - // MySql procedure by:zz + // MySql procedure: add by zz map.put("WHILE", Token.WHILE); map.put("DO", Token.DO); map.put("DECLARE", Token.DECLARE); @@ -148,6 +148,8 @@ public class Keywords { map.put("CLOSE", Token.CLOSE); map.put("CURSOR", Token.CURSOR); map.put("FETCH", Token.FETCH); + map.put("OUT", Token.OUT); + map.put("INOUT", Token.INOUT); DEFAULT_KEYWORDS = new Keywords(map); } diff --git a/src/main/java/com/alibaba/druid/sql/parser/Token.java b/src/main/java/com/alibaba/druid/sql/parser/Token.java index 8e0d0e3b80..c3e97136bb 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Token.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Token.java @@ -128,7 +128,7 @@ public enum Token { SHOW("SHOW"), REPLACE("REPLACE"), - // MySql procedure by:zz + // MySql procedure add by zz WHILE("WHILE"), DO("DO"), LEAVE("LEAVE"), @@ -137,6 +137,8 @@ public enum Token { UNTIL("UNTIL"), OPEN("OPEN"), CLOSE("CLOSE"), + OUT("OUT"), + INOUT("INOUT"), //postgresql WINDOW("WINDOW"), diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest6.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest6.java new file mode 100644 index 0000000000..026eea9d66 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlCreateProcedureTest6.java @@ -0,0 +1,155 @@ +/* + * Copyright 1999-2101 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.mysql; + +import java.util.List; + +import org.junit.Assert; + +import com.alibaba.druid.sql.MysqlTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; +import com.alibaba.druid.stat.TableStat.Column; + +/** + * + * @Description: create procedure parameter type support + * @author zz email:455910092@qq.com + * @date 2015-9-14 + * @version V1.0 + */ +public class MySqlCreateProcedureTest6 extends MysqlTest { + + public void test_0() throws Exception { + String sql="create or replace procedure sp_name(level int,age int)"+ + " begin"+ + " insert into test values(id,age);"+ + " end"; + + MySqlStatementParser parser=new MySqlStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + Assert.assertEquals(1, statementList.size()); + + MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor(); + statemen.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(2, visitor.getColumns().size()); + Assert.assertEquals(0, visitor.getConditions().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("test"))); + + Assert.assertTrue(visitor.getColumns().contains(new Column("test", "id"))); + Assert.assertTrue(visitor.getColumns().contains(new Column("test", "age"))); + } + public void test_1() throws Exception { + String sql="create or replace procedure sp_name(in level int,in age int)"+ + " begin"+ + " insert into test values(id,age);"+ + " end"; + + MySqlStatementParser parser=new MySqlStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + Assert.assertEquals(1, statementList.size()); + + MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor(); + statemen.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(2, visitor.getColumns().size()); + Assert.assertEquals(0, visitor.getConditions().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("test"))); + + Assert.assertTrue(visitor.getColumns().contains(new Column("test", "id"))); + Assert.assertTrue(visitor.getColumns().contains(new Column("test", "age"))); + } + public void test_2() throws Exception { + String sql="create or replace procedure sp_name(out level int,out age int)"+ + " begin"+ + " insert into test values(id,age);"+ + " end"; + + MySqlStatementParser parser=new MySqlStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + Assert.assertEquals(1, statementList.size()); + + MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor(); + statemen.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(2, visitor.getColumns().size()); + Assert.assertEquals(0, visitor.getConditions().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("test"))); + + Assert.assertTrue(visitor.getColumns().contains(new Column("test", "id"))); + Assert.assertTrue(visitor.getColumns().contains(new Column("test", "age"))); + } + public void test_3() throws Exception { + String sql="create or replace procedure sp_name(inout level int,inout age int)"+ + " begin"+ + " insert into test values(id,age);"+ + " end"; + + MySqlStatementParser parser=new MySqlStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + Assert.assertEquals(1, statementList.size()); + + MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor(); + statemen.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(2, visitor.getColumns().size()); + Assert.assertEquals(0, visitor.getConditions().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("test"))); + + Assert.assertTrue(visitor.getColumns().contains(new Column("test", "id"))); + Assert.assertTrue(visitor.getColumns().contains(new Column("test", "age"))); + } + +} From 1150f45f396a99839fc877c958a74fb05e0d7ded Mon Sep 17 00:00:00 2001 From: zhujunxxxxx <455910092@qq.com> Date: Mon, 21 Sep 2015 21:24:22 +0800 Subject: [PATCH 2/8] fixed issue#949 --- .../ast/stmt/SQLServerExecStatement.java | 47 +++++++++++++++--- .../parser/SQLServerStatementParser.java | 48 +++++++++++++++++-- .../visitor/SQLServerASTVisitor.java | 5 ++ .../visitor/SQLServerASTVisitorAdapter.java | 13 +++++ .../visitor/SQLServerOutputVisitor.java | 18 +++++++ .../visitor/SQLServerSchemaStatVisitor.java | 13 +++++ .../bvt/sql/sqlserver/SQLServerExec_Test.java | 24 ++++++++++ 7 files changed, 158 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/stmt/SQLServerExecStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/stmt/SQLServerExecStatement.java index 43faa2d97d..1395ca92b4 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/stmt/SQLServerExecStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/stmt/SQLServerExecStatement.java @@ -1,8 +1,3 @@ -package com.alibaba.druid.sql.dialect.sqlserver.ast.stmt; - -import java.util.ArrayList; -import java.util.List; - /* * Copyright 1999-2101 Alibaba Group Holding Ltd. * @@ -18,6 +13,11 @@ import java.util.List; * See the License for the specific language governing permissions and * limitations under the License. */ +package com.alibaba.druid.sql.dialect.sqlserver.ast.stmt; + +import java.util.ArrayList; +import java.util.List; + import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerObjectImpl; @@ -28,7 +28,7 @@ public class SQLServerExecStatement extends SQLServerObjectImpl implements SQLSe private SQLName returnStatus; private SQLName moduleName; - private List parameters = new ArrayList(); + private List parameters = new ArrayList(); private String dbType; public SQLName getModuleName() { @@ -39,7 +39,7 @@ public class SQLServerExecStatement extends SQLServerObjectImpl implements SQLSe this.moduleName = moduleName; } - public List getParameters() { + public List getParameters() { return parameters; } @@ -67,4 +67,37 @@ public class SQLServerExecStatement extends SQLServerObjectImpl implements SQLSe public void setDbType(String dbType) { this.dbType = dbType; } + + /** + * + * @Description: SQLServer execute Parameter statement + * @author zz email:455910092@qq.com + * @date 2015-9-20 + * @version V1.0 + */ + public static class SQLServerParameter extends SQLServerObjectImpl + { + private SQLExpr expr; + private boolean type;//sql server 支持参数只有input 和 output 两种 + public SQLExpr getExpr() { + return expr; + } + public void setExpr(SQLExpr expr) { + this.expr = expr; + } + public boolean getType() { + return type; + } + public void setType(boolean type) { + this.type = type; + } + @Override + public void accept0(SQLServerASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, expr); + } + visitor.endVisit(this); + + } + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java index f49257a66d..42e2281879 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java @@ -15,9 +15,12 @@ */ package com.alibaba.druid.sql.dialect.sqlserver.parser; +import java.util.Collection; import java.util.List; +import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLName; +import com.alibaba.druid.sql.ast.SQLObject; import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; import com.alibaba.druid.sql.ast.expr.SQLQueryExpr; @@ -43,6 +46,7 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerSetStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerSetTransactionIsolationLevelStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerUpdateStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerWaitForStatement; +import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement.SQLServerParameter; import com.alibaba.druid.sql.parser.Lexer; import com.alibaba.druid.sql.parser.ParserException; import com.alibaba.druid.sql.parser.SQLSelectParser; @@ -76,7 +80,7 @@ public class SQLServerStatementParser extends SQLStatementParser { SQLServerExecStatement execStmt = new SQLServerExecStatement(); if (lexer.token() == Token.LPAREN) { lexer.nextToken(); - this.exprParser.exprList(execStmt.getParameters(), execStmt); + this.parseExecParameter(execStmt.getParameters(), execStmt); accept(Token.RPAREN); } else { SQLName sqlNameName = this.exprParser.name(); @@ -88,8 +92,8 @@ public class SQLServerStatementParser extends SQLStatementParser { } else { execStmt.setModuleName(sqlNameName); } - - this.exprParser.exprList(execStmt.getParameters(), execStmt); + + this.parseExecParameter(execStmt.getParameters(), execStmt); } statementList.add(execStmt); return true; @@ -122,6 +126,44 @@ public class SQLServerStatementParser extends SQLStatementParser { return false; } + /** + * SQLServer parse Parameter statement support out type + * @author zz email:455910092@qq.com + * @date 2015-9-20 + */ + public void parseExecParameter(Collection exprCol, SQLObject parent) + { + if (lexer.token() == Token.RPAREN || lexer.token() == Token.RBRACKET) { + return; + } + + if (lexer.token() == Token.EOF) { + return; + } + SQLServerParameter param=new SQLServerParameter(); + SQLExpr expr=this.exprParser.expr(); + expr.setParent(parent); + param.setExpr(expr); + if(lexer.token()==Token.OUT) + { + param.setType(true); + accept(Token.OUT); + } + exprCol.add(param); + while (lexer.token() == Token.COMMA) { + lexer.nextToken(); + param=new SQLServerParameter(); + expr=this.exprParser.expr(); + expr.setParent(parent); + param.setExpr(expr); + if(lexer.token()==Token.OUT) + { + param.setType(true); + accept(Token.OUT); + } + exprCol.add(param); + } + } public SQLStatement parseDeclare() { this.accept(Token.DECLARE); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerASTVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerASTVisitor.java index a4f2493898..829d1ca73e 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerASTVisitor.java @@ -26,6 +26,7 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerBlockStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerCommitStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerDeclareStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement; +import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement.SQLServerParameter; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerIfStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerIfStatement.Else; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement; @@ -117,5 +118,9 @@ public interface SQLServerASTVisitor extends SQLASTVisitor { boolean visit(SQLServerWaitForStatement x); void endVisit(SQLServerWaitForStatement x); + + boolean visit(SQLServerParameter x); + + void endVisit(SQLServerParameter x); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerASTVisitorAdapter.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerASTVisitorAdapter.java index ba4d4a6e5c..cabb471ae3 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerASTVisitorAdapter.java @@ -26,6 +26,7 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerBlockStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerCommitStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerDeclareStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement; +import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement.SQLServerParameter; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerIfStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerIfStatement.Else; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement; @@ -238,4 +239,16 @@ public class SQLServerASTVisitorAdapter extends SQLASTVisitorAdapter implements } + @Override + public boolean visit(SQLServerParameter x) { + // TODO Auto-generated method stub + return false; + } + + @Override + public void endVisit(SQLServerParameter x) { + // TODO Auto-generated method stub + + } + } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerOutputVisitor.java index d7c748a0a2..c2c94ac19c 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerOutputVisitor.java @@ -35,6 +35,7 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerBlockStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerCommitStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerDeclareStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement; +import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement.SQLServerParameter; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerIfStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerIfStatement.Else; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement; @@ -690,4 +691,21 @@ public class SQLServerOutputVisitor extends SQLASTOutputVisitor implements SQLSe public void endVisit(SQLServerWaitForStatement x) { } + + @Override + public boolean visit(SQLServerParameter x) { + // TODO Auto-generated method stub + x.getExpr().accept(this); + if(x.getType()) + { + print(" OUT"); + } + return false; + } + + @Override + public void endVisit(SQLServerParameter x) { + // TODO Auto-generated method stub + + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerSchemaStatVisitor.java index cf44d95f8e..c01db613b0 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerSchemaStatVisitor.java @@ -33,6 +33,7 @@ import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerBlockStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerCommitStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerDeclareStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement; +import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement.SQLServerParameter; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerIfStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerIfStatement.Else; import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement; @@ -274,4 +275,16 @@ public class SQLServerSchemaStatVisitor extends SchemaStatVisitor implements SQL } + @Override + public boolean visit(SQLServerParameter x) { + // TODO Auto-generated method stub + return false; + } + + @Override + public void endVisit(SQLServerParameter x) { + // TODO Auto-generated method stub + + } + } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerExec_Test.java b/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerExec_Test.java index 6c61e6c004..eb6f716c0a 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerExec_Test.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerExec_Test.java @@ -71,4 +71,28 @@ public class SQLServerExec_Test extends TestCase { Assert.assertEquals(0, visitor.getColumns().size()); } + /** + * add by zz to test execute sp with out type + * @throws Exception + */ + public void test_3() throws Exception { + String sql = "EXEC sp_rename @P0 OUT"; + SQLServerStatementParser parser = new SQLServerStatementParser(sql); + SQLStatement stmt = parser.parseStatementList().get(0); + parser.match(Token.EOF); + + SQLServerSchemaStatVisitor visitor = new SQLServerSchemaStatVisitor(); + 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()); + + String output = SQLUtils.toSQLString(stmt, JdbcConstants.SQL_SERVER); + Assert.assertEquals("EXEC sp_rename @P0 OUT", output); + + Assert.assertEquals(0, visitor.getTables().size()); + Assert.assertEquals(0, visitor.getColumns().size()); + } } From 5504c7125ec78f8e3d82dea99777cdcb0a45d40f Mon Sep 17 00:00:00 2001 From: Yako Date: Thu, 24 Sep 2015 17:18:22 +0800 Subject: [PATCH 3/8] support select ... from update .. for alibaba mysql --- .../ast/statement/MySqlUpdateTableSource.java | 55 +++++++++++ .../mysql/parser/MySqlSelectParser.java | 95 +++++++++++++++++++ .../mysql/visitor/MySqlASTVisitor.java | 5 + .../mysql/visitor/MySqlASTVisitorAdapter.java | 11 +++ .../mysql/visitor/MySqlOutputVisitor.java | 14 +++ .../mysql/visitor/MySqlSchemaStatVisitor.java | 14 +++ .../druid/sql/parser/SQLSelectParser.java | 2 +- .../bvt/sql/mysql/MySqlSelectTest_update.java | 81 ++++++++++++++++ 8 files changed, 276 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlUpdateTableSource.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlSelectTest_update.java diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlUpdateTableSource.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlUpdateTableSource.java new file mode 100644 index 0000000000..404079863f --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlUpdateTableSource.java @@ -0,0 +1,55 @@ +/* + * Copyright 1999-2101 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.mysql.ast.statement; + +import com.alibaba.druid.sql.ast.statement.SQLTableSourceImpl; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor; +import com.alibaba.druid.sql.visitor.SQLASTVisitor; + +// just for alibaba mysql +public class MySqlUpdateTableSource extends SQLTableSourceImpl { + + private MySqlUpdateStatement update; + + public MySqlUpdateTableSource(MySqlUpdateStatement update){ + this.update = update; + } + + @Override + protected void accept0(SQLASTVisitor visitor) { + if (visitor instanceof MySqlASTVisitor) { + accept0((MySqlASTVisitor) visitor); + } else { + throw new IllegalArgumentException("not support visitor type : " + visitor.getClass().getName()); + } + } + + public void accept0(MySqlASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, update); + } + visitor.endVisit(this); + } + + public MySqlUpdateStatement getUpdate() { + return update; + } + + public void setUpdate(MySqlUpdateStatement update) { + this.update = update; + } + +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java index accba3cd56..e6b003ae99 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java @@ -19,11 +19,16 @@ import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLSetQuantifier; import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr; +import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; +import com.alibaba.druid.sql.ast.statement.SQLSelect; import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause; import com.alibaba.druid.sql.ast.statement.SQLSelectQuery; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; +import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource; import com.alibaba.druid.sql.ast.statement.SQLTableSource; import com.alibaba.druid.sql.ast.statement.SQLUnionQuery; +import com.alibaba.druid.sql.ast.statement.SQLUnionQueryTableSource; +import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem; import com.alibaba.druid.sql.dialect.mysql.ast.MySqlForceIndexHint; import com.alibaba.druid.sql.dialect.mysql.ast.MySqlIgnoreIndexHint; import com.alibaba.druid.sql.dialect.mysql.ast.MySqlIndexHint; @@ -32,8 +37,10 @@ import com.alibaba.druid.sql.dialect.mysql.ast.MySqlUseIndexHint; import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOutFileExpr; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectGroupBy; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock.Limit; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnionQuery; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateTableSource; import com.alibaba.druid.sql.parser.ParserException; import com.alibaba.druid.sql.parser.SQLExprParser; import com.alibaba.druid.sql.parser.SQLSelectParser; @@ -166,6 +173,94 @@ public class MySqlSelectParser extends SQLSelectParser { return queryRest(queryBlock); } + public SQLTableSource parseTableSource() { + if (lexer.token() == Token.LPAREN) { + lexer.nextToken(); + SQLTableSource tableSource; + if (lexer.token() == Token.SELECT || lexer.token() == Token.WITH) { + SQLSelect select = select(); + accept(Token.RPAREN); + SQLSelectQuery query = queryRest(select.getQuery()); + if (query instanceof SQLUnionQuery) { + tableSource = new SQLUnionQueryTableSource((SQLUnionQuery) query); + } else { + tableSource = new SQLSubqueryTableSource(select); + } + } else if (lexer.token() == Token.LPAREN) { + tableSource = parseTableSource(); + accept(Token.RPAREN); + } else { + tableSource = parseTableSource(); + accept(Token.RPAREN); + } + + return parseTableSourceRest(tableSource); + } + + if(lexer.token() == Token.UPDATE) { + SQLTableSource tableSource = new MySqlUpdateTableSource(parseUpdateStatment()); + return parseTableSourceRest(tableSource); + } + + if (lexer.token() == Token.SELECT) { + throw new ParserException("TODO"); + } + + SQLExprTableSource tableReference = new SQLExprTableSource(); + + parseTableSourceQueryTableExpr(tableReference); + + SQLTableSource tableSrc = parseTableSourceRest(tableReference); + + if (lexer.hasComment() && lexer.isKeepComments()) { + tableSrc.addAfterComment(lexer.readAndResetComments()); + } + + return tableSrc; + } + + private MySqlUpdateStatement parseUpdateStatment() { + MySqlUpdateStatement update = new MySqlUpdateStatement(); + + lexer.nextToken(); + + if (identifierEquals("LOW_PRIORITY")) { + lexer.nextToken(); + update.setLowPriority(true); + } + + if (identifierEquals("IGNORE")) { + lexer.nextToken(); + update.setIgnore(true); + } + + SQLTableSource updateTableSource = this.exprParser.createSelectParser().parseTableSource(); + update.setTableSource(updateTableSource); + + accept(Token.SET); + + for (;;) { + SQLUpdateSetItem item = this.exprParser.parseUpdateSetItem(); + update.addItem(item); + + if (lexer.token() != Token.COMMA) { + break; + } + + lexer.nextToken(); + } + + if (lexer.token() == (Token.WHERE)) { + lexer.nextToken(); + update.setWhere(this.exprParser.expr()); + } + + update.setOrderBy(this.exprParser.parseOrderBy()); + update.setLimit(parseLimit()); + + return update; + } + protected void parseInto(SQLSelectQueryBlock queryBlock) { if (lexer.token() == (Token.INTO)) { lexer.nextToken(); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitor.java index 74e7918cdb..fc2c334ba5 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitor.java @@ -136,6 +136,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlTableIndex; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnionQuery; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnlockTablesStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateTableSource; import com.alibaba.druid.sql.visitor.SQLASTVisitor; public interface MySqlASTVisitor extends SQLASTVisitor { @@ -650,5 +651,9 @@ public interface MySqlASTVisitor extends SQLASTVisitor { boolean visit(MySqlCursorDeclareStatement x); void endVisit(MySqlCursorDeclareStatement x); + + boolean visit(MySqlUpdateTableSource x); + + void endVisit(MySqlUpdateTableSource x); } // diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitorAdapter.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitorAdapter.java index 6fd4e3964d..3c129826cc 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlASTVisitorAdapter.java @@ -141,6 +141,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlTableIndex; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnionQuery; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnlockTablesStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateTableSource; import com.alibaba.druid.sql.visitor.SQLASTVisitorAdapter; public class MySqlASTVisitorAdapter extends SQLASTVisitorAdapter implements MySqlASTVisitor { @@ -1466,5 +1467,15 @@ public class MySqlASTVisitorAdapter extends SQLASTVisitorAdapter implements MySq // TODO Auto-generated method stub } + + @Override + public boolean visit(MySqlUpdateTableSource x) { + return true; + } + + @Override + public void endVisit(MySqlUpdateTableSource x) { + + } } // diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java index 12e0b106ab..c59ed17cd7 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java @@ -168,6 +168,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlTableIndex; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnionQuery; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnlockTablesStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateTableSource; import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTVisitor { @@ -3585,4 +3586,17 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV } + @Override + public boolean visit(MySqlUpdateTableSource x) { + MySqlUpdateStatement update = x.getUpdate(); + if (update != null) { + update.accept0(this); + } + return false; + } + + @Override + public void endVisit(MySqlUpdateTableSource x) { + + } } // diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java index 5c261e8f21..444234d994 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java @@ -156,6 +156,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlTableIndex; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnionQuery; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnlockTablesStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateTableSource; import com.alibaba.druid.sql.visitor.SchemaStatVisitor; import com.alibaba.druid.stat.TableStat; import com.alibaba.druid.stat.TableStat.Mode; @@ -1570,5 +1571,18 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS // TODO Auto-generated method stub } + + @Override + public boolean visit(MySqlUpdateTableSource x) { + if (x.getUpdate() != null) { + return this.visit(x.getUpdate()); + } + return false; + } + + @Override + public void endVisit(MySqlUpdateTableSource x) { + + } } diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java index b1be24a49e..e450cd9237 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLSelectParser.java @@ -355,7 +355,7 @@ public class SQLSelectParser extends SQLParser { return tableSrc; } - private void parseTableSourceQueryTableExpr(SQLExprTableSource tableReference) { + protected void parseTableSourceQueryTableExpr(SQLExprTableSource tableReference) { if (lexer.token() == Token.LITERAL_ALIAS || lexer.token() == Token.IDENTIFIED || lexer.token() == Token.LITERAL_CHARS) { tableReference.setExpr(this.exprParser.name()); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlSelectTest_update.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlSelectTest_update.java new file mode 100644 index 0000000000..833078c922 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlSelectTest_update.java @@ -0,0 +1,81 @@ +/* + * Copyright 1999-2101 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.mysql; + +import java.util.List; + +import org.junit.Assert; + +import com.alibaba.druid.sql.MysqlTest; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.ast.statement.SQLSelect; +import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; +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.MySqlSchemaStatVisitor; + +public class MySqlSelectTest_update extends MysqlTest { + + public void test_0() throws Exception { + String sql = "select current_no from " + + "update wlb_waybill_branch_rule set current_no = current_no + ? ,gmt_modified = now() " + + "where id = ? and status = ? and end_no > current_no " + + "order by current_no desc " + + "limit 10"; + + MySqlStatementParser parser = new MySqlStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + + SQLSelectStatement selectStmt = (SQLSelectStatement) stmt; + + SQLSelect select = selectStmt.getSelect(); + Assert.assertNotNull(select.getQuery()); + MySqlSelectQueryBlock queryBlock = (MySqlSelectQueryBlock) select.getQuery(); + Assert.assertNull(queryBlock.getOrderBy()); + + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + String output = SQLUtils.toMySqlString(stmt); + + String expected = "SELECT current_no" + + "\nFROM UPDATE wlb_waybill_branch_rule" + + "\nSET current_no = current_no + ?, gmt_modified = now()" + + "\nWHERE id = ?" + + "\n\tAND status = ?" + + "\n\tAND end_no > current_no" + + "\nORDER BY current_no DESC" + + "\nLIMIT 10"; + + Assert.assertEquals(expected, output); + + MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor(); + 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(5, visitor.getColumns().size()); + Assert.assertEquals(4, visitor.getConditions().size()); + Assert.assertEquals(0, visitor.getOrderByColumns().size()); + } +} From 4ed1235a9041667d8d20446ed2674f70b7372ade Mon Sep 17 00:00:00 2001 From: Yako Date: Sat, 10 Oct 2015 14:55:47 +0800 Subject: [PATCH 4/8] 1.0.16 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 660b205893..d211154f42 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.alibaba druid - 1.0.16-SNAPSHOT + 1.0.16 jar druid From 9a925d49fcc0a726e37df8bbca248aca86a83a9c Mon Sep 17 00:00:00 2001 From: zhujunxxxxx <455910092@qq.com> Date: Tue, 20 Oct 2015 19:29:32 +0800 Subject: [PATCH 5/8] fix issue#975, fixed && and || --- .../sql/visitor/SQLEvalVisitorUtils.java | 14 +++++++++++++ .../druid/bvt/sql/eval/EvalAndOrTest.java | 20 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/eval/EvalAndOrTest.java diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorUtils.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorUtils.java index b155c54567..835cf24593 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLEvalVisitorUtils.java @@ -1049,6 +1049,20 @@ public class SQLEvalVisitorUtils { x.putAttribute(EVAL_VALUE, result); break; } + case BooleanAnd: + { + boolean first = eq(leftValue, true); + boolean second = eq(rightValue, true); + x.putAttribute(EVAL_VALUE, first&&second); + break; + } + case BooleanOr: + { + boolean first = eq(leftValue, true); + boolean second = eq(rightValue, true); + x.putAttribute(EVAL_VALUE, first||second); + break; + } default: break; } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/eval/EvalAndOrTest.java b/src/test/java/com/alibaba/druid/bvt/sql/eval/EvalAndOrTest.java new file mode 100644 index 0000000000..3fc6b7f5b4 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/eval/EvalAndOrTest.java @@ -0,0 +1,20 @@ +package com.alibaba.druid.bvt.sql.eval; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.druid.sql.visitor.SQLEvalVisitorUtils; +import com.alibaba.druid.util.JdbcConstants; + + +public class EvalAndOrTest extends TestCase { + public void test_and() throws Exception { + Assert.assertEquals(false, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "?>0 && ?>0", 1,0)); + Assert.assertEquals(true, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "2>1 && 100>10")); + } + public void test_or() throws Exception { + Assert.assertEquals(true, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "10>0 || 2>0")); + Assert.assertEquals(true, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "10>0 || 2<0")); + Assert.assertEquals(false, SQLEvalVisitorUtils.evalExpr(JdbcConstants.MYSQL, "2>10 || 100<10")); + } +} From e38b49f107de6b636585602f2ad3babbffb330be Mon Sep 17 00:00:00 2001 From: Yako Date: Tue, 3 Nov 2015 09:54:44 +0800 Subject: [PATCH 6/8] 1.0.17 --- pom.xml | 2 +- src/main/java/com/alibaba/druid/VERSION.java | 2 +- src/main/resources/support/http/resources/js/doT.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index d211154f42..33533a1173 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.alibaba druid - 1.0.16 + 1.0.17-SNAPSHOT jar druid diff --git a/src/main/java/com/alibaba/druid/VERSION.java b/src/main/java/com/alibaba/druid/VERSION.java index f9311d761f..d6b9875a1c 100644 --- a/src/main/java/com/alibaba/druid/VERSION.java +++ b/src/main/java/com/alibaba/druid/VERSION.java @@ -19,7 +19,7 @@ public final class VERSION { public final static int MajorVersion = 1; public final static int MinorVersion = 0; - public final static int RevisionVersion = 16; + public final static int RevisionVersion = 17; public static String getVersionNumber() { return VERSION.MajorVersion + "." + VERSION.MinorVersion + "." + VERSION.RevisionVersion; diff --git a/src/main/resources/support/http/resources/js/doT.js b/src/main/resources/support/http/resources/js/doT.js index 9927e3711e..beb31e267e 100644 --- a/src/main/resources/support/http/resources/js/doT.js +++ b/src/main/resources/support/http/resources/js/doT.js @@ -6,7 +6,7 @@ "use strict"; var doT = { - version: '1.0.14', + version: '1.0.17', templateSettings: { evaluate: /\{\{([\s\S]+?\}?)\}\}/g, interpolate: /\{\{=([\s\S]+?)\}\}/g, From bf8b6e4b7244a2f1b72704a09e0af0ac92ce7e03 Mon Sep 17 00:00:00 2001 From: Yako Date: Tue, 3 Nov 2015 09:57:27 +0800 Subject: [PATCH 7/8] support odps show grants ... --- .../dialect/odps/ast/OdpsShowGrantsStmt.java | 64 +++++++++++++++++++ .../odps/parser/OdpsStatementParser.java | 19 ++++++ .../dialect/odps/visitor/OdpsASTVisitor.java | 5 ++ .../odps/visitor/OdpsASTVisitorAdapter.java | 11 ++++ .../odps/visitor/OdpsOutputVisitor.java | 21 ++++++ .../odps/visitor/OdpsSchemaStatVisitor.java | 11 ++++ .../druid/sql/parser/SQLExprParser.java | 1 + .../bvt/sql/odps/OdpsShowGrantsTest.java | 34 ++++++++++ 8 files changed, 166 insertions(+) create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsShowGrantsStmt.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsShowGrantsTest.java diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsShowGrantsStmt.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsShowGrantsStmt.java new file mode 100644 index 0000000000..a279d44425 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsShowGrantsStmt.java @@ -0,0 +1,64 @@ +/* + * Copyright 1999-2101 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.odps.ast; + +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.ast.SQLStatementImpl; +import com.alibaba.druid.sql.dialect.odps.visitor.OdpsASTVisitor; +import com.alibaba.druid.sql.visitor.SQLASTVisitor; + +public class OdpsShowGrantsStmt extends SQLStatementImpl implements SQLStatement { + + private SQLExpr user; + + private SQLExpr objectType; + + @Override + protected void accept0(SQLASTVisitor visitor) { + accept0((OdpsASTVisitor) visitor); + } + + public void accept0(OdpsASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, user); + acceptChild(visitor, objectType); + } + visitor.endVisit(this); + } + + public SQLExpr getUser() { + return user; + } + + public void setUser(SQLExpr user) { + if (user != null) { + user.setParent(this); + } + this.user = user; + } + + public SQLExpr getObjectType() { + return objectType; + } + + public void setObjectType(SQLExpr objectType) { + if (objectType != null) { + objectType.setParent(this); + } + this.objectType = objectType; + } +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsStatementParser.java index 6ba6303a4e..18f30d53fe 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsStatementParser.java @@ -35,6 +35,7 @@ import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsertStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsReadStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsRemoveStatisticStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsSetLabelStatement; +import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowGrantsStmt; import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowPartitionsStmt; import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowStatisticStmt; import com.alibaba.druid.sql.dialect.odps.ast.OdpsStatisticClause; @@ -318,6 +319,24 @@ public class OdpsStatementParser extends SQLStatementParser { return stmt; } + if (identifierEquals("GRANTS")) { + lexer.nextToken(); + OdpsShowGrantsStmt stmt = new OdpsShowGrantsStmt(); + + if (lexer.token() == Token.FOR) { + lexer.nextToken(); + stmt.setUser(this.exprParser.expr()); + } + + if (lexer.token() == Token.ON) { + lexer.nextToken(); + acceptIdentifier("type"); + stmt.setObjectType(this.exprParser.expr()); + } + + return stmt; + } + throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal()); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitor.java index 9efed2fd1d..dd626d3cd4 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitor.java @@ -24,6 +24,7 @@ import com.alibaba.druid.sql.dialect.odps.ast.OdpsReadStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsRemoveStatisticStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsSelectQueryBlock; import com.alibaba.druid.sql.dialect.odps.ast.OdpsSetLabelStatement; +import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowGrantsStmt; import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowPartitionsStmt; import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowStatisticStmt; import com.alibaba.druid.sql.dialect.odps.ast.OdpsStatisticClause; @@ -103,4 +104,8 @@ public interface OdpsASTVisitor extends SQLASTVisitor { void endVisit(OdpsReadStatement x); boolean visit(OdpsReadStatement x); + + void endVisit(OdpsShowGrantsStmt x); + + boolean visit(OdpsShowGrantsStmt x); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitorAdapter.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitorAdapter.java index 4d7d65afa9..b43104abad 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitorAdapter.java @@ -24,6 +24,7 @@ import com.alibaba.druid.sql.dialect.odps.ast.OdpsReadStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsRemoveStatisticStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsSelectQueryBlock; import com.alibaba.druid.sql.dialect.odps.ast.OdpsSetLabelStatement; +import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowGrantsStmt; import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowPartitionsStmt; import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowStatisticStmt; import com.alibaba.druid.sql.dialect.odps.ast.OdpsStatisticClause; @@ -213,4 +214,14 @@ public class OdpsASTVisitorAdapter extends SQLASTVisitorAdapter implements OdpsA return true; } + @Override + public void endVisit(OdpsShowGrantsStmt x) { + + } + + @Override + public boolean visit(OdpsShowGrantsStmt x) { + return true; + } + } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java index 5dcc0e0679..9bc143b171 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java @@ -44,6 +44,7 @@ import com.alibaba.druid.sql.dialect.odps.ast.OdpsReadStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsRemoveStatisticStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsSelectQueryBlock; import com.alibaba.druid.sql.dialect.odps.ast.OdpsSetLabelStatement; +import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowGrantsStmt; import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowPartitionsStmt; import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowStatisticStmt; import com.alibaba.druid.sql.dialect.odps.ast.OdpsStatisticClause; @@ -753,4 +754,24 @@ public class OdpsOutputVisitor extends SQLASTOutputVisitor implements OdpsASTVis print(name); } } + + @Override + public void endVisit(OdpsShowGrantsStmt x) { + + } + + @Override + public boolean visit(OdpsShowGrantsStmt x) { + print("SHOW GRANTS"); + if (x.getUser() != null) { + print(" FOR "); + x.getUser().accept(this); + } + + if (x.getObjectType() != null) { + print(" ON TYPE "); + x.getObjectType().accept(this); + } + return false; + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsSchemaStatVisitor.java index 1feb7be649..312a62d6b8 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsSchemaStatVisitor.java @@ -26,6 +26,7 @@ import com.alibaba.druid.sql.dialect.odps.ast.OdpsReadStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsRemoveStatisticStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsSelectQueryBlock; import com.alibaba.druid.sql.dialect.odps.ast.OdpsSetLabelStatement; +import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowGrantsStmt; import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowPartitionsStmt; import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowStatisticStmt; import com.alibaba.druid.sql.dialect.odps.ast.OdpsStatisticClause; @@ -216,4 +217,14 @@ public class OdpsSchemaStatVisitor extends SchemaStatVisitor implements OdpsASTV public boolean visit(OdpsReadStatement x) { return true; } + + @Override + public void endVisit(OdpsShowGrantsStmt x) { + + } + + @Override + public boolean visit(OdpsShowGrantsStmt x) { + return true; + } } 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 76e5b2d976..82dfd7bdfd 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java @@ -330,6 +330,7 @@ public class SQLExprParser extends SQLParser { case TYPE: case OPEN: case REPEAT: + case TABLE: sqlExpr = new SQLIdentifierExpr(lexer.stringVal()); lexer.nextToken(); break; diff --git a/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsShowGrantsTest.java b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsShowGrantsTest.java new file mode 100644 index 0000000000..d251a17731 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsShowGrantsTest.java @@ -0,0 +1,34 @@ +package com.alibaba.druid.bvt.sql.odps; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.odps.parser.OdpsStatementParser; +import com.alibaba.druid.sql.parser.Token; + +public class OdpsShowGrantsTest extends TestCase { + + public void test_0() throws Exception { + String sql = "show grants for aliyun$DXP_XXXX@aliyun.com"; + OdpsStatementParser parser = new OdpsStatementParser(sql); + SQLStatement stmt = parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toOdpsString(stmt); + //System.out.println(output); + Assert.assertEquals("SHOW GRANTS FOR aliyun$DXP_XXXX@aliyun.com", output); + } + + public void test_1() throws Exception { + String sql = "show grants for aliyun$DXP_XXXX@aliyun.com on type table"; + OdpsStatementParser parser = new OdpsStatementParser(sql); + SQLStatement stmt = parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toOdpsString(stmt); + //System.out.println(output); + Assert.assertEquals("SHOW GRANTS FOR aliyun$DXP_XXXX@aliyun.com ON TYPE table", output); + } + +} From c1d9a6fdcc252cf5e935f2a7e3436b87f246a470 Mon Sep 17 00:00:00 2001 From: Yako Date: Tue, 3 Nov 2015 11:02:47 +0800 Subject: [PATCH 8/8] support odps list ... --- .../sql/dialect/odps/ast/OdpsListStmt.java | 55 ++++++++++++ .../odps/parser/OdpsStatementParser.java | 16 +++- .../dialect/odps/visitor/OdpsASTVisitor.java | 5 ++ .../odps/visitor/OdpsASTVisitorAdapter.java | 11 +++ .../odps/visitor/OdpsOutputVisitor.java | 15 ++++ .../odps/visitor/OdpsSchemaStatVisitor.java | 11 +++ .../druid/bvt/sql/odps/OdpsListTest.java | 84 +++++++++++++++++++ 7 files changed, 195 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsListStmt.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsListTest.java diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsListStmt.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsListStmt.java new file mode 100644 index 0000000000..612cdaabeb --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsListStmt.java @@ -0,0 +1,55 @@ +/* + * Copyright 1999-2101 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.odps.ast; + +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.ast.SQLStatementImpl; +import com.alibaba.druid.sql.dialect.odps.visitor.OdpsASTVisitor; +import com.alibaba.druid.sql.visitor.SQLASTVisitor; +import com.alibaba.druid.util.JdbcConstants; + +public class OdpsListStmt extends SQLStatementImpl implements SQLStatement { + + private SQLExpr object; + + public OdpsListStmt(){ + super(JdbcConstants.ODPS); + } + + @Override + protected void accept0(SQLASTVisitor visitor) { + accept0((OdpsASTVisitor) visitor); + } + + protected void accept0(OdpsASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, object); + } + visitor.endVisit(this); + } + + public SQLExpr getObject() { + return object; + } + + public void setObject(SQLExpr object) { + if (object != null) { + object.setParent(this); + } + this.object = object; + } +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsStatementParser.java index 18f30d53fe..c276fa846b 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsStatementParser.java @@ -32,6 +32,7 @@ import com.alibaba.druid.sql.dialect.odps.ast.OdpsAddStatisticStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsAnalyzeTableStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsert; import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsertStatement; +import com.alibaba.druid.sql.dialect.odps.ast.OdpsListStmt; import com.alibaba.druid.sql.dialect.odps.ast.OdpsReadStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsRemoveStatisticStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsSetLabelStatement; @@ -159,6 +160,18 @@ public class OdpsStatementParser extends SQLStatementParser { statementList.add(stmt); return true; } + + if(identifierEquals("LIST")) { + OdpsListStmt stmt = new OdpsListStmt(); + + lexer.nextToken(); + stmt.setObject(this.exprParser.expr()); + + statementList.add(stmt); + + return true; + } + return false; } @@ -390,6 +403,5 @@ public class OdpsStatementParser extends SQLStatementParser { return stmt; } } - - + } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitor.java index dd626d3cd4..94c35484fe 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitor.java @@ -20,6 +20,7 @@ import com.alibaba.druid.sql.dialect.odps.ast.OdpsAnalyzeTableStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsCreateTableStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsert; import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsertStatement; +import com.alibaba.druid.sql.dialect.odps.ast.OdpsListStmt; import com.alibaba.druid.sql.dialect.odps.ast.OdpsReadStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsRemoveStatisticStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsSelectQueryBlock; @@ -108,4 +109,8 @@ public interface OdpsASTVisitor extends SQLASTVisitor { void endVisit(OdpsShowGrantsStmt x); boolean visit(OdpsShowGrantsStmt x); + + void endVisit(OdpsListStmt x); + + boolean visit(OdpsListStmt x); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitorAdapter.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitorAdapter.java index b43104abad..0ef7989246 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitorAdapter.java @@ -20,6 +20,7 @@ import com.alibaba.druid.sql.dialect.odps.ast.OdpsAnalyzeTableStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsCreateTableStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsert; import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsertStatement; +import com.alibaba.druid.sql.dialect.odps.ast.OdpsListStmt; import com.alibaba.druid.sql.dialect.odps.ast.OdpsReadStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsRemoveStatisticStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsSelectQueryBlock; @@ -224,4 +225,14 @@ public class OdpsASTVisitorAdapter extends SQLASTVisitorAdapter implements OdpsA return true; } + @Override + public void endVisit(OdpsListStmt x) { + + } + + @Override + public boolean visit(OdpsListStmt x) { + return true; + } + } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java index 9bc143b171..064890f762 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java @@ -40,6 +40,7 @@ import com.alibaba.druid.sql.dialect.odps.ast.OdpsAnalyzeTableStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsCreateTableStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsert; import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsertStatement; +import com.alibaba.druid.sql.dialect.odps.ast.OdpsListStmt; import com.alibaba.druid.sql.dialect.odps.ast.OdpsReadStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsRemoveStatisticStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsSelectQueryBlock; @@ -774,4 +775,18 @@ public class OdpsOutputVisitor extends SQLASTOutputVisitor implements OdpsASTVis } return false; } + + @Override + public void endVisit(OdpsListStmt x) { + + } + + @Override + public boolean visit(OdpsListStmt x) { + print("LIST "); + if (x.getObject() != null) { + x.getObject().accept(this); + } + return false; + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsSchemaStatVisitor.java index 312a62d6b8..cc2dda9398 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsSchemaStatVisitor.java @@ -22,6 +22,7 @@ import com.alibaba.druid.sql.dialect.odps.ast.OdpsAnalyzeTableStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsCreateTableStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsert; import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsertStatement; +import com.alibaba.druid.sql.dialect.odps.ast.OdpsListStmt; import com.alibaba.druid.sql.dialect.odps.ast.OdpsReadStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsRemoveStatisticStatement; import com.alibaba.druid.sql.dialect.odps.ast.OdpsSelectQueryBlock; @@ -227,4 +228,14 @@ public class OdpsSchemaStatVisitor extends SchemaStatVisitor implements OdpsASTV public boolean visit(OdpsShowGrantsStmt x) { return true; } + + @Override + public void endVisit(OdpsListStmt x) { + + } + + @Override + public boolean visit(OdpsListStmt x) { + return true; + } } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsListTest.java b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsListTest.java new file mode 100644 index 0000000000..531a7f9d44 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsListTest.java @@ -0,0 +1,84 @@ +package com.alibaba.druid.bvt.sql.odps; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.odps.parser.OdpsStatementParser; +import com.alibaba.druid.sql.parser.Token; + +public class OdpsListTest extends TestCase { + + public void test_0() throws Exception { + String sql = "list roles"; + OdpsStatementParser parser = new OdpsStatementParser(sql); + SQLStatement stmt = parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toOdpsString(stmt); + // System.out.println(output); + Assert.assertEquals("LIST roles", output); + } + + public void test_1() throws Exception { + String sql = "list users"; + OdpsStatementParser parser = new OdpsStatementParser(sql); + SQLStatement stmt = parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toOdpsString(stmt); + // System.out.println(output); + Assert.assertEquals("LIST users", output); + } + + public void test_2() throws Exception { + String sql = "list functions"; + OdpsStatementParser parser = new OdpsStatementParser(sql); + SQLStatement stmt = parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toOdpsString(stmt); + // System.out.println(output); + Assert.assertEquals("LIST functions", output); + } + + public void test_3() throws Exception { + String sql = "list resources"; + OdpsStatementParser parser = new OdpsStatementParser(sql); + SQLStatement stmt = parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toOdpsString(stmt); + // System.out.println(output); + Assert.assertEquals("LIST resources", output); + } + + public void test_4() throws Exception { + String sql = "list accountproviders"; + OdpsStatementParser parser = new OdpsStatementParser(sql); + SQLStatement stmt = parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toOdpsString(stmt); + // System.out.println(output); + Assert.assertEquals("LIST accountproviders", output); + } + + public void test_5() throws Exception { + String sql = "list jobs"; + OdpsStatementParser parser = new OdpsStatementParser(sql); + SQLStatement stmt = parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toOdpsString(stmt); + // System.out.println(output); + Assert.assertEquals("LIST jobs", output); + } + + public void test_6() throws Exception { + String sql = "list trustedprojects"; + OdpsStatementParser parser = new OdpsStatementParser(sql); + SQLStatement stmt = parser.parseStatementList().get(0); + parser.match(Token.EOF); + String output = SQLUtils.toOdpsString(stmt); + // System.out.println(output); + Assert.assertEquals("LIST trustedprojects", output); + } + +}