mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -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<SQLExpr> parameters = new ArrayList<SQLExpr>();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -135,6 +135,11 @@ public class DB2EvalVisitor extends DB2ASTVisitorAdapter implements SQLEvalVisit
|
||||
public void registerFunction(String funcName, Function function) {
|
||||
functions.put(funcName, function);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterFunction(String funcName) {
|
||||
functions.remove(funcName);
|
||||
}
|
||||
|
||||
public boolean visit(SQLIdentifierExpr x) {
|
||||
return SQLEvalVisitorUtils.visit(this, x);
|
||||
|
||||
@@ -162,4 +162,9 @@ public class MySqlEvalVisitorImpl extends MySqlASTVisitorAdapter implements SQLE
|
||||
public boolean visit(SQLIdentifierExpr x) {
|
||||
return SQLEvalVisitorUtils.visit(this, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterFunction(String funcName) {
|
||||
functions.remove(funcName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,6 +135,11 @@ public class OracleEvalVisitor extends OracleASTVisitorAdapter implements SQLEva
|
||||
public void registerFunction(String funcName, Function function) {
|
||||
functions.put(funcName, function);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterFunction(String funcName) {
|
||||
functions.remove(funcName);
|
||||
}
|
||||
|
||||
public boolean visit(SQLIdentifierExpr x) {
|
||||
return SQLEvalVisitorUtils.visit(this, x);
|
||||
|
||||
@@ -135,6 +135,11 @@ public class PGEvalVisitor extends PGASTVisitorAdapter implements SQLEvalVisitor
|
||||
public void registerFunction(String funcName, Function function) {
|
||||
functions.put(funcName, function);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterFunction(String funcName) {
|
||||
functions.remove(funcName);
|
||||
}
|
||||
|
||||
public boolean visit(SQLIdentifierExpr x) {
|
||||
return SQLEvalVisitorUtils.visit(this, x);
|
||||
|
||||
+5
@@ -136,6 +136,11 @@ public class SQLServerEvalVisitor extends SQLServerASTVisitorAdapter implements
|
||||
functions.put(funcName, function);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterFunction(String funcName) {
|
||||
functions.remove(funcName);
|
||||
}
|
||||
|
||||
public boolean visit(SQLIdentifierExpr x) {
|
||||
return SQLEvalVisitorUtils.visit(this, x);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,8 @@ public interface SQLEvalVisitor extends SQLASTVisitor {
|
||||
Function getFunction(String funcName);
|
||||
|
||||
void registerFunction(String funcName, Function function);
|
||||
|
||||
void unregisterFunction(String funcName);
|
||||
|
||||
List<Object> getParameters();
|
||||
|
||||
|
||||
@@ -138,4 +138,9 @@ public class SQLEvalVisitorImpl extends SQLASTVisitorAdapter implements SQLEvalV
|
||||
public boolean visit(SQLIdentifierExpr x) {
|
||||
return SQLEvalVisitorUtils.visit(this, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterFunction(String funcName) {
|
||||
functions.remove(funcName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,7 +228,11 @@ public class SQLEvalVisitorUtils {
|
||||
public static boolean visit(SQLEvalVisitor visitor, SQLMethodInvokeExpr x) {
|
||||
String methodName = x.getMethodName().toLowerCase();
|
||||
|
||||
Function function = functions.get(methodName);
|
||||
Function function = visitor.getFunction(methodName);
|
||||
|
||||
if (function == null) {
|
||||
function = functions.get(methodName);
|
||||
}
|
||||
|
||||
if (function != null) {
|
||||
Object result = function.eval(visitor, x);
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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;
|
||||
import com.alibaba.druid.sql.visitor.SQLEvalVisitor;
|
||||
|
||||
public class Nil implements Function {
|
||||
|
||||
public final static Nil instance = new Nil();
|
||||
|
||||
@Override
|
||||
public Object eval(SQLEvalVisitor visitor, SQLMethodInvokeExpr x) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -100,7 +100,9 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement;
|
||||
import com.alibaba.druid.sql.visitor.ExportParameterVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLEvalVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLEvalVisitorUtils;
|
||||
import com.alibaba.druid.sql.visitor.functions.Nil;
|
||||
import com.alibaba.druid.support.logging.Log;
|
||||
import com.alibaba.druid.support.logging.LogFactory;
|
||||
import com.alibaba.druid.util.JdbcUtils;
|
||||
@@ -739,7 +741,7 @@ public class WallVisitorUtils {
|
||||
dbType = wallContext.getDbType();
|
||||
}
|
||||
|
||||
return SQLEvalVisitorUtils.eval(dbType, x, Collections.emptyList(), false);
|
||||
return eval(dbType, x, Collections.emptyList());
|
||||
}
|
||||
|
||||
public static SQLExpr getFirst(SQLExpr x) {
|
||||
@@ -1042,7 +1044,7 @@ public class WallVisitorUtils {
|
||||
|| x instanceof SQLInListExpr //
|
||||
|| x instanceof SQLUnaryExpr //
|
||||
) {
|
||||
return SQLEvalVisitorUtils.eval(dbType, x, Collections.emptyList(), false);
|
||||
return eval(dbType, x, Collections.emptyList());
|
||||
}
|
||||
|
||||
if (visitor != null && (!visitor.getConfig().isCaseConditionAllow()) && x instanceof SQLCaseExpr) {
|
||||
@@ -1065,11 +1067,21 @@ public class WallVisitorUtils {
|
||||
}
|
||||
}
|
||||
|
||||
return SQLEvalVisitorUtils.eval(dbType, x, Collections.emptyList(), false);
|
||||
return eval(dbType, x, Collections.emptyList());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Object eval(String dbType, SQLObject sqlObject, List<Object> parameters) {
|
||||
SQLEvalVisitor visitor = SQLEvalVisitorUtils.createEvalVisitor(dbType);
|
||||
visitor.setParameters(parameters);
|
||||
visitor.registerFunction("rand", Nil.instance);
|
||||
sqlObject.accept(visitor);
|
||||
|
||||
Object value = SQLEvalVisitorUtils.getValue(sqlObject);
|
||||
return value;
|
||||
}
|
||||
|
||||
public static boolean isSimpleCountTableSource(WallVisitor visitor, SQLTableSource tableSource) {
|
||||
if (!(tableSource instanceof SQLSubqueryTableSource)) {
|
||||
|
||||
@@ -0,0 +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.bvt.filter.wall;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
import com.alibaba.druid.wall.WallProvider;
|
||||
import com.alibaba.druid.wall.spi.MySqlWallProvider;
|
||||
|
||||
public class MySqlWallTest144 extends TestCase {
|
||||
|
||||
public void test_false() throws Exception {
|
||||
WallProvider provider = new MySqlWallProvider();
|
||||
|
||||
String sql = "select min(id) from wx_interact where activityid=1008 group by true_name,mobile having rand()<1";
|
||||
Assert.assertTrue(provider.checkValid(sql));
|
||||
}
|
||||
}
|
||||
@@ -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<SQLStatement> 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")));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user