mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
add sql wall support
This commit is contained in:
@@ -19,5 +19,9 @@ public class IllegalConditionViolation implements Violation {
|
||||
public void setCondition(String condition) {
|
||||
this.condition = condition;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.condition;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,22 +2,26 @@ package com.alibaba.druid.filter.wall;
|
||||
|
||||
public class IllegalSQLObjectViolation implements Violation {
|
||||
|
||||
private String condition;
|
||||
private String sqlPart;
|
||||
|
||||
public IllegalSQLObjectViolation(){
|
||||
|
||||
}
|
||||
|
||||
public IllegalSQLObjectViolation(String condition){
|
||||
this.condition = condition;
|
||||
this.sqlPart = condition;
|
||||
}
|
||||
|
||||
public String getCondition() {
|
||||
return condition;
|
||||
public String getSqlPart() {
|
||||
return sqlPart;
|
||||
}
|
||||
|
||||
public void setCondition(String condition) {
|
||||
this.condition = condition;
|
||||
public void setSqlPart(String sqlPart) {
|
||||
this.sqlPart = sqlPart;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.sqlPart;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.alibaba.druid.filter.wall;
|
||||
|
||||
|
||||
public interface Violation {
|
||||
|
||||
String toString();
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ public abstract class WallProvider {
|
||||
|
||||
if (visitor.getViolations().size() > 0) {
|
||||
if (throwException) {
|
||||
visitor.getViolations().get(0);
|
||||
throw new WallRuntimeException();
|
||||
} else {
|
||||
return false;
|
||||
|
||||
@@ -17,7 +17,10 @@ import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectQuery;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUnionQuery;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOutFileExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlExecuteStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowColumnsStatement;
|
||||
@@ -27,8 +30,9 @@ import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitorAdapter;
|
||||
|
||||
public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisitor {
|
||||
|
||||
private Set<String> permitFunctions = new HashSet<String>();
|
||||
private Set<String> permitSchemas = new HashSet<String>();
|
||||
private Set<String> permitFunctions = new HashSet<String>();
|
||||
private Set<String> permitTablesoures = new HashSet<String>();
|
||||
private Set<String> permitSchemas = new HashSet<String>();
|
||||
|
||||
private final List<Violation> violations;
|
||||
|
||||
@@ -39,9 +43,21 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi
|
||||
public MySqlWallVisitor(List<Violation> violations){
|
||||
this.violations = violations;
|
||||
|
||||
permitFunctions.add("load_file");
|
||||
permitFunctions.add("version");
|
||||
permitFunctions.add("load_file");
|
||||
permitFunctions.add("databse");
|
||||
permitFunctions.add("schema");
|
||||
permitFunctions.add("user");
|
||||
permitFunctions.add("system_user");
|
||||
permitFunctions.add("session_user");
|
||||
permitFunctions.add("benchmark");
|
||||
permitFunctions.add("connection_id");
|
||||
permitFunctions.add("current_user");
|
||||
|
||||
permitSchemas.add("information_schema");
|
||||
permitSchemas.add("information_schema");
|
||||
permitSchemas.add("mysql");
|
||||
|
||||
permitTablesoures.add("outfile");
|
||||
}
|
||||
|
||||
public List<Violation> getViolations() {
|
||||
@@ -137,4 +153,27 @@ permitSchemas.add("information_schema");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MySqlOutFileExpr x) {
|
||||
violations.add(new IllegalSQLObjectViolation(SQLUtils.toMySqlString(x)));
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLUnionQuery x) {
|
||||
if (queryBlockFromIsNull(x.getLeft()) || queryBlockFromIsNull(x.getRight())) {
|
||||
violations.add(new IllegalSQLObjectViolation(SQLUtils.toMySqlString(x)));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean queryBlockFromIsNull(SQLSelectQuery query) {
|
||||
if (query instanceof SQLSelectQueryBlock) {
|
||||
return ((SQLSelectQueryBlock) query).getFrom() == null;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
package com.alibaba.druid.sql.dialect.mysql.ast.expr;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlObjectImpl;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
|
||||
|
||||
public class MySqlOutFileExpr extends MySqlObjectImpl implements SQLExpr {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private SQLExpr file;
|
||||
private String charset;
|
||||
|
||||
private SQLLiteralExpr columnsTerminatedBy;
|
||||
private boolean columnsEnclosedOptionally = false;
|
||||
private SQLLiteralExpr columnsEnclosedBy;
|
||||
private SQLLiteralExpr columnsEscaped;
|
||||
|
||||
private SQLLiteralExpr linesStartingBy;
|
||||
private SQLLiteralExpr linesTerminatedBy;
|
||||
|
||||
private SQLExpr ignoreLinesNumber;
|
||||
|
||||
public MySqlOutFileExpr(){
|
||||
}
|
||||
|
||||
public MySqlOutFileExpr(SQLExpr file){
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept0(MySqlASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, file);
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
|
||||
public SQLExpr getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public void setFile(SQLExpr file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
public String getCharset() {
|
||||
return charset;
|
||||
}
|
||||
|
||||
public void setCharset(String charset) {
|
||||
this.charset = charset;
|
||||
}
|
||||
|
||||
public SQLLiteralExpr getColumnsTerminatedBy() {
|
||||
return columnsTerminatedBy;
|
||||
}
|
||||
|
||||
public void setColumnsTerminatedBy(SQLLiteralExpr columnsTerminatedBy) {
|
||||
this.columnsTerminatedBy = columnsTerminatedBy;
|
||||
}
|
||||
|
||||
public boolean isColumnsEnclosedOptionally() {
|
||||
return columnsEnclosedOptionally;
|
||||
}
|
||||
|
||||
public void setColumnsEnclosedOptionally(boolean columnsEnclosedOptionally) {
|
||||
this.columnsEnclosedOptionally = columnsEnclosedOptionally;
|
||||
}
|
||||
|
||||
public SQLLiteralExpr getColumnsEnclosedBy() {
|
||||
return columnsEnclosedBy;
|
||||
}
|
||||
|
||||
public void setColumnsEnclosedBy(SQLLiteralExpr columnsEnclosedBy) {
|
||||
this.columnsEnclosedBy = columnsEnclosedBy;
|
||||
}
|
||||
|
||||
public SQLLiteralExpr getColumnsEscaped() {
|
||||
return columnsEscaped;
|
||||
}
|
||||
|
||||
public void setColumnsEscaped(SQLLiteralExpr columnsEscaped) {
|
||||
this.columnsEscaped = columnsEscaped;
|
||||
}
|
||||
|
||||
public SQLLiteralExpr getLinesStartingBy() {
|
||||
return linesStartingBy;
|
||||
}
|
||||
|
||||
public void setLinesStartingBy(SQLLiteralExpr linesStartingBy) {
|
||||
this.linesStartingBy = linesStartingBy;
|
||||
}
|
||||
|
||||
public SQLLiteralExpr getLinesTerminatedBy() {
|
||||
return linesTerminatedBy;
|
||||
}
|
||||
|
||||
public void setLinesTerminatedBy(SQLLiteralExpr linesTerminatedBy) {
|
||||
this.linesTerminatedBy = linesTerminatedBy;
|
||||
}
|
||||
|
||||
public SQLExpr getIgnoreLinesNumber() {
|
||||
return ignoreLinesNumber;
|
||||
}
|
||||
|
||||
public void setIgnoreLinesNumber(SQLExpr ignoreLinesNumber) {
|
||||
this.ignoreLinesNumber = ignoreLinesNumber;
|
||||
}
|
||||
|
||||
}
|
||||
+19
-100
@@ -22,7 +22,6 @@ import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.SQLObjectImpl;
|
||||
import com.alibaba.druid.sql.ast.SQLOrderBy;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
@@ -30,55 +29,37 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
@SuppressWarnings("serial")
|
||||
public class MySqlSelectQueryBlock extends SQLSelectQueryBlock {
|
||||
|
||||
private boolean hignPriority;
|
||||
private boolean straightJoin;
|
||||
private boolean hignPriority;
|
||||
private boolean straightJoin;
|
||||
|
||||
private boolean smallResult;
|
||||
private boolean bigResult;
|
||||
private boolean bufferResult;
|
||||
private Boolean cache;
|
||||
private boolean calcFoundRows;
|
||||
private boolean smallResult;
|
||||
private boolean bigResult;
|
||||
private boolean bufferResult;
|
||||
private Boolean cache;
|
||||
private boolean calcFoundRows;
|
||||
|
||||
private SQLOrderBy orderBy;
|
||||
private SQLOrderBy orderBy;
|
||||
|
||||
private Limit limit;
|
||||
private Limit limit;
|
||||
|
||||
private SQLName procedureName;
|
||||
private List<SQLExpr> procedureArgumentList = new ArrayList<SQLExpr>();
|
||||
private SQLExpr outFile;
|
||||
private String outFileCharset;
|
||||
private SQLName procedureName;
|
||||
private List<SQLExpr> procedureArgumentList = new ArrayList<SQLExpr>();
|
||||
|
||||
private SQLLiteralExpr outFileColumnsTerminatedBy;
|
||||
private boolean outFileColumnsEnclosedOptionally = false;
|
||||
private SQLLiteralExpr outFileColumnsEnclosedBy;
|
||||
private SQLLiteralExpr outFileColumnsEscaped;
|
||||
private SQLExpr into;
|
||||
|
||||
private SQLLiteralExpr outFileLinesStartingBy;
|
||||
private SQLLiteralExpr outFileLinesTerminatedBy;
|
||||
|
||||
private SQLExpr outFileIgnoreLinesNumber;
|
||||
|
||||
private boolean forUpdate = false;
|
||||
private boolean lockInShareMode = false;
|
||||
private boolean forUpdate = false;
|
||||
private boolean lockInShareMode = false;
|
||||
|
||||
public MySqlSelectQueryBlock(){
|
||||
|
||||
}
|
||||
|
||||
public SQLExpr getOutFile() {
|
||||
return outFile;
|
||||
public SQLExpr getInto() {
|
||||
return into;
|
||||
}
|
||||
|
||||
public void setOutFile(SQLExpr outFile) {
|
||||
this.outFile = outFile;
|
||||
}
|
||||
|
||||
public String getOutFileCharset() {
|
||||
return outFileCharset;
|
||||
}
|
||||
|
||||
public void setOutFileCharset(String charset) {
|
||||
this.outFileCharset = charset;
|
||||
public void setInto(SQLExpr into) {
|
||||
this.into = into;
|
||||
}
|
||||
|
||||
public boolean isForUpdate() {
|
||||
@@ -185,62 +166,6 @@ public class MySqlSelectQueryBlock extends SQLSelectQueryBlock {
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
public SQLLiteralExpr getOutFileColumnsTerminatedBy() {
|
||||
return outFileColumnsTerminatedBy;
|
||||
}
|
||||
|
||||
public void setOutFileColumnsTerminatedBy(SQLLiteralExpr outFileColumnsTerminatedBy) {
|
||||
this.outFileColumnsTerminatedBy = outFileColumnsTerminatedBy;
|
||||
}
|
||||
|
||||
public boolean isOutFileColumnsEnclosedOptionally() {
|
||||
return outFileColumnsEnclosedOptionally;
|
||||
}
|
||||
|
||||
public void setOutFileColumnsEnclosedOptionally(boolean outFileColumnsEnclosedOptionally) {
|
||||
this.outFileColumnsEnclosedOptionally = outFileColumnsEnclosedOptionally;
|
||||
}
|
||||
|
||||
public SQLLiteralExpr getOutFileColumnsEnclosedBy() {
|
||||
return outFileColumnsEnclosedBy;
|
||||
}
|
||||
|
||||
public void setOutFileColumnsEnclosedBy(SQLLiteralExpr outFileColumnsEnclosedBy) {
|
||||
this.outFileColumnsEnclosedBy = outFileColumnsEnclosedBy;
|
||||
}
|
||||
|
||||
public SQLLiteralExpr getOutFileColumnsEscaped() {
|
||||
return outFileColumnsEscaped;
|
||||
}
|
||||
|
||||
public void setOutFileColumnsEscaped(SQLLiteralExpr outFileColumnsEscaped) {
|
||||
this.outFileColumnsEscaped = outFileColumnsEscaped;
|
||||
}
|
||||
|
||||
public SQLLiteralExpr getOutFileLinesStartingBy() {
|
||||
return outFileLinesStartingBy;
|
||||
}
|
||||
|
||||
public void setOutFileLinesStartingBy(SQLLiteralExpr outFileLinesStartingBy) {
|
||||
this.outFileLinesStartingBy = outFileLinesStartingBy;
|
||||
}
|
||||
|
||||
public SQLLiteralExpr getOutFileLinesTerminatedBy() {
|
||||
return outFileLinesTerminatedBy;
|
||||
}
|
||||
|
||||
public void setOutFileLinesTerminatedBy(SQLLiteralExpr outFileLinesTerminatedBy) {
|
||||
this.outFileLinesTerminatedBy = outFileLinesTerminatedBy;
|
||||
}
|
||||
|
||||
public SQLExpr getOutFileIgnoreLinesNumber() {
|
||||
return outFileIgnoreLinesNumber;
|
||||
}
|
||||
|
||||
public void setOutFileIgnoreLinesNumber(SQLExpr outFileIgnoreLinesNumber) {
|
||||
this.outFileIgnoreLinesNumber = outFileIgnoreLinesNumber;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void accept0(SQLASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
@@ -252,13 +177,7 @@ public class MySqlSelectQueryBlock extends SQLSelectQueryBlock {
|
||||
acceptChild(visitor, this.limit);
|
||||
acceptChild(visitor, this.procedureName);
|
||||
acceptChild(visitor, this.procedureArgumentList);
|
||||
acceptChild(visitor, this.outFile);
|
||||
acceptChild(visitor, this.outFileColumnsTerminatedBy);
|
||||
acceptChild(visitor, this.outFileColumnsEnclosedBy);
|
||||
acceptChild(visitor, this.outFileColumnsEscaped);
|
||||
acceptChild(visitor, this.outFileLinesStartingBy);
|
||||
acceptChild(visitor, this.outFileLinesTerminatedBy);
|
||||
acceptChild(visitor, this.outFileIgnoreLinesNumber);
|
||||
acceptChild(visitor, this.into);
|
||||
}
|
||||
|
||||
visitor.endVisit(this);
|
||||
|
||||
@@ -33,6 +33,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlIntervalExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlIntervalUnit;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlMatchAgainstExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlMatchAgainstExpr.SearchModifier;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOutFileExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSQLColumnDefinition;
|
||||
import com.alibaba.druid.sql.parser.Lexer;
|
||||
import com.alibaba.druid.sql.parser.ParserException;
|
||||
@@ -110,6 +111,15 @@ public class MySqlExprParser extends SQLExprParser {
|
||||
|
||||
public SQLExpr primary() throws ParserException {
|
||||
final Token tok = lexer.token();
|
||||
|
||||
if (identifierEquals("outfile")) {
|
||||
lexer.nextToken();
|
||||
SQLExpr file = primary();
|
||||
SQLExpr expr = new MySqlOutFileExpr(file);
|
||||
|
||||
return primaryRest(expr);
|
||||
|
||||
}
|
||||
|
||||
switch (tok) {
|
||||
case TRUE:
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr;
|
||||
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.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.parser.Lexer;
|
||||
@@ -111,8 +112,11 @@ public class MySqlSelectParser extends SQLSelectParser {
|
||||
if (lexer.token() == (Token.INTO)) {
|
||||
lexer.nextToken();
|
||||
acceptIdentifier("OUTFILE");
|
||||
SQLExpr outFile = expr();
|
||||
queryBlock.setOutFile(outFile);
|
||||
|
||||
MySqlOutFileExpr outFile = new MySqlOutFileExpr();
|
||||
outFile.setFile(expr());
|
||||
|
||||
queryBlock.setInto(outFile);
|
||||
|
||||
if (identifierEquals("FIELDS") || identifierEquals("COLUMNS")) {
|
||||
lexer.nextToken();
|
||||
@@ -121,23 +125,23 @@ public class MySqlSelectParser extends SQLSelectParser {
|
||||
lexer.nextToken();
|
||||
accept(Token.BY);
|
||||
}
|
||||
queryBlock.setOutFileColumnsTerminatedBy((SQLLiteralExpr) expr());
|
||||
outFile.setColumnsTerminatedBy((SQLLiteralExpr) expr());
|
||||
|
||||
if (identifierEquals("OPTIONALLY")) {
|
||||
lexer.nextToken();
|
||||
queryBlock.setOutFileColumnsEnclosedOptionally(true);
|
||||
outFile.setColumnsEnclosedOptionally(true);
|
||||
}
|
||||
|
||||
if (identifierEquals("ENCLOSED")) {
|
||||
lexer.nextToken();
|
||||
accept(Token.BY);
|
||||
queryBlock.setOutFileColumnsEnclosedBy((SQLLiteralExpr) expr());
|
||||
outFile.setColumnsEnclosedBy((SQLLiteralExpr) expr());
|
||||
}
|
||||
|
||||
if (identifierEquals("ESCAPED")) {
|
||||
lexer.nextToken();
|
||||
accept(Token.BY);
|
||||
queryBlock.setOutFileColumnsEscaped((SQLLiteralExpr) expr());
|
||||
outFile.setColumnsEscaped((SQLLiteralExpr) expr());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,12 +151,12 @@ public class MySqlSelectParser extends SQLSelectParser {
|
||||
if (identifierEquals("STARTING")) {
|
||||
lexer.nextToken();
|
||||
accept(Token.BY);
|
||||
queryBlock.setOutFileLinesStartingBy((SQLLiteralExpr) expr());
|
||||
outFile.setLinesStartingBy((SQLLiteralExpr) expr());
|
||||
} else {
|
||||
identifierEquals("TERMINATED");
|
||||
lexer.nextToken();
|
||||
accept(Token.BY);
|
||||
queryBlock.setOutFileLinesTerminatedBy((SQLLiteralExpr) expr());
|
||||
outFile.setLinesTerminatedBy((SQLLiteralExpr) expr());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.MySqlKey;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlPrimaryKey;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlBinaryExpr;
|
||||
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.expr.MySqlExtractExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlIntervalExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlMatchAgainstExpr;
|
||||
@@ -191,4 +192,8 @@ public interface MySqlASTVisitor extends SQLASTVisitor {
|
||||
boolean visit(MySqlSelectQueryBlock x);
|
||||
|
||||
void endVisit(MySqlSelectQueryBlock x);
|
||||
|
||||
boolean visit(MySqlOutFileExpr x);
|
||||
|
||||
void endVisit(MySqlOutFileExpr x);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlBooleanExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlExtractExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlIntervalExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlMatchAgainstExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOutFileExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.CobarShowStatus;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlBinlogStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCommitStatement;
|
||||
@@ -411,4 +412,14 @@ public class MySqlASTVisitorAdapter extends SQLASTVisitorAdapter implements
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MySqlOutFileExpr x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(MySqlOutFileExpr x) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -36,11 +36,13 @@ import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlCharExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlExtractExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlIntervalExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlMatchAgainstExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOutFileExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.CobarShowStatus;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlBinlogStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCommitStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateUserStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateUserStatement.UserSpecification;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDeleteStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDropTableStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDropUser;
|
||||
@@ -57,7 +59,6 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlRollbackStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSQLColumnDefinition;
|
||||
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.MySqlCreateUserStatement.UserSpecification;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock.Limit;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowColumnsStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowDatabasesStatement;
|
||||
@@ -135,49 +136,10 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
|
||||
printSelectList(x.getSelectList());
|
||||
|
||||
if (x.getOutFile() != null) {
|
||||
if (x.getInto() != null) {
|
||||
println();
|
||||
print("INTO OUTFILE ");
|
||||
x.getOutFile().accept(this);
|
||||
if (x.getOutFileCharset() != null) {
|
||||
print(" CHARACTER SET ");
|
||||
print(x.getOutFileCharset());
|
||||
}
|
||||
|
||||
if (x.getOutFileColumnsTerminatedBy() != null || x.getOutFileColumnsEnclosedBy() != null
|
||||
|| x.getOutFileColumnsEscaped() != null) {
|
||||
print(" COLUMNS");
|
||||
if (x.getOutFileColumnsTerminatedBy() != null) {
|
||||
print(" TERMINATED BY ");
|
||||
x.getOutFileColumnsTerminatedBy().accept(this);
|
||||
}
|
||||
|
||||
if (x.getOutFileColumnsEnclosedBy() != null) {
|
||||
if (x.isOutFileColumnsEnclosedOptionally()) {
|
||||
print(" OPTIONALLY");
|
||||
}
|
||||
print(" ENCLOSED BY ");
|
||||
x.getOutFileColumnsEnclosedBy().accept(this);
|
||||
}
|
||||
|
||||
if (x.getOutFileColumnsEscaped() != null) {
|
||||
print(" ESCAPED BY ");
|
||||
x.getOutFileColumnsEscaped().accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
if (x.getOutFileLinesStartingBy() != null || x.getOutFileLinesTerminatedBy() != null) {
|
||||
print(" LINES");
|
||||
if (x.getOutFileLinesStartingBy() != null) {
|
||||
print(" STARTING BY ");
|
||||
x.getOutFileLinesStartingBy().accept(this);
|
||||
}
|
||||
|
||||
if (x.getOutFileLinesTerminatedBy() != null) {
|
||||
print(" TERMINATED BY ");
|
||||
x.getOutFileLinesTerminatedBy().accept(this);
|
||||
}
|
||||
}
|
||||
print("INTO ");
|
||||
x.getInto().accept(this);
|
||||
}
|
||||
|
||||
if (x.getFrom() != null) {
|
||||
@@ -1348,4 +1310,57 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
public void endVisit(MySqlSelectQueryBlock x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MySqlOutFileExpr x) {
|
||||
print("OUTFILE ");
|
||||
x.getFile().accept(this);
|
||||
|
||||
if (x.getCharset() != null) {
|
||||
print(" CHARACTER SET ");
|
||||
print(x.getCharset());
|
||||
}
|
||||
|
||||
if (x.getColumnsTerminatedBy() != null || x.getColumnsEnclosedBy() != null
|
||||
|| x.getColumnsEscaped() != null) {
|
||||
print(" COLUMNS");
|
||||
if (x.getColumnsTerminatedBy() != null) {
|
||||
print(" TERMINATED BY ");
|
||||
x.getColumnsTerminatedBy().accept(this);
|
||||
}
|
||||
|
||||
if (x.getColumnsEnclosedBy() != null) {
|
||||
if (x.isColumnsEnclosedOptionally()) {
|
||||
print(" OPTIONALLY");
|
||||
}
|
||||
print(" ENCLOSED BY ");
|
||||
x.getColumnsEnclosedBy().accept(this);
|
||||
}
|
||||
|
||||
if (x.getColumnsEscaped() != null) {
|
||||
print(" ESCAPED BY ");
|
||||
x.getColumnsEscaped().accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
if (x.getLinesStartingBy() != null || x.getLinesTerminatedBy() != null) {
|
||||
print(" LINES");
|
||||
if (x.getLinesStartingBy() != null) {
|
||||
print(" STARTING BY ");
|
||||
x.getLinesStartingBy().accept(this);
|
||||
}
|
||||
|
||||
if (x.getLinesTerminatedBy() != null) {
|
||||
print(" TERMINATED BY ");
|
||||
x.getLinesTerminatedBy().accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(MySqlOutFileExpr x) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlBooleanExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlExtractExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlIntervalExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlMatchAgainstExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOutFileExpr;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.CobarShowStatus;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlBinlogStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCommitStatement;
|
||||
@@ -474,4 +475,14 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS
|
||||
public void endVisit(MySqlSelectQueryBlock x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MySqlOutFileExpr x) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(MySqlOutFileExpr x) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,10 +287,6 @@ public class SQLSelectParser extends SQLParser {
|
||||
return parseTableSourceRest(join);
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.UNION) {
|
||||
throw new SQLParseException("TODO");
|
||||
}
|
||||
|
||||
return tableSource;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,8 +14,19 @@ public class MySqlWallTest extends TestCase {
|
||||
|
||||
Assert.assertFalse(WallUtils.isValidateMySql("select hex(load_file(0x633A2F77696E646F77732F7265706169722F73616D))"));
|
||||
Assert.assertTrue(WallUtils.isValidateMySql("select 'hex(load_file(0x633A2F77696E646F77732F7265706169722F73616D))'"));
|
||||
|
||||
Assert.assertFalse(WallUtils.isValidateMySql("select 15,version()"));
|
||||
Assert.assertTrue(WallUtils.isValidateMySql("select 15,'version'"));
|
||||
|
||||
Assert.assertFalse(WallUtils.isValidateMySql("select 1 from information_schema.columns"));
|
||||
Assert.assertTrue(WallUtils.isValidateMySql("select 'information_schema.columns'"));
|
||||
|
||||
Assert.assertFalse(WallUtils.isValidateMySql("select 1 from mysql.user"));
|
||||
Assert.assertTrue(WallUtils.isValidateMySql("select 'mysql.user'"));
|
||||
|
||||
Assert.assertFalse(WallUtils.isValidateMySql("select 0x3C3F706870206576616C28245F504F53545B2763275D293F3E into outfile '\\www\\edu\\1.php'"));
|
||||
Assert.assertTrue(WallUtils.isValidateMySql("select 'outfile'"));
|
||||
|
||||
Assert.assertFalse(WallUtils.isValidateMySql("select f1, f2 from t union select 1, 2"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user