mysql parser support BINLOG statement

This commit is contained in:
温少
2012-02-20 14:48:17 +08:00
parent 915b4d0553
commit 0ca1ded998
13 changed files with 392 additions and 4 deletions
@@ -0,0 +1,95 @@
package com.alibaba.druid.sql.dialect.hive.parser;
import com.alibaba.druid.sql.parser.Lexer;
import com.alibaba.druid.sql.parser.Token;
public class HiveLexer extends Lexer {
public HiveLexer(char[] input, int inputLength, boolean skipComment) {
super(input, inputLength, skipComment);
}
public void scanComment() {
if (ch != '/') {
throw new IllegalStateException();
}
np = bp;
sp = 0;
scanChar();
sp++;
// /*+ */
if (ch == '*') {
scanChar();
sp++;
while (ch == ' ') {
scanChar();
sp++;
}
boolean isHint = false;
int startHintSp = sp + 1;
if (ch == '+') {
isHint = true;
scanChar();
sp++;
}
for (;;) {
if (ch == '*' && buf[bp + 1] == '/') {
sp += 2;
scanChar();
scanChar();
break;
}
scanChar();
sp++;
}
if (isHint) {
stringVal = new String(buf, np + startHintSp, (sp - startHintSp) - 2).trim();
token = Token.HINT;
} else {
stringVal = new String(buf, np, sp);
token = Token.MULTI_LINE_COMMENT;
}
return;
}
if (ch == '/') {
scanChar();
sp++;
for (;;) {
if (ch == '\r') {
if (buf[bp + 1] == '\n') {
sp += 2;
scanChar();
break;
}
sp++;
break;
}
if (ch == '\r') {
scanChar();
sp++;
break;
}
scanChar();
sp++;
}
stringVal = new String(buf, np + 1, sp);
token = Token.LINE_COMMENT;
return;
}
}
}
@@ -0,0 +1,24 @@
package com.alibaba.druid.sql.dialect.mysql.ast.statement;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
public class MySqlBinlogStatement extends MySqlStatementImpl {
private static final long serialVersionUID = 1L;
private SQLExpr expr;
public SQLExpr getExpr() {
return expr;
}
public void setExpr(SQLExpr expr) {
this.expr = expr;
}
protected void accept0(MySqlASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, expr);
}
}
}
@@ -0,0 +1,36 @@
package com.alibaba.druid.sql.dialect.mysql.ast.statement;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
public class MySqlKillStatement extends MySqlStatementImpl {
private static final long serialVersionUID = 1L;
private Type type;
private SQLExpr threadId;
public static enum Type {
CONNECTION, QUERY
}
public Type getType() {
return type;
}
public void setType(Type type) {
this.type = type;
}
public SQLExpr getThreadId() {
return threadId;
}
public void setThreadId(SQLExpr threadId) {
this.threadId = threadId;
}
protected void accept0(MySqlASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, threadId);
}
}
}
@@ -107,6 +107,7 @@ public class MySqlLexer extends Lexer {
map.put("TRUE", Token.TRUE);
map.put("FALSE", Token.FALSE);
map.put("LIMIT", Token.LIMIT);
map.put("KILL", Token.KILL);
DEFAULT_MYSQL_KEYWORDS = new Keywords(map);
}
@@ -30,11 +30,13 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
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.MySqlCreateTableParser;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDeleteStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlExecuteStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlKillStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLoadDataInFileStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLoadXmlStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPrepareStatement;
@@ -153,8 +155,46 @@ public class MySqlStatementParser extends SQLStatementParser {
throw new ParserException("TODO " + lexer.token());
}
public SQLStatement parseKill() {
accept(Token.KILL);
MySqlKillStatement stmt = new MySqlKillStatement();
if (identifierEquals("CONNECTION")) {
stmt.setType(MySqlKillStatement.Type.CONNECTION);
lexer.nextToken();
} else if (identifierEquals("QUERY")) {
stmt.setType(MySqlKillStatement.Type.QUERY);
lexer.nextToken();
} else {
throw new ParserException("not support kill type " + lexer.token());
}
SQLExpr threadId = this.exprParser.expr();
stmt.setThreadId(threadId);
return stmt;
}
public SQLStatement parseBinlog() {
acceptIdentifier("binlog");
MySqlBinlogStatement stmt = new MySqlBinlogStatement();
SQLExpr expr = this.exprParser.expr();
stmt.setExpr(expr);
return stmt;
}
public boolean parseStatementListDialect(List<SQLStatement> statementList) {
if (lexer.token() == Token.KILL) {
SQLStatement stmt = parseKill();
statementList.add(stmt);
return true;
}
if (identifierEquals("PREPARE")) {
MySqlPrepareStatement stmt = parsePrepare();
statementList.add(stmt);
@@ -202,6 +242,12 @@ public class MySqlStatementParser extends SQLStatementParser {
statementList.add(stmt);
return true;
}
if (identifierEquals("BINLOG")) {
SQLStatement stmt = parseBinlog();
statementList.add(stmt);
return true;
}
return false;
}
@@ -23,10 +23,12 @@ 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.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.MySqlDeleteStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlExecuteStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlKillStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLoadDataInFileStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLoadXmlStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPrepareStatement;
@@ -148,4 +150,12 @@ public interface MySqlASTVisitor extends SQLASTVisitor {
void endVisit(CobarShowStatus x);
boolean visit(CobarShowStatus x);
void endVisit(MySqlKillStatement x);
boolean visit(MySqlKillStatement x);
void endVisit(MySqlBinlogStatement x);
boolean visit(MySqlBinlogStatement x);
}
@@ -8,10 +8,12 @@ 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.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.MySqlDeleteStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlExecuteStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlKillStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLoadDataInFileStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLoadXmlStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPrepareStatement;
@@ -311,4 +313,24 @@ public class MySqlASTVisitorAdapter extends SQLASTVisitorAdapter implements MySq
return true;
}
@Override
public void endVisit(MySqlKillStatement x) {
}
@Override
public boolean visit(MySqlKillStatement x) {
return true;
}
@Override
public void endVisit(MySqlBinlogStatement x) {
}
@Override
public boolean visit(MySqlBinlogStatement x) {
return true;
}
}
@@ -37,11 +37,13 @@ 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.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.MySqlDeleteStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlExecuteStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlKillStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLoadDataInFileStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLoadXmlStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlPrepareStatement;
@@ -1201,4 +1203,34 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
print("SHOW COBAR_STATUS");
return false;
}
@Override
public void endVisit(MySqlKillStatement x) {
}
@Override
public boolean visit(MySqlKillStatement x) {
if (MySqlKillStatement.Type.CONNECTION.equals(x.getType())) {
print("KILL CONNECTION ");
} else if (MySqlKillStatement.Type.QUERY.equals(x.getType())) {
print("KILL QUERY ");
}
x.getThreadId().accept(this);
return false;
}
@Override
public void endVisit(MySqlBinlogStatement x) {
}
@Override
public boolean visit(MySqlBinlogStatement x) {
print("BINLOG ");
x.getExpr().accept(this);
return false;
}
}
@@ -97,6 +97,7 @@ public enum Token {
TRUE("TRUE"),
FALSE("FALSE"),
LIMIT("LIMIT"),
KILL("KILL"),
// oracle
START("START"),