/*
* Copyright 1999-2011 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.wall.spi;
import static com.alibaba.druid.sql.visitor.SQLEvalVisitor.EVAL_VALUE;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Set;
import java.util.Stack;
import com.alibaba.druid.sql.SQLUtils;
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.SQLAggregateExpr;
import com.alibaba.druid.sql.ast.expr.SQLAllColumnExpr;
import com.alibaba.druid.sql.ast.expr.SQLBetweenExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
import com.alibaba.druid.sql.ast.expr.SQLCaseExpr;
import com.alibaba.druid.sql.ast.expr.SQLCaseExpr.Item;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.sql.ast.expr.SQLExistsExpr;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLInListExpr;
import com.alibaba.druid.sql.ast.expr.SQLInSubQueryExpr;
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.alibaba.druid.sql.ast.expr.SQLNCharExpr;
import com.alibaba.druid.sql.ast.expr.SQLNotExpr;
import com.alibaba.druid.sql.ast.expr.SQLNumberExpr;
import com.alibaba.druid.sql.ast.expr.SQLNumericLiteralExpr;
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
import com.alibaba.druid.sql.ast.expr.SQLUnaryExpr;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLCallStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateIndexStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateViewStatement;
import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement;
import com.alibaba.druid.sql.ast.statement.SQLDropIndexStatement;
import com.alibaba.druid.sql.ast.statement.SQLDropSequenceStatement;
import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLDropTriggerStatement;
import com.alibaba.druid.sql.ast.statement.SQLDropViewStatement;
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
import com.alibaba.druid.sql.ast.statement.SQLInsertInto;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause;
import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource;
import com.alibaba.druid.sql.ast.statement.SQLRollbackStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelect;
import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause;
import com.alibaba.druid.sql.ast.statement.SQLSelectItem;
import com.alibaba.druid.sql.ast.statement.SQLSelectQuery;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.ast.statement.SQLSetStatement;
import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.ast.statement.SQLTruncateStatement;
import com.alibaba.druid.sql.ast.statement.SQLUnionOperator;
import com.alibaba.druid.sql.ast.statement.SQLUnionQuery;
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.ast.statement.SQLUseStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlBooleanExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOutFileExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCommitStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDeleteStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDescribeStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplaceStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetCharSetStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetNamesStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowGrantsStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateSequenceStatement;
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.dialect.sqlserver.ast.stmt.SQLServerInsertStatement;
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;
import com.alibaba.druid.util.ServletPathMatcher;
import com.alibaba.druid.util.StringUtils;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallConfig.TenantCallBack;
import com.alibaba.druid.wall.WallConfig.TenantCallBack.StatementType;
import com.alibaba.druid.wall.WallContext;
import com.alibaba.druid.wall.WallProvider;
import com.alibaba.druid.wall.WallSqlTableStat;
import com.alibaba.druid.wall.WallVisitor;
import com.alibaba.druid.wall.violation.ErrorCode;
import com.alibaba.druid.wall.violation.IllegalSQLObjectViolation;
public class WallVisitorUtils {
private final static Log LOG = LogFactory.getLog(WallVisitorUtils.class);
public final static String HAS_TRUE_LIKE = "hasTrueLike";
public static void check(WallVisitor visitor, SQLInListExpr x) {
}
public static boolean check(WallVisitor visitor, SQLBinaryOpExpr x) {
if (x.getOperator() == SQLBinaryOperator.BooleanOr || x.getOperator() == SQLBinaryOperator.BooleanAnd) {
List<SQLExpr> groupList = SQLUtils.split(x);
for (SQLExpr item : groupList) {
item.accept(visitor);
}
return false;
}
if (x.getOperator() == SQLBinaryOperator.Add || x.getOperator() == SQLBinaryOperator.Concat) {
List<SQLExpr> groupList = SQLUtils.split(x);
if (groupList.size() >= 4) {
int chrCount = 0;
for (int i = 0; i < groupList.size(); ++i) {
SQLExpr item = groupList.get(i);
if (item instanceof SQLMethodInvokeExpr) {
SQLMethodInvokeExpr methodExpr = (SQLMethodInvokeExpr) item;
String methodName = methodExpr.getMethodName().toLowerCase();
if ("chr".equals(methodName) || "char".equals(methodName)) {
if (methodExpr.getParameters().get(0) instanceof SQLLiteralExpr) {
chrCount++;
}
}
}
}
if (chrCount >= 4) {
addViolation(visitor, ErrorCode.EVIL_CONCAT, "evil concat", x);
}
}
}
return true;
}
public static void check(WallVisitor visitor, SQLCreateTableStatement x) {
String tableName = ((SQLName) x.getName()).getSimleName();
WallContext context = WallContext.current();
if (context != null) {
WallSqlTableStat tableStat = context.getTableStat(tableName);
if (tableStat != null) {
tableStat.incrementCreateCount();
}
}
}
public static void check(WallVisitor visitor, SQLAlterTableStatement x) {
String tableName = ((SQLName) x.getName()).getSimleName();
WallContext context = WallContext.current();
if (context != null) {
WallSqlTableStat tableStat = context.getTableStat(tableName);
if (tableStat != null) {
tableStat.incrementAlterCount();
}
}
}
public static void check(WallVisitor visitor, SQLDropTableStatement x) {
for (SQLTableSource item : x.getTableSources()) {
if (item instanceof SQLExprTableSource) {
SQLExpr expr = ((SQLExprTableSource) item).getExpr();
String tableName = ((SQLName) expr).getSimleName();
WallContext context = WallContext.current();
if (context != null) {
WallSqlTableStat tableStat = context.getTableStat(tableName);
if (tableStat != null) {
tableStat.incrementDropCount();
}
}
}
}
}
public static void check(WallVisitor visitor, SQLSelectItem x) {
SQLExpr expr = x.getExpr();
if (expr instanceof SQLVariantRefExpr) {
if (!isTopSelectItem(expr) && "@".equals(((SQLVariantRefExpr) expr).getName())) {
addViolation(visitor, ErrorCode.EVIL_NAME, "@ not allow", x);
}
}
if (visitor.getConfig().isSelectAllColumnAllow()) {
return;
}
if (expr instanceof SQLAllColumnExpr //
&& x.getParent() instanceof SQLSelectQueryBlock) {
SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) x.getParent();
SQLTableSource from = queryBlock.getFrom();
if (from instanceof SQLExprTableSource) {
addViolation(visitor, ErrorCode.SELECT_NOT_ALLOW, "'SELECT *' not allow", x);
}
}
}
public static void check(WallVisitor visitor, SQLPropertyExpr x) {
checkSchema(visitor, x.getOwner());
}
public static void checkInsert(WallVisitor visitor, SQLInsertInto x) {
checkReadOnly(visitor, x.getTableSource());
if (!visitor.getConfig().isInsertAllow()) {
addViolation(visitor, ErrorCode.INSERT_NOT_ALLOW, "insert not allow", x);
}
checkInsertForMultiTenant(visitor, x);
}
public static void checkSelelct(WallVisitor visitor, SQLSelectQueryBlock x) {
for (SQLSelectItem item : x.getSelectList()) {
item.setParent(x);
}
if (x.getInto() != null) {
checkReadOnly(visitor, x.getInto());
}
if (!visitor.getConfig().isSelectIntoAllow() && x.getInto() != null) {
addViolation(visitor, ErrorCode.SELECT_INTO_NOT_ALLOW, "select into not allow", x);
return;
}
if (x.getFrom() != null) {
x.getFrom().setParent(x);
}
SQLExpr where = x.getWhere();
if (where != null) {
where.setParent(x);
checkCondition(visitor, x.getWhere());
Object whereValue = getConditionValue(visitor, where, visitor.getConfig().isSelectWhereAlwayTrueCheck());
if (Boolean.TRUE == whereValue) {
if (queryBlockFromIsNull(visitor, x, false)) {
addViolation(visitor, ErrorCode.EMPTY_QUERY_HAS_CONDITION, "empty select has condition", x);
}
if (!isSimpleConstExpr(where)) {// 简单表达式
addViolation(visitor, ErrorCode.ALWAY_TRUE, "select alway true condition not allow", x);
}
}
}
checkSelectForMultiTenant(visitor, x);
// checkConditionForMultiTenant(visitor, x.getWhere(), x);
}
public static void checkHaving(WallVisitor visitor, SQLExpr x) {
if (x == null) {
return;
}
if (Boolean.TRUE == getConditionValue(visitor, x, visitor.getConfig().isSelectHavingAlwayTrueCheck())) {
if (!isSimpleConstExpr(x)) {
addViolation(visitor, ErrorCode.ALWAY_TRUE, "having alway true condition not allow", x);
}
}
}
public static void checkDelete(WallVisitor visitor, SQLDeleteStatement x) {
checkReadOnly(visitor, x.getTableSource());
WallConfig config = visitor.getConfig();
if (!config.isDeleteAllow()) {
addViolation(visitor, ErrorCode.INSERT_NOT_ALLOW, "delete not allow", x);
return;
}
boolean hasUsing = false;
if (x instanceof MySqlDeleteStatement) {
hasUsing = ((MySqlDeleteStatement) x).getUsing() != null;
}
boolean isJoinTableSource = x.getTableSource() instanceof SQLJoinTableSource;
if (x.getWhere() == null && (!hasUsing) && !isJoinTableSource) {
WallContext context = WallContext.current();
if (context != null) {
context.incrementDeleteNoneConditionWarnnings();
}
if (config.isDeleteWhereNoneCheck()) {
addViolation(visitor, ErrorCode.NONE_CONDITION, "delete none condition not allow", x);
return;
}
}
SQLExpr where = x.getWhere();
if (where != null) {
checkCondition(visitor, where);
if (Boolean.TRUE == getConditionValue(visitor, where, config.isDeleteWhereAlwayTrueCheck())) {
if (!isSimpleConstExpr(where)) {
addViolation(visitor, ErrorCode.ALWAY_TRUE, "delete alway true condition not allow", x);
}
}
}
// checkConditionForMultiTenant(visitor, x.getWhere(), x);
}
private static boolean isSimpleConstExpr(SQLExpr sqlExpr) {
List<SQLExpr> parts = getParts(sqlExpr);
if (parts.isEmpty()) {
return false;
}
for (SQLExpr part : parts) {
boolean isSimpleConstExpr = false;
if (part == sqlExpr || part instanceof SQLLiteralExpr) {
isSimpleConstExpr = true;
} else if (part instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr binaryOpExpr = (SQLBinaryOpExpr) part;
if (binaryOpExpr.getOperator() == SQLBinaryOperator.Equality
|| binaryOpExpr.getOperator() == SQLBinaryOperator.NotEqual
|| binaryOpExpr.getOperator() == SQLBinaryOperator.GreaterThan) {
if (binaryOpExpr.getLeft() instanceof SQLIntegerExpr
&& binaryOpExpr.getRight() instanceof SQLIntegerExpr) {
isSimpleConstExpr = true;
}
}
}
if (!isSimpleConstExpr) {
return false;
}
}
return true;
}
private static void checkCondition(WallVisitor visitor, SQLExpr x) {
if (x == null) {
return;
}
if (visitor.getConfig().isMustParameterized()) {
ExportParameterVisitor exportParameterVisitor = visitor.getProvider().createExportParameterVisitor();
x.accept(exportParameterVisitor);
if (exportParameterVisitor.getParameters().size() > 0) {
addViolation(visitor, ErrorCode.NOT_PARAMETERIZED, "sql must parameterized", x);
return;
}
}
}
private static void checkJoinSelectForMultiTenant(WallVisitor visitor, SQLJoinTableSource join,
SQLSelectQueryBlock x) {
TenantCallBack tenantCallBack = visitor.getConfig().getTenantCallBack();
String tenantTablePattern = visitor.getConfig().getTenantTablePattern();
if (tenantCallBack == null && (tenantTablePattern == null || tenantTablePattern.length() == 0)) {
return;
}
SQLTableSource right = join.getRight();
if (right instanceof SQLExprTableSource) {
SQLExpr tableExpr = ((SQLExprTableSource) right).getExpr();
if (tableExpr instanceof SQLIdentifierExpr) {
String tableName = ((SQLIdentifierExpr) tableExpr).getName();
String alias = null;
String tenantColumn = null;
if (tenantCallBack != null) {
tenantColumn = tenantCallBack.getTenantColumn(StatementType.SELECT, tableName);
}
if (StringUtils.isEmpty(tenantColumn)
&& ServletPathMatcher.getInstance().matches(tenantTablePattern, tableName)) {
tenantColumn = visitor.getConfig().getTenantColumn();
}
if (!StringUtils.isEmpty(tenantColumn)) {
alias = right.getAlias();
if (alias == null) {
alias = tableName;
}
SQLExpr item = null;
if (alias != null) {
item = new SQLPropertyExpr(new SQLIdentifierExpr(alias), tenantColumn);
} else {
item = new SQLIdentifierExpr(tenantColumn);
}
SQLSelectItem selectItem = new SQLSelectItem(item);
x.getSelectList().add(selectItem);
visitor.setSqlModified(true);
}
}
}
}
private static boolean isSelectStatmentForMultiTenant(SQLSelectQueryBlock queryBlock) {
SQLObject parent = queryBlock.getParent();
while (parent != null) {
if (parent instanceof SQLUnionQuery) {
SQLObject x = parent;
parent = x.getParent();
} else {
break;
}
}
if (!(parent instanceof SQLSelect)) {
return false;
}
parent = ((SQLSelect) parent).getParent();
if (parent instanceof SQLSelectStatement) {
return true;
}
return false;
}
private static void checkSelectForMultiTenant(WallVisitor visitor, SQLSelectQueryBlock x) {
TenantCallBack tenantCallBack = visitor.getConfig().getTenantCallBack();
String tenantTablePattern = visitor.getConfig().getTenantTablePattern();
if (tenantCallBack == null && (tenantTablePattern == null || tenantTablePattern.length() == 0)) {
return;
}
if (x == null) {
throw new IllegalStateException("x is null");
}
if (!isSelectStatmentForMultiTenant(x)) {
return;
}
SQLTableSource tableSource = x.getFrom();
String alias = null;
String matchTableName = null;
String tenantColumn = null;
if (tableSource instanceof SQLExprTableSource) {
SQLExpr tableExpr = ((SQLExprTableSource) tableSource).getExpr();
if (tableExpr instanceof SQLIdentifierExpr) {
String tableName = ((SQLIdentifierExpr) tableExpr).getName();
if (tenantCallBack != null) {
tenantColumn = tenantCallBack.getTenantColumn(StatementType.SELECT, tableName);
}
if (StringUtils.isEmpty(tenantColumn)
&& ServletPathMatcher.getInstance().matches(tenantTablePattern, tableName)) {
tenantColumn = visitor.getConfig().getTenantColumn();
}
if (!StringUtils.isEmpty(tenantColumn)) {
matchTableName = tableName;
alias = tableSource.getAlias();
}
}
} else if (tableSource instanceof SQLJoinTableSource) {
SQLJoinTableSource join = (SQLJoinTableSource) tableSource;
if (join.getLeft() instanceof SQLExprTableSource) {
SQLExpr tableExpr = ((SQLExprTableSource) join.getLeft()).getExpr();
if (tableExpr instanceof SQLIdentifierExpr) {
String tableName = ((SQLIdentifierExpr) tableExpr).getName();
if (tenantCallBack != null) {
tenantColumn = tenantCallBack.getTenantColumn(StatementType.SELECT, tableName);
}
if (StringUtils.isEmpty(tenantColumn)
&& ServletPathMatcher.getInstance().matches(tenantTablePattern, tableName)) {
tenantColumn = visitor.getConfig().getTenantColumn();
}
if (!StringUtils.isEmpty(tenantColumn)) {
matchTableName = tableName;
alias = join.getLeft().getAlias();
if (alias == null) {
alias = tableName;
}
}
}
checkJoinSelectForMultiTenant(visitor, join, x);
} else {
checkJoinSelectForMultiTenant(visitor, join, x);
}
}
if (matchTableName == null) {
return;
}
SQLExpr item = null;
if (alias != null) {
item = new SQLPropertyExpr(new SQLIdentifierExpr(alias), tenantColumn);
} else {
item = new SQLIdentifierExpr(tenantColumn);
}
SQLSelectItem selectItem = new SQLSelectItem(item);
x.getSelectList().add(selectItem);
visitor.setSqlModified(true);
}
private static void checkUpdateForMultiTenant(WallVisitor visitor, SQLUpdateStatement x) {
TenantCallBack tenantCallBack = visitor.getConfig().getTenantCallBack();
String tenantTablePattern = visitor.getConfig().getTenantTablePattern();
if (tenantCallBack == null && (tenantTablePattern == null || tenantTablePattern.length() == 0)) {
return;
}
if (x == null) {
throw new IllegalStateException("x is null");
}
SQLTableSource tableSource = x.getTableSource();
String alias = null;
String matchTableName = null;
String tenantColumn = null;
if (tableSource instanceof SQLExprTableSource) {
SQLExpr tableExpr = ((SQLExprTableSource) tableSource).getExpr();
if (tableExpr instanceof SQLIdentifierExpr) {
String tableName = ((SQLIdentifierExpr) tableExpr).getName();
if (tenantCallBack != null) {
tenantColumn = tenantCallBack.getTenantColumn(StatementType.UPDATE, tableName);
}
if (StringUtils.isEmpty(tenantColumn)
&& ServletPathMatcher.getInstance().matches(tenantTablePattern, tableName)) {
tenantColumn = visitor.getConfig().getTenantColumn();
}
if (!StringUtils.isEmpty(tenantColumn)) {
matchTableName = tableName;
alias = tableSource.getAlias();
}
}
}
if (matchTableName == null) {
return;
}
SQLExpr item = null;
if (alias != null) {
item = new SQLPropertyExpr(new SQLIdentifierExpr(alias), tenantColumn);
} else {
item = new SQLIdentifierExpr(tenantColumn);
}
SQLExpr value = generateTenantValue(visitor, alias, StatementType.UPDATE, matchTableName);
SQLUpdateSetItem updateSetItem = new SQLUpdateSetItem();
updateSetItem.setColumn(item);
updateSetItem.setValue(value);
x.getItems().add(updateSetItem);
visitor.setSqlModified(true);
}
private static void checkInsertForMultiTenant(WallVisitor visitor, SQLInsertInto x) {
TenantCallBack tenantCallBack = visitor.getConfig().getTenantCallBack();
String tenantTablePattern = visitor.getConfig().getTenantTablePattern();
if (tenantCallBack == null && (tenantTablePattern == null || tenantTablePattern.length() == 0)) {
return;
}
if (x == null) {
throw new IllegalStateException("x is null");
}
SQLExprTableSource tableSource = x.getTableSource();
String alias = null;
String matchTableName = null;
String tenantColumn = null;
SQLExpr tableExpr = tableSource.getExpr();
if (tableExpr instanceof SQLIdentifierExpr) {
String tableName = ((SQLIdentifierExpr) tableExpr).getName();
if (tenantCallBack != null) {
tenantColumn = tenantCallBack.getTenantColumn(StatementType.INSERT, tableName);
}
if (StringUtils.isEmpty(tenantColumn)
&& ServletPathMatcher.getInstance().matches(tenantTablePattern, tableName)) {
tenantColumn = visitor.getConfig().getTenantColumn();
}
if (!StringUtils.isEmpty(tenantColumn)) {
matchTableName = tableName;
alias = tableSource.getAlias();
}
}
if (matchTableName == null) {
return;
}
SQLExpr item = null;
if (alias != null) {
item = new SQLPropertyExpr(new SQLIdentifierExpr(alias), tenantColumn);
} else {
item = new SQLIdentifierExpr(tenantColumn);
}
SQLExpr value = generateTenantValue(visitor, alias, StatementType.INSERT, matchTableName);
// add insert item and value
x.getColumns().add(item);
List<ValuesClause> valuesClauses = null;
ValuesClause valuesClause = null;
if (x instanceof MySqlInsertStatement) {
valuesClauses = ((MySqlInsertStatement) x).getValuesList();
} else if (x instanceof SQLServerInsertStatement) {
valuesClauses = ((MySqlInsertStatement) x).getValuesList();
} else {
valuesClause = x.getValues();
}
if (valuesClauses != null && valuesClauses.size() > 0) {
for (ValuesClause clause : valuesClauses) {
clause.addValue(value);
}
}
if (valuesClause != null) {
valuesClause.addValue(value);
}
// insert .. select
SQLSelect select = x.getQuery();
if (select != null) {
List<SQLSelectQueryBlock> queryBlocks = splitSQLSelectQuery(select.getQuery());
for (SQLSelectQueryBlock queryBlock : queryBlocks) {
queryBlock.getSelectList().add(new SQLSelectItem(value));
}
}
visitor.setSqlModified(true);
}
private static List<SQLSelectQueryBlock> splitSQLSelectQuery(SQLSelectQuery x) {
List<SQLSelectQueryBlock> groupList = new ArrayList<SQLSelectQueryBlock>();
Stack<SQLSelectQuery> stack = new Stack<SQLSelectQuery>();
stack.push(x);
do {
SQLSelectQuery query = stack.pop();
if (query instanceof SQLSelectQueryBlock) {
groupList.add((SQLSelectQueryBlock) query);
} else if (query instanceof SQLUnionQuery) {
SQLUnionQuery unionQuery = (SQLUnionQuery) query;
stack.push(unionQuery.getLeft());
stack.push(unionQuery.getRight());
}
} while (!stack.empty());
return groupList;
}
@Deprecated
public static void checkConditionForMultiTenant(WallVisitor visitor, SQLExpr x, SQLObject parent) {
String tenantTablePattern = visitor.getConfig().getTenantTablePattern();
if (tenantTablePattern == null || tenantTablePattern.length() == 0) {
return;
}
if (parent == null) {
throw new IllegalStateException("parent is null");
}
String alias = null;
SQLTableSource tableSource;
StatementType statementType = null;
if (parent instanceof SQLDeleteStatement) {
tableSource = ((SQLDeleteStatement) parent).getTableSource();
statementType = StatementType.DELETE;
} else if (parent instanceof SQLUpdateStatement) {
tableSource = ((SQLUpdateStatement) parent).getTableSource();
statementType = StatementType.UPDATE;
} else if (parent instanceof SQLSelectQueryBlock) {
tableSource = ((SQLSelectQueryBlock) parent).getFrom();
statementType = StatementType.SELECT;
} else {
throw new IllegalStateException("not support parent : " + parent.getClass());
}
String matchTableName = null;
if (tableSource instanceof SQLExprTableSource) {
SQLExpr tableExpr = ((SQLExprTableSource) tableSource).getExpr();
if (tableExpr instanceof SQLIdentifierExpr) {
String tableName = ((SQLIdentifierExpr) tableExpr).getName();
if (ServletPathMatcher.getInstance().matches(tenantTablePattern, tableName)) {
matchTableName = tableName;
alias = tableSource.getAlias();
}
}
} else if (tableSource instanceof SQLJoinTableSource) {
SQLJoinTableSource join = (SQLJoinTableSource) tableSource;
if (join.getLeft() instanceof SQLExprTableSource) {
SQLExpr tableExpr = ((SQLExprTableSource) join.getLeft()).getExpr();
if (tableExpr instanceof SQLIdentifierExpr) {
String tableName = ((SQLIdentifierExpr) tableExpr).getName();
if (ServletPathMatcher.getInstance().matches(tenantTablePattern, tableName)) {
matchTableName = tableName;
alias = join.getLeft().getAlias();
}
}
checkJoinConditionForMultiTenant(visitor, join, false, statementType);
} else {
checkJoinConditionForMultiTenant(visitor, join, true, statementType);
}
}
if (matchTableName == null) {
return;
}
SQLBinaryOpExpr tenantCondition = createTenantCondition(visitor, alias, statementType, matchTableName);
SQLExpr condition;
if (x == null) {
condition = tenantCondition;
} else {
condition = new SQLBinaryOpExpr(tenantCondition, SQLBinaryOperator.BooleanAnd, x);
}
if (parent instanceof SQLDeleteStatement) {
SQLDeleteStatement deleteStmt = (SQLDeleteStatement) parent;
deleteStmt.setWhere(condition);
visitor.setSqlModified(true);
} else if (parent instanceof SQLUpdateStatement) {
SQLUpdateStatement updateStmt = (SQLUpdateStatement) parent;
updateStmt.setWhere(condition);
visitor.setSqlModified(true);
} else if (parent instanceof SQLSelectQueryBlock) {
SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) parent;
queryBlock.setWhere(condition);
visitor.setSqlModified(true);
}
}
@Deprecated
public static void checkJoinConditionForMultiTenant(WallVisitor visitor, SQLJoinTableSource join,
boolean checkLeft, StatementType statementType) {
String tenantTablePattern = visitor.getConfig().getTenantTablePattern();
if (tenantTablePattern == null || tenantTablePattern.length() == 0) {
return;
}
SQLExpr condition = join.getCondition();
SQLTableSource right = join.getRight();
if (right instanceof SQLExprTableSource) {
SQLExpr tableExpr = ((SQLExprTableSource) right).getExpr();
if (tableExpr instanceof SQLIdentifierExpr) {
String tableName = ((SQLIdentifierExpr) tableExpr).getName();
if (ServletPathMatcher.getInstance().matches(tenantTablePattern, tableName)) {
String alias = right.getAlias();
if (alias == null) {
alias = tableName;
}
SQLBinaryOpExpr tenantCondition = createTenantCondition(visitor, alias, statementType, tableName);
if (condition == null) {
condition = tenantCondition;
} else {
condition = new SQLBinaryOpExpr(tenantCondition, SQLBinaryOperator.BooleanAnd, condition);
}
}
}
}
if (condition != join.getCondition()) {
join.setCondition(condition);
visitor.setSqlModified(true);
}
}
@Deprecated
private static SQLBinaryOpExpr createTenantCondition(WallVisitor visitor, String alias,
StatementType statementType, String tableName) {
SQLExpr left, right;
if (alias != null) {
left = new SQLPropertyExpr(new SQLIdentifierExpr(alias), visitor.getConfig().getTenantColumn());
} else {
left = new SQLIdentifierExpr(visitor.getConfig().getTenantColumn());
}
right = generateTenantValue(visitor, alias, statementType, tableName);
SQLBinaryOpExpr tenantCondition = new SQLBinaryOpExpr(left, SQLBinaryOperator.Equality, right);
return tenantCondition;
}
private static SQLExpr generateTenantValue(WallVisitor visitor, String alias, StatementType statementType,
String tableName) {
SQLExpr value;
TenantCallBack callBack = visitor.getConfig().getTenantCallBack();
if (callBack != null) {
WallProvider.setTenantValue(callBack.getTenantValue(statementType, tableName));
}
Object tenantValue = WallProvider.getTenantValue();
if (tenantValue instanceof Number) {
value = new SQLNumberExpr((Number) tenantValue);
} else if (tenantValue instanceof String) {
value = new SQLCharExpr((String) tenantValue);
} else {
throw new IllegalStateException("tenant value not support type " + tenantValue);
}
return value;
}
public static void checkReadOnly(WallVisitor visitor, SQLTableSource tableSource) {
if (tableSource instanceof SQLExprTableSource) {
String tableName = null;
SQLExpr tableNameExpr = ((SQLExprTableSource) tableSource).getExpr();
if (tableNameExpr instanceof SQLName) {
tableName = ((SQLName) tableNameExpr).getSimleName();
}
boolean readOnlyValid = visitor.getProvider().checkReadOnlyTable(tableName);
if (!readOnlyValid) {
addViolation(visitor, ErrorCode.READ_ONLY, "table readonly : " + tableName, tableSource);
}
} else if (tableSource instanceof SQLJoinTableSource) {
SQLJoinTableSource join = (SQLJoinTableSource) tableSource;
checkReadOnly(visitor, join.getLeft());
checkReadOnly(visitor, join.getRight());
}
}
public static void checkUpdate(WallVisitor visitor, SQLUpdateStatement x) {
checkReadOnly(visitor, x.getTableSource());
WallConfig config = visitor.getConfig();
if (!config.isUpdateAllow()) {
addViolation(visitor, ErrorCode.UPDATE_NOT_ALLOW, "update not allow", x);
return;
}
SQLExpr where = x.getWhere();
if (where == null) {
WallContext context = WallContext.current();
if (context != null) {
context.incrementUpdateNoneConditionWarnnings();
}
if (config.isUpdateWhereNoneCheck()) {
if (x instanceof MySqlUpdateStatement) {
MySqlUpdateStatement mysqlUpdate = (MySqlUpdateStatement) x;
if (mysqlUpdate.getLimit() == null) {
addViolation(visitor, ErrorCode.NONE_CONDITION, "update none condition not allow", x);
return;
}
} else {
addViolation(visitor, ErrorCode.NONE_CONDITION, "update none condition not allow", x);
return;
}
}
} else {
where.setParent(x);
checkCondition(visitor, where);
if (Boolean.TRUE == getConditionValue(visitor, where, config.isUpdateWhereAlayTrueCheck())) {
if (!isSimpleConstExpr(where)) {
addViolation(visitor, ErrorCode.ALWAY_TRUE, "update alway true condition not allow", x);
}
}
}
checkUpdateForMultiTenant(visitor, x);
}
public static Object getValue(WallVisitor visitor, SQLBinaryOpExpr x) {
if (x.getLeft() instanceof SQLName && x.getRight() instanceof SQLName) {
if (x.getLeft().toString().equalsIgnoreCase(x.getRight().toString())) {
if (x.getOperator() == SQLBinaryOperator.Equality) {
return Boolean.TRUE;
} else if (x.getOperator() == SQLBinaryOperator.NotEqual) {
return Boolean.FALSE;
}
switch (x.getOperator()) {
case Equality:
case Like:
return Boolean.TRUE;
case NotEqual:
case GreaterThan:
case GreaterThanOrEqual:
case LessThan:
case LessThanOrEqual:
case LessThanOrGreater:
case NotLike:
return Boolean.FALSE;
default:
break;
}
}
}
if (x.getOperator() == SQLBinaryOperator.BooleanOr) {
List<SQLExpr> groupList = SQLUtils.split(x);
boolean allFalse = true;
for (int i = groupList.size() - 1; i >= 0; --i) {
SQLExpr item = groupList.get(i);
Object result = getValue(visitor, item);
Boolean booleanVal = SQLEvalVisitorUtils.castToBoolean(result);
if (Boolean.TRUE == booleanVal) {
final WallConditionContext wallContext = WallVisitorUtils.getWallConditionContext();
if (wallContext != null && !isFirst(item)) {
wallContext.setPartAlwayTrue(true);
}
return true;
}
if (Boolean.FALSE != booleanVal) {
allFalse = false;
}
}
if (allFalse) {
return false;
}
return null;
}
if (x.getOperator() == SQLBinaryOperator.BooleanAnd) {
List<SQLExpr> groupList = SQLUtils.split(x);
int dalConst = 0;
Boolean allTrue = Boolean.TRUE;
for (int i = groupList.size() - 1; i >= 0; --i) {
SQLExpr item = groupList.get(i);
Object result = getValue(visitor, item);
Boolean booleanVal = SQLEvalVisitorUtils.castToBoolean(result);
if (Boolean.TRUE == booleanVal) {
final WallConditionContext wallContext = WallVisitorUtils.getWallConditionContext();
if (wallContext != null && !isFirst(item)) {
wallContext.setPartAlwayTrue(true);
}
dalConst++;
} else if (Boolean.FALSE == booleanVal) {
final WallConditionContext wallContext = WallVisitorUtils.getWallConditionContext();
if (wallContext != null && !isFirst(item)) {
wallContext.setPartAlwayFalse(true);
}
allTrue = Boolean.FALSE;
dalConst++;
} else {
if (allTrue != Boolean.FALSE) {
allTrue = null;
}
dalConst = 0;
}
if (dalConst == 2 && visitor != null && !visitor.getConfig().isConditionDoubleConstAllow()) {
addViolation(visitor, ErrorCode.DOUBLE_CONST_CONDITION, "double const condition", x);
}
}
if (Boolean.TRUE == allTrue) {
return true;
} else if (Boolean.FALSE == allTrue) {
return false;
}
return null;
}
SQLExpr left = x.getLeft();
SQLExpr right = x.getRight();
Object leftResult = getValue(visitor, left);
Object rightResult = getValue(visitor, right);
if (x.getOperator() == SQLBinaryOperator.Like && leftResult instanceof String && leftResult.equals(rightResult)) {
addViolation(visitor, ErrorCode.SAME_CONST_LIKE, "same const like", x);
}
if (x.getOperator() == SQLBinaryOperator.Like || x.getOperator() == SQLBinaryOperator.NotLike) {
WallContext context = WallContext.current();
if (context != null) {
if (rightResult instanceof Number || leftResult instanceof Number) {
context.incrementLikeNumberWarnnings();
}
}
}
String dbType = null;
WallContext wallContext = WallContext.current();
if (wallContext != null) {
dbType = wallContext.getDbType();
}
return eval(visitor, dbType, x, Collections.emptyList());
}
public static SQLExpr getFirst(SQLExpr x) {
if (x instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr binary = (SQLBinaryOpExpr) x;
if (binary.getOperator() == SQLBinaryOperator.BooleanAnd
|| binary.getOperator() == SQLBinaryOperator.BooleanOr) {
return getFirst(((SQLBinaryOpExpr) x).getLeft());
}
}
return x;
}
public static List<SQLExpr> getParts(SQLExpr x) {
List<SQLExpr> exprs = new ArrayList<SQLExpr>();
exprs.add(x);
while (true) {
List<SQLExpr> tmp = partExpr(exprs);
if (tmp.size() == exprs.size()) {
break;
}
exprs = tmp;
}
return exprs;
}
public static List<SQLExpr> partExpr(List<SQLExpr> exprs) {
List<SQLExpr> partList = new ArrayList<SQLExpr>();
for (SQLExpr x : exprs) {
if (x instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr binary = (SQLBinaryOpExpr) x;
if (binary.getOperator() == SQLBinaryOperator.BooleanAnd
|| binary.getOperator() == SQLBinaryOperator.BooleanOr) {
partList.add(((SQLBinaryOpExpr) x).getLeft());
partList.add(((SQLBinaryOpExpr) x).getRight());
continue;
}
}
partList.add(x);
}
return partList;
}
public static boolean isFirst(SQLObject x) {
if (x == null) {
return true;
}
for (;;) {
SQLObject parent = x.getParent();
if (!(parent instanceof SQLExpr)) {
return true;
}
if (parent instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr binaryExpr = (SQLBinaryOpExpr) parent;
if (x == binaryExpr.getRight()) {
return false;
}
}
x = parent;
}
}
private static boolean hasWhere(SQLSelectQuery selectQuery) {
if (selectQuery instanceof SQLSelectQueryBlock) {
return ((SQLSelectQueryBlock) selectQuery).getWhere() != null;
} else if (selectQuery instanceof SQLUnionQuery) {
SQLUnionQuery union = (SQLUnionQuery) selectQuery;
return hasWhere(union.getLeft()) || hasWhere(union.getRight());
}
return false;
}
public static boolean isWhereOrHaving(SQLObject x) {
if (x == null) {
return false;
}
for (;;) {
SQLObject parent = x.getParent();
if (parent == null) {
return false;
}
if (parent instanceof SQLJoinTableSource) {
SQLJoinTableSource joinTableSource = (SQLJoinTableSource) parent;
if (joinTableSource.getCondition() == x) {
return true;
}
}
if (parent instanceof SQLUnionQuery) {
SQLUnionQuery union = (SQLUnionQuery) parent;
if (union.getRight() == x && hasWhere(union.getLeft())) {
return true;
}
}
if (parent instanceof SQLSelectQueryBlock) {
SQLSelectQueryBlock query = (SQLSelectQueryBlock) parent;
if (query.getWhere() == x) {
return true;
}
}
if (parent instanceof SQLDeleteStatement) {
SQLDeleteStatement delete = (SQLDeleteStatement) parent;
if (delete.getWhere() == x) {
return true;
} else {
return false;
}
}
if (parent instanceof SQLUpdateStatement) {
SQLUpdateStatement update = (SQLUpdateStatement) parent;
if (update.getWhere() == x) {
return true;
} else {
return false;
}
}
if (parent instanceof SQLSelectGroupByClause) {
SQLSelectGroupByClause groupBy = (SQLSelectGroupByClause) parent;
if (x == groupBy.getHaving()) {
return true;
} else {
return false;
}
}
x = parent;
}
}
public static class WallTopStatementContext {
private boolean fromSysTable = false;
private boolean fromSysSchema = false;
private boolean fromPermitTable = false;
public boolean fromSysTable() {
return fromSysTable;
}
public void setFromSysTable(boolean fromSysTable) {
this.fromSysTable = fromSysTable;
}
public boolean fromSysSchema() {
return fromSysSchema;
}
public void setFromSysSchema(boolean fromSysSchema) {
this.fromSysSchema = fromSysSchema;
}
public boolean fromPermitTable() {
return fromPermitTable;
}
public void setFromPermitTable(boolean fromPermitTable) {
this.fromPermitTable = fromPermitTable;
}
}
public static class WallConditionContext {
private boolean partAlwayTrue = false;
private boolean partAlwayFalse = false;
private boolean constArithmetic = false;
private boolean xor = false;
private boolean bitwise = false;
public boolean hasPartAlwayTrue() {
return partAlwayTrue;
}
public void setPartAlwayTrue(boolean partAllowTrue) {
this.partAlwayTrue = partAllowTrue;
}
public boolean hasPartAlwayFalse() {
return partAlwayFalse;
}
public void setPartAlwayFalse(boolean partAlwayFalse) {
this.partAlwayFalse = partAlwayFalse;
}
public boolean hasConstArithmetic() {
return constArithmetic;
}
public void setConstArithmetic(boolean constArithmetic) {
this.constArithmetic = constArithmetic;
}
public boolean hasXor() {
return xor;
}
public void setXor(boolean xor) {
this.xor = xor;
}
public boolean hasBitwise() {
return bitwise;
}
public void setBitwise(boolean bitwise) {
this.bitwise = bitwise;
}
}
private static ThreadLocal<WallConditionContext> wallConditionContextLocal = new ThreadLocal<WallConditionContext>();
private static ThreadLocal<WallTopStatementContext> wallTopStatementContextLocal = new ThreadLocal<WallTopStatementContext>();
public static WallConditionContext getWallConditionContext() {
return wallConditionContextLocal.get();
}
public static WallTopStatementContext getWallTopStatementContext() {
return wallTopStatementContextLocal.get();
}
public static void clearWallTopStatementContext() {
wallTopStatementContextLocal.set(null);
}
public static void initWallTopStatementContext() {
wallTopStatementContextLocal.set(new WallTopStatementContext());
}
public static Object getConditionValue(WallVisitor visitor, SQLExpr x, boolean alwayTrueCheck) {
final WallConditionContext old = wallConditionContextLocal.get();
try {
wallConditionContextLocal.set(new WallConditionContext());
final Object value = getValue(visitor, x);
final WallConditionContext current = wallConditionContextLocal.get();
WallContext context = WallContext.current();
if (context != null) {
if (current.hasPartAlwayTrue() || Boolean.TRUE == value) {
if (!isFirst(x)) {
context.incrementWarnnings();
}
}
}
if (current.hasPartAlwayTrue() && alwayTrueCheck && !visitor.getConfig().isConditionAndAlwayTrueAllow()) {
addViolation(visitor, ErrorCode.ALWAY_TRUE, "part alway true condition not allow", x);
}
if (current.hasPartAlwayFalse() && !visitor.getConfig().isConditionAndAlwayFalseAllow()) {
addViolation(visitor, ErrorCode.ALWAY_FALSE, "part alway false condition not allow", x);
}
if (current.hasConstArithmetic() && !visitor.getConfig().isConstArithmeticAllow()) {
addViolation(visitor, ErrorCode.CONST_ARITHMETIC, "const arithmetic not allow", x);
}
if (current.hasXor() && !visitor.getConfig().isConditionOpXorAllow()) {
addViolation(visitor, ErrorCode.XOR, "xor not allow", x);
}
if (current.hasBitwise() && !visitor.getConfig().isConditionOpBitwseAllow()) {
addViolation(visitor, ErrorCode.BITWISE, "bitwise operator not allow", x);
}
return value;
} finally {
wallConditionContextLocal.set(old);
}
}
public static Object getValueFromAttributes(WallVisitor visitor, SQLObject sqlObject) {
if (sqlObject == null) {
return null;
}
if (visitor != null && visitor.getConfig().isConditionLikeTrueAllow()
&& sqlObject.getAttributes().containsKey(HAS_TRUE_LIKE)) {
return null;
}
return sqlObject.getAttribute(EVAL_VALUE);
}
public static Object getValue(SQLExpr x) {
return getValue(null, x);
}
public static Object getValue(WallVisitor visitor, SQLExpr x) {
if (x != null && x.getAttributes().containsKey(EVAL_VALUE)) {
return getValueFromAttributes(visitor, x);
}
if (x instanceof SQLBinaryOpExpr) {
return getValue(visitor, (SQLBinaryOpExpr) x);
}
if (x instanceof MySqlBooleanExpr) {
return ((MySqlBooleanExpr) x).getValue();
}
if (x instanceof SQLNumericLiteralExpr) {
return ((SQLNumericLiteralExpr) x).getNumber();
}
if (x instanceof SQLCharExpr) {
return ((SQLCharExpr) x).getText();
}
if (x instanceof SQLNCharExpr) {
return ((SQLNCharExpr) x).getText();
}
if (x instanceof SQLNotExpr) {
Object result = getValue(visitor, ((SQLNotExpr) x).getExpr());
if (result instanceof Boolean) {
return !((Boolean) result).booleanValue();
}
}
if (x instanceof SQLQueryExpr) {
if (isSimpleCountTableSource(visitor, ((SQLQueryExpr) x).getSubQuery())) {
return Integer.valueOf(1);
}
if (isSimpleCaseTableSource(visitor, ((SQLQueryExpr) x).getSubQuery())) {
SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) ((SQLQueryExpr) x).getSubQuery().getQuery();
SQLCaseExpr caseExpr = (SQLCaseExpr) queryBlock.getSelectList().get(0).getExpr();
Object result = getValue(caseExpr);
if (visitor != null && !visitor.getConfig().isCaseConditionConstAllow()) {
boolean leftIsName = false;
if (x.getParent() instanceof SQLBinaryOpExpr) {
SQLExpr left = ((SQLBinaryOpExpr) x.getParent()).getLeft();
if (left instanceof SQLName) {
leftIsName = true;
}
}
if (!leftIsName && result != null) {
addViolation(visitor, ErrorCode.CONST_CASE_CONDITION, "const case condition", caseExpr);
}
}
return result;
}
}
String dbType = null;
if (visitor != null) {
dbType = visitor.getDbType();
}
if (x instanceof SQLMethodInvokeExpr //
|| x instanceof SQLBetweenExpr //
|| x instanceof SQLInListExpr //
|| x instanceof SQLUnaryExpr //
) {
return eval(visitor, dbType, x, Collections.emptyList());
}
if (x instanceof SQLCaseExpr) {
if (visitor != null && !visitor.getConfig().isCaseConditionConstAllow()) {
SQLCaseExpr caseExpr = (SQLCaseExpr) x;
boolean leftIsName = false;
if (caseExpr.getParent() instanceof SQLBinaryOpExpr) {
SQLExpr left = ((SQLBinaryOpExpr) caseExpr.getParent()).getLeft();
if (left instanceof SQLName) {
leftIsName = true;
}
}
if (!leftIsName && caseExpr.getValueExpr() == null && caseExpr.getItems().size() > 0) {
SQLCaseExpr.Item item = caseExpr.getItems().get(0);
Object conditionVal = getValue(visitor, item.getConditionExpr());
Object itemVal = getValue(visitor, item.getValueExpr());
if (conditionVal instanceof Boolean && itemVal != null) {
addViolation(visitor, ErrorCode.CONST_CASE_CONDITION, "const case condition", caseExpr);
}
}
}
return eval(visitor, dbType, x, Collections.emptyList());
}
return null;
}
public static Object eval(WallVisitor wallVisitor, String dbType, SQLObject sqlObject, List<Object> parameters) {
SQLEvalVisitor visitor = SQLEvalVisitorUtils.createEvalVisitor(dbType);
visitor.setParameters(parameters);
visitor.registerFunction("rand", Nil.instance);
sqlObject.accept(visitor);
if (sqlObject instanceof SQLNumericLiteralExpr) {
return ((SQLNumericLiteralExpr) sqlObject).getNumber();
}
return getValueFromAttributes(wallVisitor, sqlObject);
}
public static boolean isSimpleCountTableSource(WallVisitor visitor, SQLTableSource tableSource) {
if (!(tableSource instanceof SQLSubqueryTableSource)) {
return false;
}
SQLSubqueryTableSource subQuery = (SQLSubqueryTableSource) tableSource;
return isSimpleCountTableSource(visitor, subQuery.getSelect());
}
public static boolean isSimpleCountTableSource(WallVisitor visitor, SQLSelect select) {
SQLSelectQuery query = select.getQuery();
if (query instanceof SQLSelectQueryBlock) {
SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) query;
boolean allawTrueWhere = false;
if (queryBlock.getWhere() == null) {
allawTrueWhere = true;
} else {
Object whereValue = getValue(visitor, queryBlock.getWhere());
if (whereValue == Boolean.TRUE) {
allawTrueWhere = true;
} else if (whereValue == Boolean.FALSE) {
return false;
}
}
boolean simpleCount = false;
if (queryBlock.getSelectList().size() == 1) {
SQLExpr selectItemExpr = queryBlock.getSelectList().get(0).getExpr();
if (selectItemExpr instanceof SQLAggregateExpr) {
if (((SQLAggregateExpr) selectItemExpr).getMethodName().equalsIgnoreCase("COUNT")) {
simpleCount = true;
}
}
}
if (allawTrueWhere && simpleCount) {
return true;
}
}
return false;
}
public static boolean isSimpleCaseTableSource(WallVisitor visitor, SQLSelect select) {
SQLSelectQuery query = select.getQuery();
if (query instanceof SQLSelectQueryBlock) {
SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) query;
boolean allawTrueWhere = false;
if (queryBlock.getWhere() == null) {
allawTrueWhere = true;
} else {
Object whereValue = getValue(visitor, queryBlock.getWhere());
if (whereValue == Boolean.TRUE) {
allawTrueWhere = true;
} else if (whereValue == Boolean.FALSE) {
return false;
}
}
boolean simpleCase = false;
if (queryBlock.getSelectList().size() == 1) {
SQLExpr selectItemExpr = queryBlock.getSelectList().get(0).getExpr();
if (selectItemExpr instanceof SQLCaseExpr) {
simpleCase = true;
}
}
if (allawTrueWhere && simpleCase) {
return true;
}
}
return false;
}
public static void checkFunctionInTableSource(WallVisitor visitor, SQLMethodInvokeExpr x) {
final WallTopStatementContext topStatementContext = wallTopStatementContextLocal.get();
if (topStatementContext != null && (topStatementContext.fromSysSchema || topStatementContext.fromSysTable)) {
return;
}
checkSchema(visitor, x.getOwner());
String methodName = x.getMethodName().toLowerCase();
if (!visitor.getProvider().checkDenyTable(methodName)) {
if (isTopStatementWithTableSource(x) || isFirstSelectTableSource(x)) {
if (topStatementContext != null) {
topStatementContext.setFromSysSchema(Boolean.TRUE);
clearViolation(visitor);
}
}
}
}
public static void checkFunction(WallVisitor visitor, SQLMethodInvokeExpr x) {
final WallTopStatementContext topStatementContext = wallTopStatementContextLocal.get();
if (topStatementContext != null && (topStatementContext.fromSysSchema || topStatementContext.fromSysTable)) {
return;
}
checkSchema(visitor, x.getOwner());
if (!visitor.getConfig().isFunctionCheck()) {
return;
}
String methodName = x.getMethodName().toLowerCase();
WallContext context = WallContext.current();
if (context != null) {
context.incrementFunctionInvoke(methodName);
}
if (!visitor.getProvider().checkDenyFunction(methodName)) {
boolean isTopNoneFrom = isTopNoneFromSelect(visitor, x);
if (isTopNoneFrom) {
return;
}
boolean isShow = x.getParent() instanceof MySqlShowGrantsStatement;
if (isShow) {
return;
}
if (isWhereOrHaving(x)) {
addViolation(visitor, ErrorCode.FUNCTION_DENY, "deny function : " + methodName, x);
}
}
}
public static SQLSelectQueryBlock getQueryBlock(SQLObject x) {
if (x == null) {
return null;
}
if (x instanceof SQLSelectQueryBlock) {
return (SQLSelectQueryBlock) x;
}
SQLObject parent = x.getParent();
if (parent instanceof SQLExpr) {
return getQueryBlock(parent);
}
if (parent instanceof SQLSelectItem) {
return getQueryBlock(parent);
}
if (parent instanceof SQLSelectQueryBlock) {
return (SQLSelectQueryBlock) parent;
}
return null;
}
public static boolean isTopNoneFromSelect(WallVisitor visitor, SQLObject x) {
for (;;) {
if ((x.getParent() instanceof SQLExpr) || (x.getParent() instanceof Item)) {
x = x.getParent();
} else {
break;
}
}
if (!(x.getParent() instanceof SQLSelectItem)) {
return false;
}
SQLSelectItem item = (SQLSelectItem) x.getParent();
if (!(item.getParent() instanceof SQLSelectQueryBlock)) {
return false;
}
SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) item.getParent();
if (!queryBlockFromIsNull(visitor, queryBlock)) {
return false;
}
if (!(queryBlock.getParent() instanceof SQLSelect)) {
return false;
}
SQLSelect select = (SQLSelect) queryBlock.getParent();
if (!(select.getParent() instanceof SQLSelectStatement)) {
return false;
}
SQLSelectStatement stmt = (SQLSelectStatement) select.getParent();
return stmt.getParent() == null;
}
private static boolean checkSchema(WallVisitor visitor, SQLExpr x) {
final WallTopStatementContext topStatementContext = wallTopStatementContextLocal.get();
if (topStatementContext != null && (topStatementContext.fromSysSchema || topStatementContext.fromSysTable)) {
return true;
}
if (x instanceof SQLName) {
String owner = ((SQLName) x).getSimleName();
owner = WallVisitorUtils.form(owner);
if (isInTableSource(x) && !visitor.getProvider().checkDenySchema(owner)) {
if (!isTopStatementWithTableSource(x) && !isFirstSelectTableSource(x) && !isFirstInSubQuery(x)) {
SQLObject parent = x.getParent();
while (parent != null && !(parent instanceof SQLStatement)) {
parent = parent.getParent();
}
boolean sameToTopSelectSchema = false;
if (parent instanceof SQLSelectStatement) {
SQLSelectStatement selectStmt = (SQLSelectStatement) parent;
SQLSelectQuery query = selectStmt.getSelect().getQuery();
if (query instanceof SQLSelectQueryBlock) {
SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) query;
SQLTableSource from = queryBlock.getFrom();
while (from instanceof SQLJoinTableSource) {
from = ((SQLJoinTableSource) from).getLeft();
}
if (from instanceof SQLExprTableSource) {
SQLExpr expr = ((SQLExprTableSource) from).getExpr();
if (expr instanceof SQLPropertyExpr) {
SQLExpr schemaExpr = ((SQLPropertyExpr) expr).getOwner();
if (schemaExpr instanceof SQLIdentifierExpr) {
String schema = ((SQLIdentifierExpr) schemaExpr).getName();
schema = form(schema);
if (schema.equalsIgnoreCase(owner)) {
sameToTopSelectSchema = true;
}
}
}
}
}
}
if (!sameToTopSelectSchema) {
addViolation(visitor, ErrorCode.SCHEMA_DENY, "deny schema : " + owner, x);
}
} else {
if (topStatementContext != null) {
topStatementContext.setFromSysSchema(Boolean.TRUE);
clearViolation(visitor);
}
}
return true;
}
if (visitor.getConfig().isDenyObjects(owner)) {
addViolation(visitor, ErrorCode.OBJECT_DENY, "deny object : " + owner, x);
return true;
}
}
// if (ownerExpr instanceof SQLPropertyExpr) {
if (x instanceof SQLPropertyExpr) {
return checkSchema(visitor, ((SQLPropertyExpr) x).getOwner());
}
return true;
}
private static boolean isInTableSource(SQLObject x) {
for (;;) {
if (x instanceof SQLExpr) {
x = x.getParent();
} else {
break;
}
}
if (x instanceof SQLExprTableSource) {
return true;
}
return false;
}
private static boolean isFirstInSubQuery(SQLObject x) {
for (;;) {
if (x instanceof SQLExpr) {
x = x.getParent();
} else {
break;
}
}
if (!(x instanceof SQLExprTableSource)) {
return false;
}
SQLSelect sqlSelect = null;
SQLObject parent = x.getParent();
while (parent != null) {
if (parent instanceof SQLSelect) {
sqlSelect = (SQLSelect) parent;
break;
}
x = parent;
parent = x.getParent();
}
if (sqlSelect == null) {
return false;
}
parent = sqlSelect.getParent();
if (!(parent instanceof SQLInSubQueryExpr && isFirst(parent))) {
return false;
}
SQLInSubQueryExpr sqlInSubQueryExpr = (SQLInSubQueryExpr) parent;
if (!(sqlInSubQueryExpr.getParent() instanceof SQLSelectQueryBlock)) {
return false;
}
SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) sqlInSubQueryExpr.getParent();
if (!(queryBlock.getParent() instanceof SQLSelect)) {
return false;
}
SQLSelect select = (SQLSelect) queryBlock.getParent();
if (!(select.getParent() instanceof SQLSelectStatement)) {
return false;
}
SQLSelectStatement stmt = (SQLSelectStatement) select.getParent();
return stmt.getParent() == null;
}
private static boolean isFirstSelectTableSource(SQLObject x) {
for (;;) {
if (x instanceof SQLExpr) {
x = x.getParent();
} else {
break;
}
}
if (!(x instanceof SQLExprTableSource)) {
return false;
}
SQLSelectQueryBlock queryBlock = null;
SQLObject parent = x.getParent();
while (parent != null) {
// if (parent instanceof SQLJoinTableSource) {
// SQLJoinTableSource join = (SQLJoinTableSource) parent;
// if (join.getRight() == x && hasTableSource(join.getLeft())) {
// return false;
// }
// }
if (parent instanceof SQLSelectQueryBlock) {
queryBlock = (SQLSelectQueryBlock) parent;
break;
}
x = parent;
parent = x.getParent();
}
if (queryBlock == null) {
return false;
}
boolean isWhereQueryExpr = false;
boolean isSelectItem = false;
do {
x = parent;
parent = parent.getParent();
if (parent instanceof SQLUnionQuery) {
SQLUnionQuery union = (SQLUnionQuery) parent;
if (union.getRight() == x && hasTableSource(union.getLeft())) {
return false;
}
} else if (parent instanceof SQLQueryExpr || parent instanceof SQLInSubQueryExpr
|| parent instanceof SQLExistsExpr) {
isWhereQueryExpr = isWhereOrHaving(parent);
} else if (parent instanceof SQLSelectItem) {
isSelectItem = true;
} else if ((isWhereQueryExpr || isSelectItem) && parent instanceof SQLSelectQueryBlock) {
if (hasTableSource((SQLSelectQueryBlock) parent)) {
return false;
}
}
} while (parent != null);
return true;
}
private static boolean hasTableSource(SQLSelectQuery x) {
if (x instanceof SQLUnionQuery) {
SQLUnionQuery union = (SQLUnionQuery) x;
return hasTableSource(union.getLeft()) || hasTableSource(union.getRight());
} else if (x instanceof SQLSelectQueryBlock) {
return hasTableSource(((SQLSelectQueryBlock) x).getFrom());
}
return false;
}
private static boolean hasTableSource(SQLTableSource x) {
if (x == null) {
return false;
}
if (x instanceof SQLExprTableSource) {
SQLExpr fromExpr = ((SQLExprTableSource) x).getExpr();
if (fromExpr instanceof SQLName) {
String name = fromExpr.toString();
name = form(name);
if (name.equalsIgnoreCase("DUAL")) {
return false;
}
}
return true;
} else if (x instanceof SQLJoinTableSource) {
SQLJoinTableSource join = (SQLJoinTableSource) x;
return hasTableSource(join.getLeft()) || hasTableSource(join.getRight());
} else if (x instanceof SQLSubqueryTableSource) {
return hasTableSource(((SQLSubqueryTableSource) x).getSelect().getQuery());
}
return false;
}
private static boolean isTopStatementWithTableSource(SQLObject x) {
for (;;) {
if (x instanceof SQLExpr) {
x = x.getParent();
} else {
break;
}
}
if (x instanceof SQLExprTableSource) {
x = x.getParent();
if (x instanceof SQLStatement) {
x = x.getParent();
if (x == null) {
return true;
}
}
}
return false;
}
private static boolean isTopSelectItem(SQLObject x) {
for (;;) {
if ((x.getParent() instanceof SQLExpr) || (x.getParent() instanceof Item)) {
x = x.getParent();
} else {
break;
}
}
if (!(x.getParent() instanceof SQLSelectItem)) {
return false;
}
SQLSelectItem item = (SQLSelectItem) x.getParent();
return isTopSelectStatement(item.getParent());
}
private static boolean isTopSelectStatement(SQLObject x) {
if (!(x instanceof SQLSelectQueryBlock)) {
return false;
}
SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) x;
if (!(queryBlock.getParent() instanceof SQLSelect)) {
return false;
}
SQLSelect select = (SQLSelect) queryBlock.getParent();
if (!(select.getParent() instanceof SQLSelectStatement)) {
return false;
}
SQLSelectStatement stmt = (SQLSelectStatement) select.getParent();
return stmt.getParent() == null;
}
public static boolean isTopSelectOutFile(MySqlOutFileExpr x) {
if (!(x.getParent() instanceof SQLExprTableSource)) {
return false;
}
SQLExprTableSource tableSource = (SQLExprTableSource) x.getParent();
return isTopSelectStatement(tableSource.getParent());
}
public static boolean check(WallVisitor visitor, SQLExprTableSource x) {
final WallTopStatementContext topStatementContext = wallTopStatementContextLocal.get();
SQLExpr expr = x.getExpr();
if (expr instanceof SQLPropertyExpr) {
boolean checkResult = checkSchema(visitor, ((SQLPropertyExpr) expr).getOwner());
if (!checkResult) {
return false;
}
}
if (expr instanceof SQLName) {
String tableName = ((SQLName) expr).getSimleName();
WallContext context = WallContext.current();
if (context != null) {
WallSqlTableStat tableStat = context.getTableStat(tableName);
if (tableStat != null) {
SQLObject parent = x.getParent();
while (parent instanceof SQLTableSource) {
parent = parent.getParent();
}
if (parent instanceof SQLSelectQueryBlock) {
SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) parent;
if (x == queryBlock.getInto()) {
tableStat.incrementSelectIntoCount();
} else {
tableStat.incrementSelectCount();
}
} else if (parent instanceof SQLTruncateStatement) {
tableStat.incrementTruncateCount();
} else if (parent instanceof SQLInsertStatement) {
tableStat.incrementInsertCount();
} else if (parent instanceof SQLDeleteStatement) {
tableStat.incrementDeleteCount();
} else if (parent instanceof SQLUpdateStatement) {
tableStat.incrementUpdateCount();
} else if (parent instanceof MySqlReplaceStatement) {
tableStat.incrementReplaceCount();
}
}
}
if (topStatementContext != null && (topStatementContext.fromSysSchema || topStatementContext.fromSysTable)) {
return true;
}
if (visitor.isDenyTable(tableName)
&& !(topStatementContext != null && topStatementContext.fromPermitTable())) {
if (isTopStatementWithTableSource(x) || isFirstSelectTableSource(x)) {
if (topStatementContext != null) {
topStatementContext.setFromSysTable(Boolean.TRUE);
clearViolation(visitor);
}
return false;
}
boolean isTopNoneFrom = isTopNoneFromSelect(visitor, x);
if (isTopNoneFrom) {
return false;
}
addViolation(visitor, ErrorCode.TABLE_DENY, "deny table : " + tableName, x);
return false;
}
if (visitor.getConfig().getPermitTables().contains(tableName)) {
if (isFirstSelectTableSource(x)) {
if (topStatementContext != null) {
topStatementContext.setFromPermitTable(Boolean.TRUE);
}
return false;
}
}
}
return true;
}
private static void addViolation(WallVisitor visitor, int errorCode, String message, SQLObject x) {
visitor.addViolation(new IllegalSQLObjectViolation(errorCode, message, visitor.toSQL(x)));
}
private static void clearViolation(WallVisitor visitor) {
visitor.getViolations().clear();
}
public static void checkUnion(WallVisitor visitor, SQLUnionQuery x) {
if (x.getOperator() == SQLUnionOperator.MINUS && !visitor.getConfig().isMinusAllow()) {
addViolation(visitor, ErrorCode.INTERSET_NOT_ALLOW, "minus not allow", x);
return;
}
if (x.getOperator() == SQLUnionOperator.INTERSECT && !visitor.getConfig().isIntersectAllow()) {
addViolation(visitor, ErrorCode.INTERSET_NOT_ALLOW, "intersect not allow", x);
return;
}
if (WallVisitorUtils.queryBlockFromIsNull(visitor, x.getRight())) {
boolean isTopUpdateStatement = false;
boolean isTopInsertStatement = false;
SQLObject selectParent = x.getParent();
while (selectParent instanceof SQLUnionQuery //
|| selectParent instanceof SQLJoinTableSource //
|| selectParent instanceof SQLSubqueryTableSource //
|| selectParent instanceof SQLSelect) {
selectParent = selectParent.getParent();
}
if (selectParent instanceof SQLUpdateStatement) {
isTopUpdateStatement = true;
}
if (selectParent instanceof SQLInsertStatement) {
isTopInsertStatement = true;
}
if (isTopUpdateStatement || isTopInsertStatement) {
return;
}
WallContext context = WallContext.current();
if (context != null) {
context.incrementUnionWarnnings();
}
if (((x.getOperator() == SQLUnionOperator.UNION || x.getOperator() == SQLUnionOperator.UNION_ALL || x.getOperator() == SQLUnionOperator.DISTINCT) && visitor.getConfig().isSelectUnionCheck())
|| (x.getOperator() == SQLUnionOperator.MINUS && visitor.getConfig().isSelectMinusCheck())
|| (x.getOperator() == SQLUnionOperator.INTERSECT && visitor.getConfig().isSelectIntersectCheck())
|| (x.getOperator() == SQLUnionOperator.EXCEPT && visitor.getConfig().isSelectExceptCheck())) {
addViolation(visitor, ErrorCode.UNION,
x.getOperator().toString() + " query not contains 'from clause'", x);
}
}
}
public static boolean queryBlockFromIsNull(WallVisitor visitor, SQLSelectQuery query) {
return queryBlockFromIsNull(visitor, query, true);
}
public static boolean queryBlockFromIsNull(WallVisitor visitor, SQLSelectQuery query, boolean checkSelectConst) {
if (query instanceof SQLSelectQueryBlock) {
SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) query;
SQLTableSource from = queryBlock.getFrom();
if (from == null) {
return true;
}
if (from instanceof SQLExprTableSource) {
SQLExpr fromExpr = ((SQLExprTableSource) from).getExpr();
if (fromExpr instanceof SQLName) {
String name = fromExpr.toString();
name = form(name);
if (name.equalsIgnoreCase("DUAL")) {
return true;
}
}
}
if (queryBlock.getSelectList().size() == 1
&& queryBlock.getSelectList().get(0).getExpr() instanceof SQLAllColumnExpr) {
if (from instanceof SQLSubqueryTableSource) {
SQLSelectQuery subQuery = ((SQLSubqueryTableSource) from).getSelect().getQuery();
if (queryBlockFromIsNull(visitor, subQuery)) {
return true;
}
}
}
if (checkSelectConst) {
SQLExpr where = queryBlock.getWhere();
if (where != null) {
Object whereValue = getValue(visitor, where);
if (Boolean.TRUE == whereValue) {
boolean allIsConst = true;
for (SQLSelectItem item : queryBlock.getSelectList()) {
if (getValue(visitor, item.getExpr()) == null) {
allIsConst = false;
break;
}
}
if (allIsConst) {
return true;
}
}
}
}
}
return false;
}
public static String form(String name) {
if (name.startsWith("\"") && name.endsWith("\"")) {
name = name.substring(1, name.length() - 1);
}
if (name.startsWith("'") && name.endsWith("'")) {
name = name.substring(1, name.length() - 1);
}
if (name.startsWith("`") && name.endsWith("`")) {
name = name.substring(1, name.length() - 1);
}
name = name.toLowerCase();
return name;
}
public static void loadResource(Set<String> names, String resource) {
try {
boolean hasResource = false;
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if (classLoader != null) {
Enumeration<URL> e = Thread.currentThread().getContextClassLoader().getResources(resource);
while (e.hasMoreElements()) {
URL url = e.nextElement();
InputStream in = null;
try {
in = url.openStream();
readFromInputStream(names, in);
hasResource = true;
} finally {
JdbcUtils.close(in);
}
}
}
// for aliyun odps
if (!hasResource) {
if (!resource.startsWith("/")) {
resource = "/" + resource;
}
InputStream in = null;
try {
in = WallVisitorUtils.class.getResourceAsStream(resource);
if (in != null) {
readFromInputStream(names, in);
}
} finally {
JdbcUtils.close(in);
}
}
} catch (IOException e) {
LOG.error("load oracle deny tables errror", e);
}
}
private static void readFromInputStream(Set<String> names, InputStream in) throws IOException {
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(in));
for (;;) {
String line = reader.readLine();
if (line == null) {
break;
}
line = line.trim();
if (line.length() > 0) {
line = line.toLowerCase();
names.add(line);
}
}
} finally {
JdbcUtils.close(reader);
}
}
public static void preVisitCheck(WallVisitor visitor, SQLObject x) {
WallConfig config = visitor.getProvider().getConfig();
if (!(x instanceof SQLStatement)) {
return;
}
boolean allow = false;
int errorCode;
String denyMessage;
if (x instanceof SQLInsertStatement) {
allow = config.isInsertAllow();
denyMessage = "insert not allow";
errorCode = ErrorCode.INSERT_NOT_ALLOW;
} else if (x instanceof SQLSelectStatement) {
allow = true;
denyMessage = "select not allow";
errorCode = ErrorCode.SELECT_NOT_ALLOW;
} else if (x instanceof SQLDeleteStatement) {
allow = config.isDeleteAllow();
denyMessage = "delete not allow";
errorCode = ErrorCode.DELETE_NOT_ALLOW;
} else if (x instanceof SQLUpdateStatement) {
allow = config.isUpdateAllow();
denyMessage = "update not allow";
errorCode = ErrorCode.UPDATE_NOT_ALLOW;
} else if (x instanceof OracleMultiInsertStatement) {
allow = true;
denyMessage = "multi-insert not allow";
errorCode = ErrorCode.INSERT_NOT_ALLOW;
} else if (x instanceof OracleMergeStatement) {
allow = config.isMergeAllow();
denyMessage = "merge not allow";
errorCode = ErrorCode.MERGE_NOT_ALLOW;
} else if (x instanceof SQLCallStatement || x instanceof SQLServerExecStatement) {
allow = config.isCallAllow();
denyMessage = "call not allow";
errorCode = ErrorCode.CALL_NOT_ALLOW;
} else if (x instanceof SQLTruncateStatement) {
allow = config.isTruncateAllow();
denyMessage = "truncate not allow";
errorCode = ErrorCode.TRUNCATE_NOT_ALLOW;
} else if (x instanceof SQLCreateTableStatement //
|| x instanceof SQLCreateIndexStatement //
|| x instanceof SQLCreateViewStatement //
|| x instanceof SQLCreateTriggerStatement //
|| x instanceof OracleCreateSequenceStatement //
) {
allow = config.isCreateTableAllow();
denyMessage = "create table not allow";
errorCode = ErrorCode.CREATE_TABLE_NOT_ALLOW;
} else if (x instanceof SQLAlterTableStatement) {
allow = config.isAlterTableAllow();
denyMessage = "alter table not allow";
errorCode = ErrorCode.ALTER_TABLE_NOT_ALLOW;
} else if (x instanceof SQLDropTableStatement //
|| x instanceof SQLDropIndexStatement //
|| x instanceof SQLDropViewStatement //
|| x instanceof SQLDropTriggerStatement //
|| x instanceof SQLDropSequenceStatement //
) {
allow = config.isDropTableAllow();
denyMessage = "drop table not allow";
errorCode = ErrorCode.DROP_TABLE_NOT_ALLOW;
} else if (x instanceof MySqlSetCharSetStatement //
|| x instanceof MySqlSetNamesStatement //
|| x instanceof SQLSetStatement) {
allow = config.isSetAllow();
denyMessage = "set not allow";
errorCode = ErrorCode.SET_NOT_ALLOW;
} else if (x instanceof MySqlReplaceStatement) {
allow = config.isReplaceAllow();
denyMessage = "replace not allow";
errorCode = ErrorCode.REPLACE_NOT_ALLOW;
} else if (x instanceof MySqlDescribeStatement) {
allow = config.isDescribeAllow();
denyMessage = "describe not allow";
errorCode = ErrorCode.DESC_NOT_ALLOW;
} else if (x instanceof MySqlShowStatement) {
allow = config.isShowAllow();
denyMessage = "show not allow";
errorCode = ErrorCode.SHOW_NOT_ALLOW;
} else if (x instanceof MySqlCommitStatement) {
allow = config.isCommitAllow();
denyMessage = "show not allow";
errorCode = ErrorCode.COMMIT_NOT_ALLOW;
} else if (x instanceof SQLRollbackStatement) {
allow = config.isRollbackAllow();
denyMessage = "show not allow";
errorCode = ErrorCode.ROLLBACK_NOT_ALLOW;
} else if (x instanceof SQLUseStatement) {
allow = config.isUseAllow();
denyMessage = "show not allow";
errorCode = ErrorCode.USE_NOT_ALLOW;
} else {
allow = config.isNoneBaseStatementAllow();
errorCode = ErrorCode.NONE_BASE_STATEMENT_NOT_ALLOW;
denyMessage = x.getClass() + " not allow";
}
if (!allow) {
addViolation(visitor, errorCode, denyMessage, x);
}
}
}