This commit is contained in:
温少
2012-05-17 17:28:15 +08:00
12 changed files with 261 additions and 54 deletions
@@ -1,22 +1,28 @@
package com.alibaba.druid.sql.dialect.mysql.ast.statement;
import com.alibaba.druid.sql.ast.SQLOrderBy;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock.Limit;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class MySqlUpdateStatement extends SQLUpdateStatement implements MySqlStatement {
private static final long serialVersionUID = 1L;
private Limit limit;
public Limit getLimit() {
return limit;
}
private static final long serialVersionUID = 1L;
private SQLOrderBy orderBy;
private Limit limit;
private boolean lowPriority = false;
private boolean ignore = false;
public Limit getLimit() {
return limit;
}
public void setLimit(Limit limit) {
this.limit = limit;
}
public void setLimit(Limit limit) {
this.limit = limit;
}
@Override
protected void accept0(SQLASTVisitor visitor) {
if (visitor instanceof MySqlASTVisitor) {
@@ -26,13 +32,39 @@ public class MySqlUpdateStatement extends SQLUpdateStatement implements MySqlSta
}
}
public void accept0(MySqlASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, tableSource);
acceptChild(visitor, items);
acceptChild(visitor, where);
acceptChild(visitor, limit);
}
visitor.endVisit(this);
}
public void accept0(MySqlASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, tableSource);
acceptChild(visitor, items);
acceptChild(visitor, where);
acceptChild(visitor, orderBy);
acceptChild(visitor, limit);
}
visitor.endVisit(this);
}
public boolean isLowPriority() {
return lowPriority;
}
public void setLowPriority(boolean lowPriority) {
this.lowPriority = lowPriority;
}
public boolean isIgnore() {
return ignore;
}
public void setIgnore(boolean ignore) {
this.ignore = ignore;
}
public SQLOrderBy getOrderBy() {
return orderBy;
}
public void setOrderBy(SQLOrderBy orderBy) {
this.orderBy = orderBy;
}
}
@@ -23,7 +23,9 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectQuery;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.ast.statement.SQLUnionQuery;
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlIgnoreIndexHint;
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlIndexHint;
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlIndexHintImpl;
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlUseIndexHint;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOutFileExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectGroupBy;
@@ -260,42 +262,49 @@ public class MySqlSelectParser extends SQLSelectParser {
if (identifierEquals("USE")) {
lexer.nextToken();
MySqlUseIndexHint hint = new MySqlUseIndexHint();
if (lexer.token() == Token.INDEX) {
lexer.nextToken();
} else {
accept(Token.KEY);
}
if (lexer.token() == Token.FOR) {
lexer.nextToken();
if (lexer.token() == Token.JOIN) {
lexer.nextToken();
hint.setOption(MySqlIndexHint.Option.JOIN);
} else if (lexer.token() == Token.ORDER) {
lexer.nextToken();
accept(Token.BY);
hint.setOption(MySqlIndexHint.Option.ORDER_BY);
} else {
accept(Token.GROUP);
accept(Token.BY);
hint.setOption(MySqlIndexHint.Option.GROUP_BY);
}
}
accept(Token.LPAREN);
this.createExprParser().names(hint.getIndexList());
accept(Token.RPAREN);
parseIndexHint(hint);
tableSource.getHints().add(hint);
}
if (identifierEquals("IGNORE")) {
throw new ParserException("TODO");
lexer.nextToken();
MySqlIgnoreIndexHint hint = new MySqlIgnoreIndexHint();
parseIndexHint(hint);
tableSource.getHints().add(hint);
}
return super.parseTableSourceRest(tableSource);
}
private void parseIndexHint(MySqlIndexHintImpl hint) {
if (lexer.token() == Token.INDEX) {
lexer.nextToken();
} else {
accept(Token.KEY);
}
if (lexer.token() == Token.FOR) {
lexer.nextToken();
if (lexer.token() == Token.JOIN) {
lexer.nextToken();
hint.setOption(MySqlIndexHint.Option.JOIN);
} else if (lexer.token() == Token.ORDER) {
lexer.nextToken();
accept(Token.BY);
hint.setOption(MySqlIndexHint.Option.ORDER_BY);
} else {
accept(Token.GROUP);
accept(Token.BY);
hint.setOption(MySqlIndexHint.Option.GROUP_BY);
}
}
accept(Token.LPAREN);
this.createExprParser().names(hint.getIndexList());
accept(Token.RPAREN);
}
protected MySqlUnionQuery createSQLUnionQuery() {
return new MySqlUnionQuery();
}
@@ -36,6 +36,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.ast.statement.SQLSetStatement;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.CobarShowStatus;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlAlterTableAddColumn;
@@ -137,7 +138,53 @@ public class MySqlStatementParser extends SQLStatementParser {
}
public SQLUpdateStatement parseUpdateStatement() throws ParserException {
MySqlUpdateStatement stmt = (MySqlUpdateStatement) super.parseUpdateStatement();
MySqlUpdateStatement stmt = createUpdateStatement();
if (lexer.token() == Token.UPDATE) {
lexer.nextToken();
if (identifierEquals("LOW_PRIORITY")) {
lexer.nextToken();
stmt.setLowPriority(true);
}
if (identifierEquals("IGNORE")) {
lexer.nextToken();
stmt.setIgnore(true);
}
SQLTableSource tableSource = this.exprParser.createSelectParser().parseTableSource();
stmt.setTableSource(tableSource);
}
accept(Token.SET);
for (;;) {
SQLUpdateSetItem item = new SQLUpdateSetItem();
item.setColumn(this.exprParser.name());
if (lexer.token() == Token.EQ) {
lexer.nextToken();
} else {
accept(Token.COLONEQ);
}
item.setValue(this.exprParser.expr());
stmt.getItems().add(item);
if (lexer.token() == (Token.COMMA)) {
lexer.nextToken();
continue;
}
break;
}
if (lexer.token() == (Token.WHERE)) {
lexer.nextToken();
stmt.setWhere(this.exprParser.expr());
}
stmt.setOrderBy(this.exprParser.parseOrderBy());
stmt.setLimit(parseLimit());
@@ -15,6 +15,7 @@
*/
package com.alibaba.druid.sql.dialect.mysql.visitor;
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlIgnoreIndexHint;
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.MySqlUseIndexHint;
@@ -455,4 +456,8 @@ public interface MySqlASTVisitor extends SQLASTVisitor {
boolean visit(MySqlUseIndexHint x);
void endVisit(MySqlUseIndexHint x);
boolean visit(MySqlIgnoreIndexHint x);
void endVisit(MySqlIgnoreIndexHint x);
}
@@ -1,5 +1,6 @@
package com.alibaba.druid.sql.dialect.mysql.visitor;
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlIgnoreIndexHint;
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.MySqlUseIndexHint;
@@ -991,4 +992,14 @@ public class MySqlASTVisitorAdapter extends SQLASTVisitorAdapter implements
public void endVisit(MySqlUseIndexHint x) {
}
@Override
public boolean visit(MySqlIgnoreIndexHint x) {
return true;
}
@Override
public void endVisit(MySqlIgnoreIndexHint x) {
}
}
@@ -32,6 +32,7 @@ import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlIgnoreIndexHint;
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.MySqlUseIndexHint;
@@ -1463,7 +1464,39 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
@Override
public boolean visit(MySqlUpdateStatement x) {
super.visit((SQLUpdateStatement) x);
print("UPDATE ");
if (x.isLowPriority()) {
print("LOW_PRIORITY ");
}
if (x.isIgnore()) {
print("IGNORE ");
}
x.getTableSource().accept(this);
println();
print("SET ");
for (int i = 0, size = x.getItems().size(); i < size; ++i) {
if (i != 0) {
print(", ");
}
x.getItems().get(i).accept(this);
}
if (x.getWhere() != null) {
println();
print("WHERE ");
x.getWhere().setParent(x);
x.getWhere().accept(this);
}
if (x.getOrderBy() != null) {
println();
x.getOrderBy().accept(this);
}
if (x.getLimit() != null) {
println();
x.getLimit().accept(this);
@@ -2372,6 +2405,25 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
@Override
public void endVisit(MySqlUseIndexHint x) {
}
@Override
public boolean visit(MySqlIgnoreIndexHint x) {
print("IGNORE INDEX ");
if (x.getOption() != null) {
print("FOR ");
print(x.getOption().name);
print(' ');
}
print('(');
printAndAccept(x.getIndexList(), ", ");
print(')');
return false;
}
@Override
public void endVisit(MySqlIgnoreIndexHint x) {
}
public boolean visit(SQLExprTableSource x) {
@@ -10,6 +10,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.ast.statement.SQLUnionQuery;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlIgnoreIndexHint;
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.MySqlUseIndexHint;
@@ -1055,4 +1056,14 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS
public void endVisit(MySqlUseIndexHint x) {
}
@Override
public boolean visit(MySqlIgnoreIndexHint x) {
return false;
}
@Override
public void endVisit(MySqlIgnoreIndexHint x) {
}
}
@@ -223,8 +223,10 @@ public class SQLSelectParser extends SQLParser {
} else if (lexer.token() == Token.LPAREN) {
tableSource = parseTableSource();
accept(Token.RPAREN);
accept(Token.RPAREN);
} else {
throw new ParserException("TODO");
tableSource = parseTableSource();
accept(Token.RPAREN);
}
return parseTableSourceRest(tableSource);
@@ -34,6 +34,7 @@ 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.SQLSavePointStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.ast.statement.SQLSetStatement;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
@@ -158,17 +159,23 @@ public class SQLStatementParser extends SQLParser {
statementList.add(stmt);
continue;
}
if (identifierEquals("RENAME")) {
SQLStatement stmt = parseRename();
statementList.add(stmt);
continue;
}
if (identifierEquals("SAVEPOINT")) {
SQLStatement stmt = parseSavePoint();
statementList.add(stmt);
continue;
}
if (parseStatementListDialect(statementList)) {
continue;
}
if (lexer.token() == Token.LPAREN) {
char mark_ch = lexer.current();
int mark_bp = lexer.bp();
@@ -192,11 +199,18 @@ public class SQLStatementParser extends SQLParser {
return stmt;
}
public SQLStatement parseSavePoint() {
acceptIdentifier("SAVEPOINT");
SQLSavePointStatement stmt = new SQLSavePointStatement();
stmt.setName(this.exprParser.name());
return stmt;
}
public SQLStatement parseAlter() {
accept(Token.ALTER);
throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
}
public SQLStatement parseRename() {
throw new ParserException("TODO " + lexer.token() + " " + lexer.stringVal());
}
@@ -220,15 +234,15 @@ public class SQLStatementParser extends SQLParser {
}
return stmt;
}
protected SQLDropViewStatement parseDropView(boolean acceptDrop) {
if (acceptDrop) {
accept(Token.DROP);
}
accept(Token.VIEW);
SQLDropViewStatement stmt = new SQLDropViewStatement();
for (;;) {
SQLName name = this.exprParser.name();
stmt.getTableSources().add(new SQLExprTableSource(name));
@@ -69,6 +69,7 @@ import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLDropViewStatement;
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.ast.statement.SQLSavePointStatement;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause;
import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource;
import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource.JoinType;
@@ -1062,4 +1063,11 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter {
x.getTableName().accept(this);
return false;
}
@Override
public boolean visit(SQLSavePointStatement x) {
print("SAVEPOINT ");
x.getName().accept(this);
return false;
}
}
@@ -66,6 +66,7 @@ import com.alibaba.druid.sql.ast.statement.SQLDropViewStatement;
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource;
import com.alibaba.druid.sql.ast.statement.SQLSavePointStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelect;
import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause;
import com.alibaba.druid.sql.ast.statement.SQLSelectItem;
@@ -355,4 +356,8 @@ public interface SQLASTVisitor {
boolean visit(SQLDropViewStatement x);
void endVisit(SQLDropViewStatement x);
boolean visit(SQLSavePointStatement x);
void endVisit(SQLSavePointStatement x);
}
@@ -67,6 +67,7 @@ import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableAddColumn;
import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource;
import com.alibaba.druid.sql.ast.statement.SQLSavePointStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelect;
import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause;
import com.alibaba.druid.sql.ast.statement.SQLSelectItem;
@@ -628,4 +629,14 @@ public class SQLASTVisitorAdapter implements SQLASTVisitor {
public void endVisit(SQLDropViewStatement x) {
}
@Override
public boolean visit(SQLSavePointStatement x) {
return true;
}
@Override
public void endVisit(SQLSavePointStatement x) {
}
}