diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLIdentifierExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLIdentifierExpr.java index c527b3ae10..3e1a9a368a 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLIdentifierExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLIdentifierExpr.java @@ -15,7 +15,6 @@ */ package com.alibaba.druid.sql.ast.expr; -import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.SQLExprImpl; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.visitor.SQLASTVisitor; @@ -58,8 +57,8 @@ public class SQLIdentifierExpr extends SQLExprImpl implements SQLName { this.lowerName = lowerName; } - public String toString() { - return SQLUtils.toSQLString(this); + public void output(StringBuffer buf) { + buf.append(this.name); } protected void accept0(SQLASTVisitor visitor) { diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCallStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCallStatement.java index 5d59620f1e..f465f281b6 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCallStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCallStatement.java @@ -21,14 +21,27 @@ import java.util.List; import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.SQLStatementImpl; +import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; import com.alibaba.druid.sql.visitor.SQLASTVisitor; public class SQLCallStatement extends SQLStatementImpl { + private boolean brace = false; + + private SQLVariantRefExpr outParameter; + private SQLName procedureName; private final List parameters = new ArrayList(); + public SQLVariantRefExpr getOutParameter() { + return outParameter; + } + + public void setOutParameter(SQLVariantRefExpr outParameter) { + this.outParameter = outParameter; + } + public SQLName getProcedureName() { return procedureName; } @@ -41,11 +54,21 @@ public class SQLCallStatement extends SQLStatementImpl { return parameters; } + public boolean isBrace() { + return brace; + } + + public void setBrace(boolean brace) { + this.brace = brace; + } + protected void accept0(SQLASTVisitor visitor) { if (visitor.visit(this)) { + acceptChild(visitor, this.outParameter); acceptChild(visitor, this.procedureName); acceptChild(visitor, this.parameters); } visitor.endVisit(this); } + } diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java index b62ded9360..11f7259ddf 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java @@ -25,6 +25,7 @@ import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; import com.alibaba.druid.sql.ast.expr.SQLListExpr; import com.alibaba.druid.sql.ast.expr.SQLQueryExpr; +import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; import com.alibaba.druid.sql.ast.statement.SQLAlterTableAddColumn; import com.alibaba.druid.sql.ast.statement.SQLAlterTableAddConstraint; import com.alibaba.druid.sql.ast.statement.SQLAlterTableAddIndex; @@ -1115,10 +1116,18 @@ public class SQLStatementParser extends SQLParser { lexer.nextToken(); brace = true; } + + SQLCallStatement stmt = new SQLCallStatement(); + + if (lexer.token() == Token.QUES) { + lexer.nextToken(); + accept(Token.EQ); + stmt.setOutParameter(new SQLVariantRefExpr("?")); + } acceptIdentifier("CALL"); - SQLCallStatement stmt = new SQLCallStatement(); + stmt.setProcedureName(exprParser.name()); if (lexer.token() == Token.LPAREN) { @@ -1129,6 +1138,7 @@ public class SQLStatementParser extends SQLParser { if (brace) { accept(Token.RBRACE); + stmt.setBrace(true); } return stmt; diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java index a621694ac1..b4349ef25d 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -1141,11 +1141,23 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab @Override public boolean visit(SQLCallStatement x) { + if (x.isBrace()) { + print("{"); + } + if (x.getOutParameter() != null) { + x.getOutParameter().accept(this); + print(" = "); + } + print("CALL "); x.getProcedureName().accept(this); print('('); + printAndAccept(x.getParameters(), ", "); print(')'); + if (x.isBrace()) { + print("}"); + } return false; } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/functions/Nil.java b/src/main/java/com/alibaba/druid/sql/visitor/functions/Nil.java index c14868084b..17cca7a131 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/functions/Nil.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/functions/Nil.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.visitor.functions; import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCallTest2.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCallTest2.java new file mode 100644 index 0000000000..bc802eb48d --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleCallTest2.java @@ -0,0 +1,56 @@ +/* + * 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.oracle; + +import java.util.List; + +import org.junit.Assert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; + +public class OracleCallTest2 extends OracleTest { + + public void test_0() throws Exception { + String sql = "{?= call FUNC_QUERY_DEPT(?,?)}"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statemen = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statemen.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(0, visitor.getTables().size()); + +// Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("departments"))); + + Assert.assertEquals(0, visitor.getColumns().size()); + +// Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("departments", "department_id"))); + } +}