mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
mysql parser support hints
This commit is contained in:
+20
-1
@@ -24,9 +24,11 @@ import com.alibaba.druid.sql.ast.SQLCommentHint;
|
||||
import com.alibaba.druid.sql.ast.SQLPartitioningClause;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class MySqlCreateTableStatement extends SQLCreateTableStatement {
|
||||
public class MySqlCreateTableStatement extends SQLCreateTableStatement implements MySqlStatement {
|
||||
|
||||
private boolean ifNotExiists = false;
|
||||
|
||||
@@ -111,4 +113,21 @@ public class MySqlCreateTableStatement extends SQLCreateTableStatement {
|
||||
this.ifNotExiists = ifNotExiists;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void accept0(SQLASTVisitor visitor) {
|
||||
if (visitor instanceof MySqlASTVisitor) {
|
||||
accept0((MySqlASTVisitor) visitor);
|
||||
} else {
|
||||
throw new IllegalArgumentException("not support visitor type : " + visitor.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
public void accept0(MySqlASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
this.acceptChild(visitor, getHints());
|
||||
this.acceptChild(visitor, getTableSource());
|
||||
this.acceptChild(visitor, getTableElementList());
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
}
|
||||
|
||||
+26
-15
@@ -18,6 +18,7 @@ package com.alibaba.druid.sql.dialect.mysql.ast.statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLCommentHint;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.SQLObjectImpl;
|
||||
@@ -30,29 +31,39 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor;
|
||||
@SuppressWarnings("serial")
|
||||
public class MySqlSelectQueryBlock extends SQLSelectQueryBlock implements MySqlObject {
|
||||
|
||||
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 SQLName procedureName;
|
||||
private List<SQLExpr> procedureArgumentList = new ArrayList<SQLExpr>();
|
||||
|
||||
private boolean forUpdate = false;
|
||||
private boolean lockInShareMode = false;
|
||||
private boolean forUpdate = false;
|
||||
private boolean lockInShareMode = false;
|
||||
|
||||
private List<SQLCommentHint> hints = new ArrayList<SQLCommentHint>();
|
||||
|
||||
public MySqlSelectQueryBlock(){
|
||||
|
||||
}
|
||||
|
||||
public List<SQLCommentHint> getHints() {
|
||||
return hints;
|
||||
}
|
||||
|
||||
public void setHints(List<SQLCommentHint> hints) {
|
||||
this.hints = hints;
|
||||
}
|
||||
|
||||
public boolean isForUpdate() {
|
||||
return forUpdate;
|
||||
}
|
||||
@@ -163,7 +174,7 @@ public class MySqlSelectQueryBlock extends SQLSelectQueryBlock implements MySqlO
|
||||
accept0((MySqlASTVisitor) visitor);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, this.selectList);
|
||||
acceptChild(visitor, this.from);
|
||||
@@ -178,7 +189,7 @@ public class MySqlSelectQueryBlock extends SQLSelectQueryBlock implements MySqlO
|
||||
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void accept0(MySqlASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
|
||||
@@ -389,7 +389,7 @@ public class MySqlLexer extends Lexer {
|
||||
}
|
||||
|
||||
if (isHint) {
|
||||
stringVal = new String(buf, np + startHintSp, (sp - startHintSp) - 2).trim();
|
||||
stringVal = new String(buf, np + startHintSp, (sp - startHintSp) - 1);
|
||||
token = Token.HINT;
|
||||
} else {
|
||||
stringVal = new String(buf, np, sp);
|
||||
|
||||
@@ -64,6 +64,10 @@ public class MySqlSelectParser extends SQLSelectParser {
|
||||
|
||||
if (lexer.token() == Token.SELECT) {
|
||||
lexer.nextToken();
|
||||
|
||||
if (lexer.token() == Token.HINT) {
|
||||
this.createExprParser().parseHints(queryBlock.getHints());
|
||||
}
|
||||
|
||||
if (lexer.token() == (Token.DISTINCT)) {
|
||||
queryBlock.setDistionOption(SQLSetQuantifier.DISTINCT);
|
||||
|
||||
@@ -37,6 +37,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlAlterTableStatemen
|
||||
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.MySqlCreateIndexStatement;
|
||||
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.MySqlDeleteStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDescribeStatement;
|
||||
@@ -495,4 +496,8 @@ public interface MySqlASTVisitor extends SQLASTVisitor {
|
||||
boolean visit(MySqlAlterTableOption x);
|
||||
|
||||
void endVisit(MySqlAlterTableOption x);
|
||||
|
||||
boolean visit(MySqlCreateTableStatement x);
|
||||
|
||||
void endVisit(MySqlCreateTableStatement x);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlAlterTableStatemen
|
||||
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.MySqlCreateIndexStatement;
|
||||
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;
|
||||
@@ -1079,4 +1080,14 @@ public class MySqlASTVisitorAdapter extends SQLASTVisitorAdapter implements
|
||||
public void endVisit(MySqlAlterTableOption x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MySqlCreateTableStatement x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(MySqlCreateTableStatement x) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.alibaba.druid.sql.dialect.mysql.visitor;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLCommentHint;
|
||||
import com.alibaba.druid.sql.ast.SQLDataType;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLSetQuantifier;
|
||||
@@ -161,6 +162,12 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
}
|
||||
|
||||
print("SELECT ");
|
||||
|
||||
|
||||
for (SQLCommentHint hint : x.getHints()) {
|
||||
hint.accept(this);
|
||||
print(' ');
|
||||
}
|
||||
|
||||
if (SQLSetQuantifier.ALL == x.getDistionOption()) print("ALL ");
|
||||
else if (SQLSetQuantifier.DISTINCT == x.getDistionOption()) print("DISTINCT ");
|
||||
@@ -359,20 +366,22 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean visit(SQLCreateTableStatement x) {
|
||||
public boolean visit(MySqlCreateTableStatement x) {
|
||||
|
||||
MySqlCreateTableStatement mysqlCreateTableStatement = null;
|
||||
if (x instanceof MySqlCreateTableStatement) {
|
||||
mysqlCreateTableStatement = (MySqlCreateTableStatement) x;
|
||||
print("CREATE ");
|
||||
|
||||
for (SQLCommentHint hint : x.getHints()) {
|
||||
hint.accept(this);
|
||||
print(' ');
|
||||
}
|
||||
|
||||
if (SQLCreateTableStatement.Type.GLOBAL_TEMPORARY.equals(x.getType())) {
|
||||
print("CREATE TEMPORARY TABLE ");
|
||||
print("TEMPORARY TABLE ");
|
||||
} else {
|
||||
print("CREATE TABLE ");
|
||||
print("TABLE ");
|
||||
}
|
||||
|
||||
if (mysqlCreateTableStatement != null && mysqlCreateTableStatement.isIfNotExiists()) {
|
||||
if (x.isIfNotExiists()) {
|
||||
print("IF NOT EXISTS ");
|
||||
}
|
||||
|
||||
@@ -391,20 +400,18 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
println();
|
||||
print(")");
|
||||
|
||||
if (mysqlCreateTableStatement != null) {
|
||||
for (Map.Entry<String, String> option : mysqlCreateTableStatement.getTableOptions().entrySet()) {
|
||||
print(" ");
|
||||
print(option.getKey());
|
||||
print(" = ");
|
||||
print(option.getValue());
|
||||
}
|
||||
for (Map.Entry<String, String> option : x.getTableOptions().entrySet()) {
|
||||
print(" ");
|
||||
print(option.getKey());
|
||||
print(" = ");
|
||||
print(option.getValue());
|
||||
}
|
||||
|
||||
if (mysqlCreateTableStatement != null && mysqlCreateTableStatement.getQuery() != null) {
|
||||
if (x.getQuery() != null) {
|
||||
print(" ");
|
||||
incrementIndent();
|
||||
println();
|
||||
mysqlCreateTableStatement.getQuery().accept(this);
|
||||
x.getQuery().accept(this);
|
||||
decrementIndent();
|
||||
}
|
||||
|
||||
@@ -2525,12 +2532,12 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
public boolean visit(MySqlAlterTableCharacter x) {
|
||||
print("CHARACTER SET = ");
|
||||
x.getCharacterSet().accept(this);
|
||||
|
||||
|
||||
if (x.getCollate() != null) {
|
||||
print(", COLLATE = ");
|
||||
x.getCollate().accept(this);
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2563,7 +2570,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
|
||||
@Override
|
||||
public void endVisit(MySqlAlterTableAddIndex x) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2576,6 +2583,11 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
|
||||
@Override
|
||||
public void endVisit(MySqlAlterTableOption x) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(MySqlCreateTableStatement x) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import java.util.Map;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
|
||||
@@ -32,6 +33,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlAlterTableStatemen
|
||||
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.MySqlCreateIndexStatement;
|
||||
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;
|
||||
@@ -1143,4 +1145,14 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS
|
||||
public void endVisit(MySqlAlterTableOption x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MySqlCreateTableStatement x) {
|
||||
return super.visit((SQLCreateTableStatement) x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(MySqlCreateTableStatement x) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,7 +239,7 @@ public class OracleLexer extends Lexer {
|
||||
}
|
||||
|
||||
if (isHint) {
|
||||
stringVal = new String(buf, np + startHintSp, (sp - startHintSp) - 2).trim();
|
||||
stringVal = new String(buf, np + startHintSp, (sp - startHintSp) - 1);
|
||||
token = Token.HINT;
|
||||
} else {
|
||||
stringVal = new String(buf, np, sp);
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.alibaba.druid.sql.dialect.oracle.visitor;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLCommentHint;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLObjectCreateExpr;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.OracleOrderBy;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.clause.CycleClause;
|
||||
|
||||
@@ -17,7 +17,6 @@ package com.alibaba.druid.sql.dialect.oracle.visitor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLCommentHint;
|
||||
import com.alibaba.druid.sql.ast.SQLDataType;
|
||||
import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLHint;
|
||||
@@ -906,11 +905,6 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(SQLCommentHint x) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endVisit(OracleIntervalExpr x) {
|
||||
|
||||
@@ -2181,7 +2175,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
|
||||
print(x.getType());
|
||||
print(" ");
|
||||
}
|
||||
|
||||
|
||||
print("INDEX ");
|
||||
|
||||
x.getName().accept(this);
|
||||
|
||||
@@ -1092,7 +1092,9 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter {
|
||||
}
|
||||
|
||||
public boolean visit(SQLCommentHint x) {
|
||||
print("/*");
|
||||
print(x.getText());
|
||||
print("*/");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,15 @@ public class HintsTest extends TestCase {
|
||||
SQLStatement stmt = parser.parseStatementList().get(0);
|
||||
parser.match(Token.EOF);
|
||||
String output = SQLUtils.toMySqlString(stmt);
|
||||
Assert.assertEquals("CREATE TABLE t (\n\ta INT\n)", output);
|
||||
Assert.assertEquals("CREATE /*!32302 TEMPORARY */ TABLE t (\n\ta INT\n)", output);
|
||||
}
|
||||
|
||||
public void test_hints_1() throws Exception {
|
||||
String sql = "SELECT /*! STRAIGHT_JOIN */ col1 FROM table1,table2";
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
SQLStatement stmt = parser.parseStatementList().get(0);
|
||||
parser.match(Token.EOF);
|
||||
String output = SQLUtils.toMySqlString(stmt);
|
||||
Assert.assertEquals("SELECT /*! STRAIGHT_JOIN */ col1\nFROM table1, table2", output);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user