mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
mysql parser bug fixed
This commit is contained in:
-7
@@ -22,7 +22,6 @@ import com.alibaba.druid.sql.ast.SQLExpr;
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
|
||||
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
|
||||
|
||||
public class MySqlReplicateStatement extends MySqlStatementImpl {
|
||||
@@ -35,7 +34,6 @@ public class MySqlReplicateStatement extends MySqlStatementImpl {
|
||||
private SQLName tableName;
|
||||
private final List<SQLExpr> columns = new ArrayList<SQLExpr>();
|
||||
private List<ValuesClause> valuesList = new ArrayList<ValuesClause>();
|
||||
private List<SQLUpdateSetItem> setItems = new ArrayList<SQLUpdateSetItem>();
|
||||
private SQLQueryExpr query;
|
||||
|
||||
public SQLName getTableName() {
|
||||
@@ -79,16 +77,11 @@ public class MySqlReplicateStatement extends MySqlStatementImpl {
|
||||
return valuesList;
|
||||
}
|
||||
|
||||
public List<SQLUpdateSetItem> getSetItems() {
|
||||
return setItems;
|
||||
}
|
||||
|
||||
public void accept0(MySqlASTVisitor visitor) {
|
||||
if (visitor.visit(this)) {
|
||||
acceptChild(visitor, tableName);
|
||||
acceptChild(visitor, columns);
|
||||
acceptChild(visitor, valuesList);
|
||||
acceptChild(visitor, setItems);
|
||||
acceptChild(visitor, query);
|
||||
}
|
||||
visitor.endVisit(this);
|
||||
|
||||
+46
-14
@@ -22,7 +22,6 @@ import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.SQLOrderBy;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
|
||||
@@ -32,11 +31,11 @@ import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLDropViewStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
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;
|
||||
@@ -1356,6 +1355,17 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
SQLName tableName = exprParser.name();
|
||||
stmt.setTableName(tableName);
|
||||
|
||||
if (lexer.token() == Token.LPAREN) {
|
||||
lexer.nextToken();
|
||||
if (lexer.token() == Token.SELECT) {
|
||||
SQLQueryExpr queryExpr = (SQLQueryExpr) this.exprParser.expr();
|
||||
stmt.setQuery(queryExpr);
|
||||
} else {
|
||||
this.exprParser.exprList(stmt.getColumns());
|
||||
}
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.VALUES || identifierEquals("VALUE")) {
|
||||
lexer.nextToken();
|
||||
|
||||
@@ -1378,13 +1388,17 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
stmt.setQuery(queryExpr);
|
||||
} else if (lexer.token() == Token.SET) {
|
||||
lexer.nextToken();
|
||||
for (;;) {
|
||||
SQLUpdateSetItem item = new SQLUpdateSetItem();
|
||||
item.setColumn(this.exprParser.name());
|
||||
accept(Token.EQ);
|
||||
item.setValue(this.exprParser.expr());
|
||||
|
||||
stmt.getSetItems().add(item);
|
||||
SQLInsertStatement.ValuesClause values = new SQLInsertStatement.ValuesClause();
|
||||
stmt.getValuesList().add(values);
|
||||
for (;;) {
|
||||
stmt.getColumns().add(this.exprParser.name());
|
||||
if (lexer.token() == Token.COLONEQ) {
|
||||
lexer.nextToken();
|
||||
} else {
|
||||
accept(Token.EQ);
|
||||
}
|
||||
values.getValues().add(this.exprParser.expr());
|
||||
|
||||
if (lexer.token() == (Token.COMMA)) {
|
||||
lexer.nextToken();
|
||||
@@ -1393,6 +1407,11 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
|
||||
break;
|
||||
}
|
||||
} else if (lexer.token() == Token.LPAREN) {
|
||||
lexer.nextToken();
|
||||
SQLQueryExpr queryExpr = (SQLQueryExpr) this.exprParser.expr();
|
||||
stmt.setQuery(queryExpr);
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
|
||||
return stmt;
|
||||
@@ -1628,7 +1647,13 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
|
||||
if (lexer.token() == (Token.LPAREN)) {
|
||||
lexer.nextToken();
|
||||
this.exprParser.exprList(insertStatement.getColumns());
|
||||
if (lexer.token() == (Token.SELECT)) {
|
||||
SQLSelect select = this.exprParser.createSelectParser().select();
|
||||
select.setParent(insertStatement);
|
||||
insertStatement.setQuery(select);
|
||||
} else {
|
||||
this.exprParser.exprList(insertStatement.getColumns());
|
||||
}
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
|
||||
@@ -1654,7 +1679,7 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
|
||||
SQLInsertStatement.ValuesClause values = new SQLInsertStatement.ValuesClause();
|
||||
insertStatement.getValuesList().add(values);
|
||||
|
||||
|
||||
for (;;) {
|
||||
SQLName name = this.exprParser.name();
|
||||
insertStatement.getColumns().add(name);
|
||||
@@ -1664,18 +1689,25 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
accept(Token.COLONEQ);
|
||||
}
|
||||
values.getValues().add(this.exprParser.expr());
|
||||
|
||||
|
||||
if (lexer.token() == Token.COMMA) {
|
||||
lexer.nextToken();
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
} else if (lexer.token() == (Token.SELECT)) {
|
||||
SQLQueryExpr queryExpr = (SQLQueryExpr) this.exprParser.expr();
|
||||
insertStatement.setQuery(queryExpr.getSubQuery());
|
||||
SQLSelect select = this.exprParser.createSelectParser().select();
|
||||
select.setParent(insertStatement);
|
||||
insertStatement.setQuery(select);
|
||||
} else if (lexer.token() == (Token.LPAREN)) {
|
||||
lexer.nextToken();
|
||||
SQLSelect select = this.exprParser.createSelectParser().select();
|
||||
select.setParent(insertStatement);
|
||||
insertStatement.setQuery(select);
|
||||
accept(Token.RPAREN);
|
||||
}
|
||||
|
||||
if (lexer.token() == Token.ON) {
|
||||
|
||||
@@ -795,7 +795,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
}
|
||||
|
||||
if (x.getQuery() != null) {
|
||||
print(" ");
|
||||
println();
|
||||
x.getQuery().accept(this);
|
||||
}
|
||||
|
||||
@@ -937,12 +937,6 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
x.getQuery().accept(this);
|
||||
}
|
||||
|
||||
if (x.getSetItems().size() != 0) {
|
||||
println();
|
||||
print("SET ");
|
||||
printAndAccept(x.getSetItems(), ", ");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,4 +39,67 @@ public class DMLInsertParserTest extends TestCase {
|
||||
String output = SQLUtils.toMySqlString(stmt);
|
||||
Assert.assertEquals("INSERT INTO t1\nVALUES (123, ?) ON DUPLICATE KEY UPDATE ex.col1 = ?", output);
|
||||
}
|
||||
|
||||
public void testInsert_3() throws Exception {
|
||||
String sql = "insErt LOW_PRIORITY t1 valueS (12e-2,1,2), (?),(default)";
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
SQLStatement stmt = parser.parseStatementList().get(0);
|
||||
parser.match(Token.EOF);
|
||||
String output = SQLUtils.toMySqlString(stmt);
|
||||
Assert.assertEquals("INSERT LOW_PRIORITY INTO t1\nVALUES (0.12, 1, 2), (?), (DEFAULT)", output);
|
||||
}
|
||||
|
||||
public void testInsert_4() throws Exception {
|
||||
String sql = "insErt LOW_PRIORITY t1 select id from t1";
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
SQLStatement stmt = parser.parseStatementList().get(0);
|
||||
parser.match(Token.EOF);
|
||||
String output = SQLUtils.toMySqlString(stmt);
|
||||
Assert.assertEquals("INSERT LOW_PRIORITY INTO t1\nSELECT id\nFROM t1", output);
|
||||
}
|
||||
|
||||
public void testInsert_5() throws Exception {
|
||||
String sql = "insErt LOW_PRIORITY t1 (select id from t1) oN dupLicatE key UPDATE ex.col1=?, col2=12";
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
SQLStatement stmt = parser.parseStatementList().get(0);
|
||||
parser.match(Token.EOF);
|
||||
String output = SQLUtils.toMySqlString(stmt);
|
||||
Assert.assertEquals("INSERT LOW_PRIORITY INTO t1\nSELECT id\nFROM t1 ON DUPLICATE KEY UPDATE ex.col1 = ?, col2 = 12", output);
|
||||
}
|
||||
|
||||
public void testInsert_6() throws Exception {
|
||||
String sql = "insErt LOW_PRIORITY t1 (t1.col1) valueS (123),('12''34')";
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
SQLStatement stmt = parser.parseStatementList().get(0);
|
||||
parser.match(Token.EOF);
|
||||
String output = SQLUtils.toMySqlString(stmt);
|
||||
Assert.assertEquals("INSERT LOW_PRIORITY INTO t1 (t1.col1)\nVALUES (123), ('12''34')", output);
|
||||
}
|
||||
|
||||
public void testInsert_7() throws Exception {
|
||||
String sql = "insErt LOW_PRIORITY t1 (col1, t1.col2) VALUE (123,'123\\'4') oN dupLicatE key UPDATE ex.col1=?";
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
SQLStatement stmt = parser.parseStatementList().get(0);
|
||||
parser.match(Token.EOF);
|
||||
String output = SQLUtils.toMySqlString(stmt);
|
||||
Assert.assertEquals("INSERT LOW_PRIORITY INTO t1 (col1, t1.col2)\nVALUES (123, '123''4') ON DUPLICATE KEY UPDATE ex.col1 = ?", output);
|
||||
}
|
||||
|
||||
public void testInsert_8() throws Exception {
|
||||
String sql = "insErt LOW_PRIORITY t1 (col1, t1.col2) select id from t3 oN dupLicatE key UPDATE ex.col1=?";
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
SQLStatement stmt = parser.parseStatementList().get(0);
|
||||
parser.match(Token.EOF);
|
||||
String output = SQLUtils.toMySqlString(stmt);
|
||||
Assert.assertEquals("INSERT LOW_PRIORITY INTO t1 (col1, t1.col2)\nSELECT id\nFROM t3 ON DUPLICATE KEY UPDATE ex.col1 = ?", output);
|
||||
}
|
||||
|
||||
public void testInsert_9() throws Exception {
|
||||
String sql = "insErt LOW_PRIORITY IGNORE intO t1 (col1) ( select id from t3) ";
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
SQLStatement stmt = parser.parseStatementList().get(0);
|
||||
parser.match(Token.EOF);
|
||||
String output = SQLUtils.toMySqlString(stmt);
|
||||
Assert.assertEquals("INSERT LOW_PRIORITY IGNORE INTO t1 (col1)\nSELECT id\nFROM t3", output);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
package com.alibaba.druid.bvt.sql.cobar;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
|
||||
import com.alibaba.druid.sql.parser.Token;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
|
||||
public class DMLReplaceParserTest extends TestCase {
|
||||
public void testReplace_0() throws Exception {
|
||||
String sql = "ReplaCe LOW_PRIORITY intO test.t1 seT t1.id1:=?, id2='123'";
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
SQLStatement stmt = parser.parseStatementList().get(0);
|
||||
parser.match(Token.EOF);
|
||||
String output = SQLUtils.toMySqlString(stmt);
|
||||
Assert.assertEquals("REPLACE LOW_PRIORITY INTO test.t1 (t1.id1, id2)\nVALUES (?, '123')", output);
|
||||
}
|
||||
|
||||
public void testReplace_1() throws Exception {
|
||||
String sql = "ReplaCe test.t1 seT t1.id1:=? ";
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
SQLStatement stmt = parser.parseStatementList().get(0);
|
||||
parser.match(Token.EOF);
|
||||
String output = SQLUtils.toMySqlString(stmt);
|
||||
Assert.assertEquals("REPLACE INTO test.t1 (t1.id1)\nVALUES (?)", output);
|
||||
}
|
||||
|
||||
public void testReplace_2() throws Exception {
|
||||
String sql = "ReplaCe t1 value (123,?) ";
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
SQLStatement stmt = parser.parseStatementList().get(0);
|
||||
parser.match(Token.EOF);
|
||||
String output = SQLUtils.toMySqlString(stmt);
|
||||
Assert.assertEquals("REPLACE INTO t1\nVALUES (123, ?)", output);
|
||||
}
|
||||
|
||||
public void testReplace_3() throws Exception {
|
||||
String sql = "ReplaCe LOW_PRIORITY t1 valueS (12e-2), (?)";
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
SQLStatement stmt = parser.parseStatementList().get(0);
|
||||
parser.match(Token.EOF);
|
||||
String output = SQLUtils.toMySqlString(stmt);
|
||||
Assert.assertEquals("REPLACE LOW_PRIORITY INTO t1\nVALUES (0.12), (?)", output);
|
||||
}
|
||||
|
||||
public void testReplace_4() throws Exception {
|
||||
String sql = "ReplaCe LOW_PRIORITY t1 select id from t1";
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
SQLStatement stmt = parser.parseStatementList().get(0);
|
||||
parser.match(Token.EOF);
|
||||
String output = SQLUtils.toMySqlString(stmt);
|
||||
Assert.assertEquals("REPLACE LOW_PRIORITY INTO t1\n\tSELECT id\n\tFROM t1", output);
|
||||
}
|
||||
|
||||
public void testReplace_5() throws Exception {
|
||||
String sql = "ReplaCe delayed t1 select id from t1";
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
SQLStatement stmt = parser.parseStatementList().get(0);
|
||||
parser.match(Token.EOF);
|
||||
String output = SQLUtils.toMySqlString(stmt);
|
||||
Assert.assertEquals("REPLACE DELAYED INTO t1\n\tSELECT id\n\tFROM t1", output);
|
||||
}
|
||||
|
||||
public void testReplace_6() throws Exception {
|
||||
String sql = "ReplaCe LOW_PRIORITY t1 (select id from t1) ";
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
SQLStatement stmt = parser.parseStatementList().get(0);
|
||||
parser.match(Token.EOF);
|
||||
String output = SQLUtils.toMySqlString(stmt);
|
||||
Assert.assertEquals("REPLACE LOW_PRIORITY INTO t1\n\tSELECT id\n\tFROM t1", output);
|
||||
}
|
||||
|
||||
public void testReplace_7() throws Exception {
|
||||
String sql = "ReplaCe LOW_PRIORITY t1 (t1.col1) valueS (123),('12''34')";
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
SQLStatement stmt = parser.parseStatementList().get(0);
|
||||
parser.match(Token.EOF);
|
||||
String output = SQLUtils.toMySqlString(stmt);
|
||||
Assert.assertEquals("REPLACE LOW_PRIORITY INTO t1 (t1.col1)\nVALUES (123), ('12''34')", output);
|
||||
}
|
||||
|
||||
public void testReplace_8() throws Exception {
|
||||
String sql = "ReplaCe LOW_PRIORITY t1 (col1, t1.col2) VALUE (123,'123\\'4') ";
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
SQLStatement stmt = parser.parseStatementList().get(0);
|
||||
parser.match(Token.EOF);
|
||||
String output = SQLUtils.toMySqlString(stmt);
|
||||
Assert.assertEquals("REPLACE LOW_PRIORITY INTO t1 (col1, t1.col2)\nVALUES (123, '123''4')", output);
|
||||
}
|
||||
|
||||
public void testReplace_9() throws Exception {
|
||||
String sql = "REPLACE LOW_PRIORITY t1 (col1, t1.col2) select id from t3 ";
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
SQLStatement stmt = parser.parseStatementList().get(0);
|
||||
parser.match(Token.EOF);
|
||||
String output = SQLUtils.toMySqlString(stmt);
|
||||
Assert.assertEquals("REPLACE LOW_PRIORITY INTO t1 (col1, t1.col2)\n\tSELECT id\n\tFROM t3", output);
|
||||
}
|
||||
|
||||
public void testReplace_10() throws Exception {
|
||||
String sql = "replace LOW_PRIORITY intO t1 (col1) ( select id from t3) ";
|
||||
MySqlStatementParser parser = new MySqlStatementParser(sql);
|
||||
SQLStatement stmt = parser.parseStatementList().get(0);
|
||||
parser.match(Token.EOF);
|
||||
String output = SQLUtils.toMySqlString(stmt);
|
||||
Assert.assertEquals("REPLACE LOW_PRIORITY INTO t1 (col1)\n\tSELECT id\n\tFROM t3", output);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user