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) {
}
}