mysql parser

This commit is contained in:
温少
2012-05-18 07:42:45 +08:00
10 changed files with 170 additions and 0 deletions
@@ -0,0 +1,17 @@
package com.alibaba.druid.sql.dialect.mysql.ast;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
public class MySqlForceIndexHint extends MySqlIndexHintImpl {
private static final long serialVersionUID = 1L;
@Override
public void accept0(MySqlASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, getIndexList());
}
visitor.endVisit(this);
}
}
@@ -0,0 +1,14 @@
package com.alibaba.druid.sql.dialect.mysql.ast.statement;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
public class MySqlUnlockTablesStatement extends MySqlStatementImpl {
private static final long serialVersionUID = 1L;
public void accept0(MySqlASTVisitor visitor) {
visitor.visit(this);
visitor.endVisit(this);
}
}
@@ -23,6 +23,7 @@ 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.MySqlForceIndexHint;
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;
@@ -272,6 +273,13 @@ public class MySqlSelectParser extends SQLSelectParser {
parseIndexHint(hint);
tableSource.getHints().add(hint);
}
if (identifierEquals("FORCE")) {
lexer.nextToken();
MySqlForceIndexHint hint = new MySqlForceIndexHint();
parseIndexHint(hint);
tableSource.getHints().add(hint);
}
return super.parseTableSourceRest(tableSource);
}
@@ -110,6 +110,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowTriggersStatem
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowVariantsStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowWarningsStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlStartTransactionStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnlockTablesStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement;
import com.alibaba.druid.sql.parser.Lexer;
import com.alibaba.druid.sql.parser.ParserException;
@@ -528,6 +529,13 @@ public class MySqlStatementParser extends SQLStatementParser {
statementList.add(stmt);
return true;
}
if (identifierEquals("UNLOCK")) {
lexer.nextToken();
acceptIdentifier("TABLES");
statementList.add(new MySqlUnlockTablesStatement());
return true;
}
return false;
}
@@ -15,6 +15,7 @@
*/
package com.alibaba.druid.sql.dialect.mysql.visitor;
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlForceIndexHint;
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;
@@ -101,6 +102,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowWarningsStatem
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlStartTransactionStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlTableIndex;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnionQuery;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnlockTablesStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
@@ -465,4 +467,12 @@ public interface MySqlASTVisitor extends SQLASTVisitor {
boolean visit(MySqlLockTableStatement x);
void endVisit(MySqlLockTableStatement x);
boolean visit(MySqlUnlockTablesStatement x);
void endVisit(MySqlUnlockTablesStatement x);
boolean visit(MySqlForceIndexHint x);
void endVisit(MySqlForceIndexHint x);
}
@@ -1,5 +1,6 @@
package com.alibaba.druid.sql.dialect.mysql.visitor;
import com.alibaba.druid.sql.dialect.mysql.ast.MySqlForceIndexHint;
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;
@@ -88,6 +89,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowWarningsStatem
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlStartTransactionStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlTableIndex;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnionQuery;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnlockTablesStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement;
import com.alibaba.druid.sql.visitor.SQLASTVisitorAdapter;
@@ -1013,4 +1015,24 @@ public class MySqlASTVisitorAdapter extends SQLASTVisitorAdapter implements
public void endVisit(MySqlLockTableStatement x) {
}
@Override
public boolean visit(MySqlUnlockTablesStatement x) {
return true;
}
@Override
public void endVisit(MySqlUnlockTablesStatement x) {
}
@Override
public boolean visit(MySqlForceIndexHint x) {
return true;
}
@Override
public void endVisit(MySqlForceIndexHint x) {
}
}
@@ -31,6 +31,7 @@ import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
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.dialect.mysql.ast.MySqlForceIndexHint;
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;
@@ -122,6 +123,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowWarningsStatem
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlStartTransactionStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlTableIndex;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnionQuery;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnlockTablesStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement;
import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
@@ -2458,4 +2460,34 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
public void endVisit(MySqlLockTableStatement x) {
}
@Override
public boolean visit(MySqlUnlockTablesStatement x) {
print("UNLOCK TABLES");
return false;
}
@Override
public void endVisit(MySqlUnlockTablesStatement x) {
}
@Override
public boolean visit(MySqlForceIndexHint x) {
print("FORCE INDEX ");
if (x.getOption() != null) {
print("FOR ");
print(x.getOption().name);
print(' ');
}
print('(');
printAndAccept(x.getIndexList(), ", ");
print(')');
return false;
}
@Override
public void endVisit(MySqlForceIndexHint 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.MySqlForceIndexHint;
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;
@@ -98,6 +99,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowWarningsStatem
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlStartTransactionStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlTableIndex;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnionQuery;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnlockTablesStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement;
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
import com.alibaba.druid.stat.TableStat;
@@ -1077,4 +1079,24 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS
public void endVisit(MySqlLockTableStatement x) {
}
@Override
public boolean visit(MySqlUnlockTablesStatement x) {
return false;
}
@Override
public void endVisit(MySqlUnlockTablesStatement x) {
}
@Override
public boolean visit(MySqlForceIndexHint x) {
return false;
}
@Override
public void endVisit(MySqlForceIndexHint x) {
}
}
@@ -237,4 +237,32 @@ public class DMLSelectParserTest extends TestCase {
String output = SQLUtils.toMySqlString(stmt);
Assert.assertEquals("SELECT t1.id, t2.*\nFROM t1, test.t2\nWHERE test.t1.id = '中''‘文'\n\tAND t1.id = test.t2.id", output);
}
public void test_select_19() throws Exception {
String sql = "select * from offer a straight_join wp_image b force index for join(t1,t2) on a.member_id=b.member_id inner join product_visit c where a.member_id=c.member_id and c.member_id='abc' ";
MySqlStatementParser parser = new MySqlStatementParser(sql);
SQLStatement stmt = parser.parseStatementList().get(0);
parser.match(Token.EOF);
String output = SQLUtils.toMySqlString(stmt);
Assert.assertEquals("SELECT *\n"
+ //
"FROM offer a STRAIGHT_JOIN wp_image b FORCE INDEX FOR JOIN (t1, t2) ON a.member_id = b.member_id INNER JOIN product_visit c\n"
+ //
"WHERE a.member_id = c.member_id\n" + //
"\tAND c.member_id = 'abc'", output);
}
public void test_select_20() throws Exception {
String sql = "select * from offer a straight_join wp_image b ignore index for join(t1,t2) on a.member_id=b.member_id inner join product_visit c where a.member_id=c.member_id and c.member_id='abc' ";
MySqlStatementParser parser = new MySqlStatementParser(sql);
SQLStatement stmt = parser.parseStatementList().get(0);
parser.match(Token.EOF);
String output = SQLUtils.toMySqlString(stmt);
Assert.assertEquals("SELECT *\n"
+ //
"FROM offer a STRAIGHT_JOIN wp_image b IGNORE INDEX FOR JOIN (t1, t2) ON a.member_id = b.member_id INNER JOIN product_visit c\n"
+ //
"WHERE a.member_id = c.member_id\n" + //
"\tAND c.member_id = 'abc'", output);
}
}
@@ -90,4 +90,13 @@ public class MTSParserTest extends TestCase {
String output = SQLUtils.toMySqlString(stmt);
Assert.assertEquals("LOCK TABLES t2 READ LOCAL", output);
}
public void test_unlockTable() throws Exception {
String sql = "UNLOCK TABLES";
MySqlStatementParser parser = new MySqlStatementParser(sql);
SQLStatement stmt = parser.parseStatementList().get(0);
parser.match(Token.EOF);
String output = SQLUtils.toMySqlString(stmt);
Assert.assertEquals("UNLOCK TABLES", output);
}
}